| name | f8-features-timer-workflow |
| description | Use when implementing or troubleshooting Timer feature workflows — Timer, FrameTimer, server time sync, extensions, pause/resume in F8Framework. |
Timer Feature Workflow
⚠️ IMPORTANT: Before using this feature, you MUST formally initialize F8Framework in the launch sequence. Ensure ModuleCenter.Initialize(this); has run first, then create the required module, for example FF8.Timer = ModuleCenter.CreateModule<TimerManager>();.
Use this skill when
- The task is about timers, frame-based timers, delayed actions, or server time sync.
- The user asks about pause/resume, repeat actions, or application focus handling.
Path resolution
- Prefer project source at Assets/F8Framework.
- For usage docs, read: Assets/F8Framework/Tests/Timer/README.md
Sources of truth
- Runtime module: Assets/F8Framework/Runtime/Timer
- Test docs: Assets/F8Framework/Tests/Timer
Key classes and interfaces
| Class | Role |
|---|
TimerManager | Core module. Access via FF8.Timer. |
API quick reference
Standard Timer
int id = FF8.Timer.AddTimer(this, 1f, 0f, 3,
() => { LogF8.Log("tick"); },
() => { LogF8.Log("done"); },
ignoreTimeScale: false);
Extension methods (simplified)
FF8.Timer.AddTimer(1f, () => { });
FF8.Timer.AddTimer(1f, false, () => { });
FF8.Timer.AddTimer(1f, 1, () => { }, () => { });
this.AttachTimerF8(1f, onTick, onComplete, ignoreTimeScale);
this.DelayTimerF8(1f, () => { });
this.IntervalTimerF8(1f, () => { });
this.RepeatTimerF8(1f, 5, () => { });
this.UntilTimerF8(1f, () => true, () => { });
Frame Timer
int id = FF8.Timer.AddTimerFrame(this, 1f, 0f, -1,
() => { LogF8.Log("tick"); },
() => { LogF8.Log("done"); },
ignoreTimeScale: false);
FF8.Timer.AddTimerFrame(1f, () => { });
FF8.Timer.AddTimerFrame(1f, false, () => { });
FF8.Timer.AddTimerFrame(1f, 1, () => { }, () => { });
Timer control
FF8.Timer.RemoveTimer(id);
FF8.Timer.Pause();
FF8.Timer.Resume();
FF8.Timer.Restart();
Application focus
FF8.Timer.AddListenerApplicationFocus();
Server time sync
FF8.Timer.SetServerTime(1702573904000);
long serverTime = FF8.Timer.GetServerTime();
float gameTime = FF8.Timer.GetTime();
Workflow
- Choose timer type: time-based (
AddTimer) or frame-based (AddTimerFrame).
- Use extension methods for common patterns (delay, interval, repeat, until).
- Pass
this as owner for auto-cleanup when MonoBehaviour is destroyed.
- Use
ignoreTimeScale: true for UI timers that should work during pause.
- Set up
AddListenerApplicationFocus() for mobile pause handling.
- For online games, sync with
SetServerTime().
Common error handling
| Error | Cause | Solution |
|---|
| Timer continues after object destroyed | Missing owner reference | Pass this as owner |
| Timer not ticking during pause | ignoreTimeScale is false | Set ignoreTimeScale: true |
| Server time drift | Network latency | Re-sync periodically |
Cross-module dependencies
- Event: Uses ApplicationFocus event for auto-pause.
Output checklist
- Timer type and pattern selected.
- Owner set for auto-cleanup.
- TimeScale handling configured.
- Validation status and remaining risks.