rf2-autocam — Automated broadcast camera plugin for LMU

SeikenXa

New member
https://github.com/seikenxa/rf2-autocam


Originally developed for rFactor 2 (thread: https://forum.studio-397.com/index.php?threads/rfactor-2-automated-camera-plugin.49441/), this plugin now supports Le Mans Ultimate as well.

Automatically switches cameras during a live session — no human operator required. Useful for endurance broadcasts or unattended streams.

Note: for live multiplayer broadcasts, you'll need a dedicated PC running LMU (joined as spectator) with the plugin installed, separate from the players' PCs.


What it does:

  • Race: tracks the closest on-track battle; higher positions get priority
  • Practice/Qualifying: follows the car currently on a hot lap (sector time detection)
  • Side-by-side detection: widens to a trackside view when cars run door-to-door
  • Walk-through mode on formation lap and after the finish
  • Writes current driver, position, gap, and session info to files for OBS overlays

Installation:

  1. Copy rf2autocam_x64.dll to <LeMansUltimate>\Plugins\ (create the folder if it doesn't exist)
  2. Add to UserData\player\CustomPluginVariables.JSON:
"rf2autocam_x64.dll": { " Enabled": 1 }
  1. Launch a session — rF2autocam.ini will be created automatically in UserData\player\
Toggle autocam on/off with Ctrl+A during a session. Full configuration reference is in the README.
 
I saw a few old tools on GitHub almost usable on LMU (Upgrading the VCR merge would be awesome too).
They managed to modify the REST API in weird ways for LMU.
Like isActive from some request which is now isactive without uppercase. That kind of update ruins the compatibility rFactor2 / LMU for a real dumb reason.

And i have a question :
Would it be possible to use that tool on replays ?

Or do you think there would be some possibility to add that kind of feature ?

Sorry for double post.
 
I saw a few old tools on GitHub almost usable on LMU (Upgrading the VCR merge would be awesome too).
They managed to modify the REST API in weird ways for LMU.
Like isActive from some request which is now isactive without uppercase. That kind of update ruins the compatibility rFactor2 / LMU for a real dumb reason.

And i have a question :
Would it be possible to use that tool on replays ?

Or do you think there would be some possibility to add that kind of feature ?

Sorry for double post.
Currently, the replay function is not supported. We are investigating how to add it in the future.

Incidentally, we currently retrieve data using the UpdateScoring callback, but it seems possible to achieve this by changing to a separate thread that periodically polls SharedMemory. However, this would require almost a complete rewrite.

This could potentially become a separate project.

The original project's goal was to achieve "automatic camera operation during live sessions," so the current behavior is considered "as designed."
 
I just tried it and CTRL+A doesn't seem to work.
I'm just just in a random practice online hosted session.
It is enabled, i just put auto to 0 in the ini.
Il will try to enable debug mode.

Edit : No log in ...\Le Mans Ultimate\UserData\player\rF2stream or else.
The plugin seems to be loaded, ini has been created and CustomPluginVariables.JSON too (Enabled : 1).
Does it only works during races ?

Edit 2 : Works well in rFactor 2.
 
Last edited:
Currently, the replay function is not supported. We are investigating how to add it in the future.

Incidentally, we currently retrieve data using the UpdateScoring callback, but it seems possible to achieve this by changing to a separate thread that periodically polls SharedMemory. However, this would require almost a complete rewrite.

This could potentially become a separate project.

The original project's goal was to achieve "automatic camera operation during live sessions," so the current behavior is considered "as designed."
We investigated why replay mode is not supported and summarized our conclusions.
 
I just tried it and CTRL+A doesn't seem to work.
I'm just just in a random practice online hosted session.
It is enabled, i just put auto to 0 in the ini.
Il will try to enable debug mode.

Edit : No log in ...\Le Mans Ultimate\UserData\player\rF2stream or else.
The plugin seems to be loaded, ini has been created and CustomPluginVariables.JSON too (Enabled : 1).
Does it only works during races ?

Edit 2 : Works well in rFactor 2.
Thanks for the detailed report, Tony — we were able to reproduce the issue here.

The problem is confirmed and fixed in v1.1.1 (just released):

LMU does not call the CheckHWControl plugin callback that rF2 uses for keyboard input. The Ctrl+A hotkey was simply never reaching the plugin. Fixed by adding key detection inside UpdateScoring as a fallback — Ctrl+A now toggles autocam in LMU as well.

To fix your setup:

  1. Download rf2autocam_x64.dll from the v1.1.1 release
  2. Place it in <LeMansUltimate>\Plugins\
  3. Start a session — Ctrl+A should now toggle autocam on/off
With auto=0 in the ini (autocam disabled at startup), press Ctrl+A once to enable it. With auto=1 it starts active immediately.
 
Just tried it again tonight on a practice and it worked.

But.

There is a weird behaviour somewhat dangerous.
I noticed it didn't work instantly at start of session. It seems like there is a big delay before it works properly.
At some point i pushed CTRL+A but nothing happened. In spectator, no driver swap after the first CTRL+A.

But then i disabled it (Or i think i did it ... ), and drove back normally.
Later on i was launched to another drivers view while i was actually driving.
I surely didn't disabled the autocam properly and at some point it enabled itself.

I was on discord and changinig things on TinyPedal and maybe loose the focus to the game.

There are no protection to avoid enabling it while driving ?

We have no way to see if it is enabled or disabled in game.

I would love to keep the plugin always active and for example spectate a part of the race if i DNF
or in practice or opened qualifications to see other drivers running and auto swapping drivers.

The debug.log works and only shows lines like :
t=2026.600 ses=1 ph=5 sip=interestdiff intdiff=1 obdiff=0.400 wait=15 pmb=0.010 mb=99999.000 npos=1 apos=1 nveh=8 aveh=8 rveh=-1 inpit=0 sbs=0 stream_len=0
 
Just tried it again tonight on a practice and it worked.

But.

There is a weird behaviour somewhat dangerous.
I noticed it didn't work instantly at start of session. It seems like there is a big delay before it works properly.
At some point i pushed CTRL+A but nothing happened. In spectator, no driver swap after the first CTRL+A.

But then i disabled it (Or i think i did it ... ), and drove back normally.
Later on i was launched to another drivers view while i was actually driving.
I surely didn't disabled the autocam properly and at some point it enabled itself.

I was on discord and changinig things on TinyPedal and maybe loose the focus to the game.

There are no protection to avoid enabling it while driving ?

We have no way to see if it is enabled or disabled in game.

I would love to keep the plugin always active and for example spectate a part of the race if i DNF
or in practice or opened qualifications to see other drivers running and auto swapping drivers.

The debug.log works and only shows lines like :
Thanks for the detailed report — you identified a real bug, and it's now fixed in v1.3.2.

What was happening

The camera-switch-while-driving issue is specific to LMU. Unlike rF2 (which uses a plugin callback that the game simply stops calling once you've driven), LMU uses a REST API — meaning the plugin could issue PUT /rest/watch/focus/{slotId} and forcibly move your camera even while you were racing. That's the dangerous behaviour you experienced.

The initial delay is a separate thing: when you enable autocam via Ctrl+hotkey, there's a built-in hold timer (waitsec, default 15 s) before the first switch fires. At session start that meant up to 20 seconds of nothing happening. Fixed in this release too.

What v1.3.2 does

  • While you have an active car on track (mIsPlayer && mFinishStatus == 0), all camera selection and REST API calls are suppressed — autocam is on but stays out of your way
  • When you DNF, retire, or enter spectator mode, it resumes automatically. No toggle needed.
  • Enabling autocam now fires the first switch immediately instead of after the waitsec delay
  • The "Auto camera: on/off" HUD message now also appears in LMU when you toggle (it was rF2-only before)
How to update

Drop the new rf2autocam_x64.dll from the v1.3.2 release into your Plugins folder. No ini changes needed.

For your use case (keep it always on, spectate after a DNF, or watch others in practice/open quali) — that should now work exactly as you described. Enable it at session start and forget about it.
 
Thanks for the detailed report — you identified a real bug, and it's now fixed in v1.3.2.

What was happening

The camera-switch-while-driving issue is specific to LMU. Unlike rF2 (which uses a plugin callback that the game simply stops calling once you've driven), LMU uses a REST API — meaning the plugin could issue PUT /rest/watch/focus/{slotId} and forcibly move your camera even while you were racing. That's the dangerous behaviour you experienced.

The initial delay is a separate thing: when you enable autocam via Ctrl+hotkey, there's a built-in hold timer (waitsec, default 15 s) before the first switch fires. At session start that meant up to 20 seconds of nothing happening. Fixed in this release too.

What v1.3.2 does

  • While you have an active car on track (mIsPlayer && mFinishStatus == 0), all camera selection and REST API calls are suppressed — autocam is on but stays out of your way
  • When you DNF, retire, or enter spectator mode, it resumes automatically. No toggle needed.
  • Enabling autocam now fires the first switch immediately instead of after the waitsec delay
  • The "Auto camera: on/off" HUD message now also appears in LMU when you toggle (it was rF2-only before)
How to update

Drop the new rf2autocam_x64.dll from the v1.3.2 release into your Plugins folder. No ini changes needed.

For your use case (keep it always on, spectate after a DNF, or watch others in practice/open quali) — that should now work exactly as you described. Enable it at session start and forget about it.
Update — v1.3.3

Found a regression in v1.3.2: the "player is driving" check was too broad. It was blocking autocam even while sitting in the pit box before going out, which meant you couldn't watch other cars from the garage in rF2 — something that worked before.

The fix is a tighter condition: autocam is now only suspended when mPitState == 0, meaning the car is physically on track. Waiting in the pit box, garage, or pit lane no longer counts as "driving."

SituationAutocam
Active lap on trackSuspended
Waiting in pit / garageActive
DNF / finishedActive
Spectator modeActive
Drop v1.3.3 over the previous DLL — no ini changes needed.
 
Thanks for the very fast response. I'm impressed.
I just tested it on rFactor2 and it works as intended.

But i think i would remove the auto switch to spectator when in "Waiting in Pit / Garage" situation.
It's quite weird when it switches to autocam while you just get out to drive.

It works, but when you exit to menus with autocam on, and get back to drive, it directly activates the spectator mode on another driver.
You can't get out of garage and drive without switching back to your view by yourself.
I didn't have the control assigned to change POV and i was screwed.
I needed to do CTRL+A to off autocam, press Escape to get to menus and then click on Drive.

And also, i noticed if you click twice the CTRL+A or multiples times, sometimes it's unresponsive for a certain amount of time
or till you get back to menus.
Maybe it's just the chat anti spam feature ...

On rFactor 2 the Auto camera : on text appears on the "Message center", or "Chat interface", in fact.

I'm going to try it on LMU too.

Thanks, it works quite interestingly now.

Edit : It works on LMU but i can't see any Auto camera : on message anywhere, chat or else.
And same issue with "Waiting in Pit / Garage" situation, aautocam should be/stay suspended.

Additional question : How do you determine lowinc and highinc values ?
In result xml incidents :
<Incident et="4630.6">V... T........(76) reported contact (373.08) with another vehicle o.... w...(33)</Incident>
Does it have something to do with (373.08) or else ? I can't find the explanation on values.
I think i never see any incidents replay, and it may be linked to lowinc highinc values i think.
 
Last edited:
Does it have something to do with (373.08) or else ? I can't find the explanation on values.
That’s the severity/magnitude/points of the accident. It doesn’t mean you have to be involved in a crash; simply hitting a post is enough to cause damage (or hitting a kerb at an odd manner can also lead to incidents [Sebring, turn 15-16, for instance]).
 
Sure, but what exactly means lowinc = 0.4 accordingly to severity of accident ?

I mean 373.08 is superior to 0.4, i should have seen the incident in replay ?

Or, are there some kind of priority that hides incidents while in Practice or Qualification but not in Race ?
 
From what I see on the source code... didn't look too much it may not work as that:

Sure, but what exactly means lowinc = 0.4 accordingly to severity of accident ?
Minimal contact point. But the session should be less than 10 (0=testday 1-4=practice 5-8=qual 9=warmup 10-13=race).
If the contact point is higher than "highinc" should always trigger replay.

I mean 373.08 is superior to 0.4, i should have seen the incident in replay ?
If there is a replay in the queue or active it will be ignored.

Or, are there some kind of priority that hides incidents while in Practice or Qualification but not in Race ?
The only thing that changes depending on the session is the camera.
 
Thanks for the very fast response. I'm impressed.
I just tested it on rFactor2 and it works as intended.

But i think i would remove the auto switch to spectator when in "Waiting in Pit / Garage" situation.
It's quite weird when it switches to autocam while you just get out to drive.

It works, but when you exit to menus with autocam on, and get back to drive, it directly activates the spectator mode on another driver.
You can't get out of garage and drive without switching back to your view by yourself.
I didn't have the control assigned to change POV and i was screwed.
I needed to do CTRL+A to off autocam, press Escape to get to menus and then click on Drive.

And also, i noticed if you click twice the CTRL+A or multiples times, sometimes it's unresponsive for a certain amount of time
or till you get back to menus.
Maybe it's just the chat anti spam feature ...

On rFactor 2 the Auto camera : on

I'm going to try it on LMU too.

Thanks, it works quite interestingly now.

Edit : It works on LMU but i can't see any Auto camera : on message anywhere, chat or else.
And same issue with "Waiting in Pit / Garage" situation, aautocam should be/stay suspended.

Additional question : How do you determine lowinc and highinc values ?
In result xml incidents :

Does it have something to do with (373.08) or else ? I can't find the explanation on values.
I think i never see any incidents replay, and it may be linked to lowinc highinc values i think.
Hi TonyRZ,

Good question — let me clarify how the values work.

What lowinc and highinc mean

The (373.08) in the incident XML is the contact force magnitude reported by the physics engine. lowinc and highinc are thresholds compared against that value:

  • lowinc = 0.4 — minimum severity to record an incident as a replay candidate
  • highinc = 0.8 — minimum severity to automatically trigger replay in a Race session
In Practice or Qualifying, lowinc alone is enough, so your 373.08 contact is far above both thresholds and should fire a replay — the thresholds themselves are not why you're not seeing them.

The likely real reason

The plugin reads incidents from mResultsStream, a live XML buffer provided by the rF2/LMU engine via the plugin API. Incident replay only fires if the engine actually writes contact data into that stream.

In offline single-player sessions, it appears the engine may not populate mResultsStream with contact incidents at all — this would be engine behaviour rather than a plugin bug. The plugin has no way to detect incidents that the engine does not report through the API.

How to confirm

Add debug=1 to your rF2autocam.ini. After a session with incidents, open rF2stream\debug.log and look for the stream_len= field. If it stays at 0 throughout the session even after heavy contacts, the engine is not feeding incident data to the plugin in that session type, and there is nothing on the plugin side to fix.

If you do see stream_len growing, feel free to share the log and I can dig deeper.

Regarding the missing "Auto camera: on" message in LMU

This is a known limitation. The message is delivered through WantsToDisplayMessage, an InternalsPlugin callback that rF2 uses to display plugin notifications in its HUD message centre. LMU is built on the rF2 plugin API but appears to not implement or honour this callback, so the message never appears. This is an engine-level constraint the plugin cannot work around with the current approach. I am looking into an alternative method for LMU-specific notification.
 
Hello, i managed to create a debug.log in LMU (During a practice) and associated it with incidents.
See file attached (Incidents are added from xml result extract manually)
and we can see a few stream_len > 0 after some incidents.
IIt never triggred any replay.
 

Attachments

  • debug.log
    259.2 KB · Views: 5
Last edited:
Hello, i managed to create a debug.log in LMU (During a practice) and associated it with incidents.
See file attached (Incidents are added from xml result extract manually)
and we can see a few stream_len > 0 after some incidents.
IIt never triggred any replay.
Hi Tony, thanks a lot for the LMU debug log with the manually-aligned incidents — that was exactly what I needed, and it pinned the problem down precisely.

Good news first: detection is working in LMU. Your incident at et=215.3 (Fabrizio Spinoso, car #26, contact 310.07) was picked up — at t=215.4 the log shows rveh flip from -1 to 26. That value is only ever set once the plugin has parsed an incident and armed a replay, so the stream parsing and the incident logic are fine.

The problem is the trigger, not the detection. To actually start the replay, the plugin asks the sim to fire its built-in "Instant Replay" function through the CheckHWControl plugin callback. rFactor 2 services that callback; LMU does not — it's the same reason WantsToViewVehicle and the HUD/auto-key control don't work in LMU and we had to fall back to the REST API and the keyboard for those. So in your log the replay request just stays armed forever (rveh=26 never clears, the plugin never enters its REPLAY state) because nothing consumes it. The bouncing stream_len you noticed (0 ↔ ~380) is just LMU using a transient results buffer instead of rF2's growing one — unrelated to the trigger, though I'll harden the parser for it anyway.

I looked into using LMU's REST API as a fallback to start the replay, and unfortunately it can't be done:

  • The only replay endpoints LMU exposes (/rest/watch/replays, /rest/watch/play/{id}, /rest/watch/replaytime/{seconds}) load and seek saved replay files — there's no "instant replay during a live session" trigger.
  • Even if there were, I confirmed earlier that LMU freezes all vehicle data during replay playback (velocities = 0, positions and event time frozen) and stops calling plugin callbacks. So the plugin couldn't aim the camera at the incident car anyway — which is the whole point of the feature.
So the honest conclusion is that automatic incident replays are an rF2-only feature — LMU doesn't give plugins the hooks for it, on either the trigger or the playback side.

But here's what I can do for LMU instead, and I think it could actually be a nicer fit:

  1. Live incident cut (LMU). When a big incident is detected, instead of a replay I cut the live camera straight to the car involved and hold it there for a few seconds. Real broadcasts do exactly this — they don't always roll a replay, they often just cut to the action as it happens — so it doesn't feel unnatural, and it reuses the live REST camera switching that already works in LMU.
  2. A dedicated incident signal for OBS (both sims). Right now the only incident-related signal my OBS script gets is on_replay (the replay_start / replay_end triggers), which means OBS can't react to incidents in LMU at all, since no replay ever runs. I'd add a separate incident event so OBS can react to the incident itself — and I'd emit it in both rF2 and LMU so your OBS setup behaves identically regardless of which sim you're running.
The two signals would be distinct on purpose:

  • incident_start / incident_end — the event itself ("a big contact just happened"). Fires in both rF2 and LMU. Good for an instant lower-third / "CONTACT — Car #26" banner.
  • replay_start / replay_enda replay is currently playing. Fires in rF2 only (LMU never rolls one). Good for switching to a dedicated replay scene and back.
In rF2 the incident_start fires the moment it happens, and replay_start follows about 10 seconds later when the replay rolls — so you can flash a banner immediately and then cut to a replay scene, or wire up just one of them. In LMU you'd use incident_* only.

Would that be useful for your setup? If so I'll build it. Nothing changes for rF2 users who are happy with the current replay behaviour — this is all additive.

Thanks again for the detailed report — it saved me a lot of guessing.
 
The two features : Live incident cut and OBS signal are good ideas.

Maybe just add some sort of parameter to enable Live Cut (Defaulted to disabled).

If i see it's in Live Cut, i can use myself the InstanReplay Key (R by default) and see the incident ?
And the next hit on InstantReplay would get me back to autocam ?
Sad there is no message like autocam on/off to alert when there is an incident ready for replay. It would be a lot more usable.
Maybe, at least on rFactor2, add a message when there is an incident that "needReplay".

Plus, from what i see in the code the default lowinc 0.4 and highinc 0.8 are not optimal. I would rather use 500.0 (Light contact) and 5000.0 (High speed contact). If incidents would replay more automatically i would be able to find better values.
 
The two features : Live incident cut and OBS signal are good ideas.

Maybe just add some sort of parameter to enable Live Cut (Defaulted to disabled).

If i see it's in Live Cut, i can use myself the InstanReplay Key (R by default) and see the incident ?
And the next hit on InstantReplay would get me back to autocam ?
Sad there is no message like autocam on/off to alert when there is an incident ready for replay. It would be a lot more usable.
Maybe, at least on rFactor2, add a message when there is an incident that "needReplay".

Plus, from what i see in the code the default lowinc 0.4 and highinc 0.8 are not optimal. I would rather use 500.0 (Light contact) and 5000.0 (High speed contact). If incidents would replay more automatically i would be able to find better values.
Hi, Tony — thanks again for the detailed feedback. I've shipped most of it in v1.5.0: https://github.com/seikenxa/rf2-autocam/releases/tag/v1.5.0

Live Cut — added as livecut (default 0, so the old auto-replay behaviour is unchanged). With livecut=1, on an incident the camera cuts to the incident car and holds it, and you press Instant Replay yourself to replay it — exactly the workflow you described.

rF2 vs LMU — there's an important difference I ran into:

  • rF2: the plugin drives the replay — it seeks straight to the incident, and a second R returns to live. You also get an on-screen prompt "Incident - press R for replay" (the alert message you were missing).
  • LMU: two limitations — the plugin can't display on-screen messages (LMU doesn't show them), and it can't control or exit LMU's native replay (R enters it but doesn't exit — you click the LIVE marker on the seek bar to come back). So on LMU, Live Cut just holds the live focus on the incident car — the camera cutting to it is your visual cue — and you use LMU's own native replay on top. Set incidenthold to ~20 so the focus stays on the car long enough to watch it.
Instant Replay key — replaykey=auto reads your actual binding from the sim's own config (rF2 Controller.JSON / LMU keyboard.json), so it follows whatever key you use.

OBS signal — status.json now has an incident boolean and the OBS Lua script has incident_start / incident_end triggers (fires on both rF2 and LMU, independent of replay). On LMU this is your best "incident happening" cue since on-screen messages aren't available.

lowinc / highinc — you were spot on. The real contact-severity scale is hundreds to thousands; I measured incidents around 586–3794, so the old 0.4 / 0.8 fired on basically everything. New defaults are 500 / 2000. One catch: in races only highinc triggers (the lowinc branch is practice/qualifying only), so I went with 2000 rather than 5000 to still catch real race incidents — 5000 would have missed most of them. If you get a chance to test in races, I'd love to hear what threshold feels right so we can tune the default.

Let me know how it works for you on LMU.
 
Back
Top