Time Manager
UsewithTimeManager() to add synchronized game time without adding methods to RpgMap.
The server owns the canonical time. The client receives a map snapshot and infers the displayed time locally from elapsedMinutes, scale, paused, and serverTimestamp.
Register the Module
You can use the same module object on both sides:Units and limits
There is one clock for the whole server: every map shares the same time, and
pause() or set() applies to all of them. To keep a map out of the day night cycle (a cave, an interior), see Per map lighting.
Clock on screen
hud draws the clock on the client: a pill with the day and the hour, and a round medallion whose sky follows the
hour (a sun that crosses it, a moon and stars at night, colors that change at dawn and dusk). It is off by default.
The client must register the same module (
provideClientModules([TimeManagerModule])) and load the styles
(import "@rpgjs/ui-css/index.css"). “Day N” counts the days since the start. The texts are the rpg.time.*
keys (English and French are included). The catalogue of the GUI has it in Compositions / Game clock.
Server API
UseTimeManager from server hooks, events, or services:
Client API
UseClientTimeManager for display logic:
Snapshot
The synchronized map field is internal and namespaced:TimeManager and ClientTimeManager instead of reading __rpgjsTime directly.
Lighting
Whenlighting.enabled is true, the server can apply map lighting from time phases:
Day night cycle
UsedayNight to replace the phases by the continuous color grading of the DayNightCycle preset. The scene follows the hour of the time manager and the spots of the map are lit at night (see Lighting):
The hooks
onLightingPhaseChange and onPhaseChange (the same transition, the second one reads better for gameplay rules) receive those keys. The state exposes them too: state.phase and state.hourFloat (the hour with decimals, 18.5 is 18:30).
Per map lighting
The time manager lights every registered map. Override or disable it per map, likeweather.maps:
lighting:
Client module
The client must register the same module (provideClientModules([TimeManagerModule])). Without it the client falls back to a local clock and shows the wrong hour: a warning is logged in the console when the server drives the cycle with the time manager.
The client projects the time from the clock of the server, so a client whose clock is off still shows the same hour as the other players.
Weather Ambiences
Whenweather.enabled is true, the server can roll weather ambiences per map. Each ambience has a weight and a game-time duration. When the duration expires, the server rolls the next ambience and applies it with the existing map weather API.
maps[mapId] overrides the default weather table for that map. A weather: null ambience clears the map weather. If weather is omitted, disabled, or no table exists for a map, the time manager does not modify that map’s weather.
Weather remains server-owned. Clients receive the regular weatherState map update and should read engine.sceneMap.weather() or engine.sceneMap.getWeather() for rendering.
Environment Hooks
Usehooks on withTimeManager() when the environment should drive gameplay rules from the plugin itself:
onBeforeWeatherChange() can return false to cancel the roll, or another { key, ambience } candidate to replace it. Initial map registration is silent: hooks run only after an actual time, lighting, or weather transition.
Transition payloads include the current map so plugin hooks can update synchronized map state or trigger map-local systems.
Events can react locally by declaring matching methods: