Time
Poll-only named timers (integer seconds). No automatic ticking — caller must invoke Tick with deltaSeconds (e.g. each frame or turn).
State (Ephemeral)
Timers stored under an internal root (see EnsureTimersRoot / BuildTimersPayload in source) as a map timerId → state (value, start, target, direction, running, …).
How it looks in ephemeral.json
The Gnosis Engine’s default template (Assets/Resources/Data/ephemeral.json) uses timers for per-timer objects and activeTimers for quick flags. timerId strings are defined by your game; shape is like:
{
"Ephemeral": {
"timers": {
"levelCountdown": {
"timerId": "levelCountdown",
"direction": "down",
"start": 60,
"value": 60,
"target": 0,
"running": true,
"finished": false
},
"runElapsed": {
"timerId": "runElapsed",
"direction": "up",
"start": 0,
"value": 0,
"target": 0,
"running": true,
"finished": false
}
},
"activeTimers": {
"levelCountdown": true,
"runElapsed": true
}
}
}Exact field names may match GnosisTimeEvents payload constants in code; when in doubt, dump Ephemeral JSON from UnityGnosisEngine in Play Mode and compare.
Events
String ids are in GnosisTimeEvents (Runtime/GnosisEngine/Source/Services/Ephemeral/Services/TimeService/). REQUEST_* are interceptable where noted; FACT_* report outcomes (this service stays poll-oriented for values — see class summary in source).
| Event id | Kind |
|---|---|
REQUEST_TIME_CREATE | Request |
FACT_TIME_CREATED | Fact |
REQUEST_TIME_ADD | Request |
FACT_TIME_ADD | Fact |
REQUEST_TIME_REMOVE | Request |
FACT_TIME_REMOVE | Fact |
FACT_TIME_FINISHED | Fact (timer reached target / terminal) |
Timer field names in payloads match PAYLOAD_* on the same class (timerId, value, target, direction, running, finished, delta, allowed, reason, …).
Functions
| Function | Parameters |
|---|---|
Tick | deltaSeconds |
CreateTimer | timerId, direction (up/down), optional start, target, running |
DeleteTimer | timerId |
SetRunning | timerId, running |
StartTimer / PauseTimer / ResumeTimer | timerId |
ResetTimer | timerId |
SetValue | timerId, value |
AddTime / RemoveTime | timerId, delta |
AddStartTime | timerId, delta |
GetTimer | timerId |
HasTimer | timerId |
IsFinished | timerId |
ListTimers | — |
Many operations support request interceptors in partials — check TryCreateTimerWithInterceptors etc.
Usage example — create and reset timers
Create a named timer with Time.CreateTimer. Payload keys are the string values from GnosisTimeEvents in the package (e.g. "timerId", "direction", "target", "running"):
private void EnsureLevelCountdownTimerStarted()
{
if (Context?.Store == null || Context.CallService == null)
return;
bool isCountdown = IsCountdownGameMode();
var create = GnosisNode.CreateObject(Context.Store);
create.Set("timerId", "levelCountdown"); // your game’s timer id string
create.Set("direction", isCountdown ? "down" : "up");
create.Set("start", isCountdown ? levelCountdownSeconds : 0);
create.Set("target", 0);
create.Set("running", true);
CallService("Time", "CreateTimer", create);
}Reset then start the same timer id:
private void ResetLevelCountdownTimer()
{
if (Context?.Store == null || Context.CallService == null)
return;
var parameters = GnosisNode.CreateObject(Context.Store);
parameters.Set("timerId", "levelCountdown");
CallService("Time", "ResetTimer", parameters);
CallService("Time", "StartTimer", parameters);
}Checking whether a timer already exists uses a dot path on the live state tree:
private bool TryEphemeralHasTimer(string timerId)
{
var n = Context.State.Root.GetAtPath($"Ephemeral.timers.{timerId}");
return n.IsValid && n.Type == GnosisValueType.Object;
}
// e.g. Ephemeral.timers.levelCountdown for the id above(Typical host-side pattern; use your own timer id strings.)
Statistics
None.