Rich Presence
Manages Steam and Discord rich presence status, showing what the player is doing (level, vehicle, activity).
Manages Steam and Discord rich presence status, showing what the player is doing (level, vehicle, activity).
Overview
util_richPresence updates Steam rich presence text and Discord activity based on the current game state - which level is loaded, which vehicle is active, whether the player is in a scenario, mission, editor, or freeroam. Also integrates with Steam Timeline for event markers (crashes, laps, drifts).
Extension path: lua/ge/extensions/util/richPresence.lua
Exports (M)
| Function | Signature | Description |
|---|---|---|
set | (v) → bool|nil | Sets Steam rich presence string. Returns success. |
onExtensionLoaded | () | Initializes Steam/Discord presence, registers timeline callbacks. |
onExtensionUnloaded | () | Clears presence and removes timeline callbacks. |
onSettingsChanged | () | Responds to rich presence toggle in settings. |
onVehicleSwitched | (oldId, newId, player) | Updates vehicle name in presence. |
onClientPostStartMission | (levelPath) | Updates level name in presence. |
onGameStateUpdate | (state) | Refreshes presence on game state changes. |
onAnyMissionChanged | () | Refreshes presence when missions change. |
onEditorActivated | () | Updates presence and sets Steam timeline to editor mode. |
onEditorDeactivated | () | Reverts presence from editor mode. |
onUiReady | () | Sets Steam timeline game mode on UI load. |
onUiChangedState | (toState, fromState) | Updates timeline game mode on UI state transitions. |
onResetGameplay | () | Adds "reset" timeline event. |
onNewAttempt | (data) | Adds "New attempt" timeline event. |
onAttemptFailed | (data) | Adds "Failed" timeline event. |
onAttemptCompleted | (data) | Adds "Completed" timeline event. |
onRaceWaypointReached | (data) | Adds race waypoint timeline event. |
onRaceLap | (data) | Adds lap timeline event with time string. |
onRaceBranchChosen | (data) | Adds race branch timeline event. |
onRaceResult | (data) | Adds race result timeline event. |
onMissionAttemptAggregated | (attempt, mission) | Adds mission result timeline event. |
M.clientEndMission | (levelpath) | - |
M.clientPreStartMission | (levelpath) | - |
Internals
State
M.state = {
levelName = "", -- Human-readable level name
vehicleName = "", -- "Brand Model" string
levelIdentifier = "" -- Lowercase level ID for Discord asset matching
}Message Formatting (msgFormat)
Builds a presence string like:
"Playing Freeroam on East Coast Usa with Gavril D-Series""Using World Editor on Italy""Walking around on Grid Map"
Sets both Steam (timelineSetStateDescription) and Discord (setActivity) with level images and vehicle info.
Discord Assets
Level images are matched against lvlAssets (e.g., lvl_east_coast_usa). Unmatched levels use missingnormaltexture.
Steam Timeline Events
Registered via gameplay_statistic.callbackRegister:
| Stat Key | Icon | Title | Type |
|---|---|---|---|
vehicle/crash | steam_death | Crash | instant |
vehicle/airtime.time | steam_effect | Air | range |
vehicle/rollover | steam_starburst | Rollover | instant |
vehicle/jturn | steam_triangle | jturn | instant |
drift/crashes | steam_bolt | drift crash | instant |
| M.onDeserialized | varies | Assigned as nop -- do not remove |
| M.richPresenceEnabled | varies | Assigned as true |
Toggleable Functions
Rich presence can be disabled via settings. When disabled, the internal set function is replaced with nop. Internal builds disable presence by default.
How It Works
- On load, initializes Steam/Discord presence and registers timeline stat callbacks.
- Vehicle switches and level loads update
M.stateand callmsgFormat(). msgFormat()builds a descriptive string and pushes it to Steam and Discord.- Game events (crashes, laps) are reported to Steam Timeline for replay highlights.
Lua Examples
-- Manually set presence text
extensions.util_richPresence.set("Testing mods")
-- Check current state
local state = extensions.util_richPresence.state
print(state.levelName, state.vehicleName)Additional Exports
M.onAnyMissionChanged- (undocumented)M.onAttemptCompleted- (undocumented)M.onAttemptFailed- (undocumented)M.onClientPostStartMission- (undocumented)M.onEditorActivated- (undocumented)M.onEditorDeactivated- (undocumented)M.onExtensionLoaded- (undocumented)M.onExtensionUnloaded- (undocumented)M.onGameStateUpdate- (undocumented)M.onMissionAttemptAggregated- (undocumented)M.onNewAttempt- (undocumented)M.onPursuitOffense- (undocumented)M.onRaceBranchChosen- (undocumented)M.onRaceLap- (undocumented)M.onRaceResult- (undocumented)M.onRaceWaypointReached- (undocumented)M.onResetGameplay- (undocumented)M.onScenarioChange- (undocumented)M.onScenarioFinished- (undocumented)M.onScenarioRestarted- (undocumented)M.onScenarioUIReady- (undocumented)M.onSettingsChanged- (undocumented)M.onUiChangedState- (undocumented)M.onUiReady- (undocumented)M.onVehicleSwitched- (undocumented)M.set- (undocumented)