Skip to main content

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

FilePurpose
chunk-service.tsMain orchestrator — heartbeat, safe zones, run completion
chunk-generator.tsTemplate cloning, positioning, overlap detection
chunk-prepper.tsCreates Start/End parts from baseplate attachments
pacing-manager.tsDifficulty cycle, safe zone markers, enemy scaling
danger-zone-manager.tsRing zones around baseplates for enemy spawning
baseplate-manager.tsOctree-based spatial indexing of chunk positions

Chunk Creation Flow

  1. Template SelectiongetChunkForPacing() picks from ReplicatedStorage.Prefabs.Cyclable
    • SafeZone chunks filtered by ChunkType === "SafeZone" attribute
    • Up to 5 attempts to avoid overlap
  2. PreparationprepareChunk() creates Start/End parts from baseplate attachments
  3. Positioning — End-to-end alignment using Start/End attachment CFrames
  4. Overlap Check — AABB intersection with 5-stud padding against all placed chunks
  5. Registration — Tagged Gameplay_Chunk, baseplate registered in octree
  6. 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 GameplayChunk component
  • 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:

  1. Path nodes re-parented to UnloadedPathNodes folder (keeps refs valid)
  2. Danger zones removed
  3. Chunk model destroyed
  4. Echo boundary updated for late joiners

Safe Zones

Safe zone detection uses a dual approach:

  • Registered parts — Tagged SafeZone parts checked via PointToObjectSpace
  • Pacing-based — Chunks with isSafeZone pacing 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):

  1. checkRunCompletion() detects player on SafeZone chunk at max marker
  2. runCompleteCallback fires
  3. Player teleported to lobby