Chunk System
The chunk system procedurally generates the forest trail that players navigate. Chunks stream ahead of the player and despawn behind them.
Pipeline Overview
Server Startup
→ Load start chunk (ChunkPrefab_Start)
→ Prewarm 3 chunks ahead
→ Sync game seed to clients
Heartbeat (0.25s)
→ Update safe zone players
→ Ensure chunks ahead for all players
→ Check run completion
→ Process pending chunk queue (one per tick)
→ Process pending unload queue (one per tick)
Key Files
| File | Purpose |
|---|---|
chunk-service.ts | Main orchestrator — heartbeat, safe zones, run completion |
chunk-generator.ts | Template cloning, positioning, overlap detection |
chunk-prepper.ts | Creates Start/End parts from baseplate attachments |
pacing-manager.ts | Difficulty cycle, safe zone markers, enemy scaling |
danger-zone-manager.ts | Ring zones around baseplates for enemy spawning |
baseplate-manager.ts | Octree-based spatial indexing of chunk positions |
Chunk Creation Flow
- Template Selection —
getChunkForPacing()picks fromReplicatedStorage.Prefabs.Cyclable- SafeZone chunks filtered by
ChunkType === "SafeZone"attribute - Up to 5 attempts to avoid overlap
- SafeZone chunks filtered by
- Preparation —
prepareChunk()creates Start/End parts from baseplate attachments - Positioning — End-to-end alignment using Start/End attachment CFrames
- Overlap Check — AABB intersection with 5-stud padding against all placed chunks
- Registration — Tagged
Gameplay_Chunk, baseplate registered in octree - Danger Zones — Deferred ring creation around the baseplate
Pacing System
The game cycles through phases, with safe zones at fixed trail markers:
Calm (2 chunks) → Tense (2 chunks) → Challenge (2 chunks) → repeat
Safe Zones at markers: 10, 30, 70
Trail Markers
- ~1 marker per 2 chunks:
trailMarker = floor(chunkIndex / 2) + 1 - Physical wooden posts placed by
GameplayChunkcomponent - Max trail marker: 30 (MVP) — chunks stop generating after this
Difficulty Scaling
- Multiplier:
1.0 + (trailMarker × 0.05), capped at 3.0 - Affects enemy density and aggression per phase
Chunk Unloading
When enabled, chunks 3+ behind the furthest-back player are queued for unloading:
- Path nodes re-parented to
UnloadedPathNodesfolder (keeps refs valid) - Danger zones removed
- Chunk model destroyed
- Echo boundary updated for late joiners
Safe Zones
Safe zone detection uses a dual approach:
- Registered parts — Tagged
SafeZoneparts checked viaPointToObjectSpace - Pacing-based — Chunks with
isSafeZonepacing flag
Safe zone effects (0.25s tick):
- Health regen: 10 HP/sec (2.5 per tick)
- Insanity decay (client-side)
- Enemy exclusion
Server Verification
Client detects safe zone entry via ZonePlus, fires remote. Server verifies with retry logic (3 attempts, 0.15s apart) to account for network latency.
Run Completion
When a player reaches the final safe zone (marker 30):
checkRunCompletion()detects player on SafeZone chunk at max markerrunCompleteCallbackfires- Player teleported to lobby