Train/Rail Event Implementation (Unified Tick + Snapshot Policy)
Overview
Use this skill when changing train/rail event contracts and handler wiring under unified ordering.
Reuse-First Rule
- Before adding new event-side helpers, search existing train/rail event implementations first.
- Prefer reusing domain logic in
Game.Trainover re-implementing logic in handlers. - If duplication is unavoidable, record
WHY_NEW_IMPLEMENTATIONin code/PR notes. - Recommended pre-check:
rg --line-number "TickUnifiedId|NextTickSequenceId|TrainUnitSnapshot|TickDiffBundle" moorestech_client/Assets/Scripts moorestech_server/Assets/Scripts
Core Concepts
1) Unified ordering key
TickUnifiedId = ((ulong)ServerTick << 32) | TickSequenceId.TickSequenceIdis server-allocated and per-tick monotonic.
2) Unified event queue
- Client handlers enqueue events into
TrainUnitFutureMessageBuffer. - Buffered events apply by unified id order.
3) Snapshot-first train sync
- Structural TrainUnit/TrainCar changes use
va:event:trainUnitSnapshot(upsert/delete). - Full-unit resync uses
va:getTrainUnitSnapshots.
4) TickDiffBundle role
va:event:trainUnitTickDiffBundletransports hash + per-tick diffs and drives simulation timing.Diffs[]can be empty and still acts as simulation trigger.
Emission Patterns
A. Tick simulation path
- Server emits hash state.
- Server advances tick, resets sequence, runs simulation.
- Server emits pre-sim diff signal.
- Tick diff bundle packet broadcasts ordered hash/diff payload.
B. Train structure change path
- Domain/protocol mutates train state.
- Server emits per-unit snapshot notify (
NotifySnapshot/NotifyDeleted). - Snapshot packet broadcasts
va:event:trainUnitSnapshot.
C. Rail graph change path
- Rail node/connection packets allocate
TickSequenceIdand broadcast ordered diff events.
Implementation Rules
Server-side
- Allocate sequence IDs only via
TrainUpdateService.NextTickSequenceId(). - Every train/rail event carries
ServerTickand sequence ID. - Train composition changes should prefer snapshot notify path over new ad-hoc car events.
Client-side
- Handlers enqueue events, do not apply immediately.
- Snapshot handlers apply upsert/delete at buffered tick and reconcile train/car visuals.
- TickDiffBundle handler preserves current semantics: pre-sim diff apply + local simulation update.
Implementation Checklist
- Choose correct path (tick bundle, snapshot, rail diff).
- Keep ordering fields in payload and on apply path.
- Keep stale-event protection for destructive operations.
- If state shape changes, update packet mapping + client apply + tests.
- Verify unified-id ordering behavior with relevant tests.
Converted and distributed by TomeVault — claim your Tome and manage your conversions.