Skip to content

feat(flight): Milestone 3 — F-key Drone Flight Mode#16

Merged
maxfelker merged 4 commits into
mainfrom
feature/biome-m3-elevation
Mar 2, 2026
Merged

feat(flight): Milestone 3 — F-key Drone Flight Mode#16
maxfelker merged 4 commits into
mainfrom
feature/biome-m3-elevation

Conversation

@maxfelker

Copy link
Copy Markdown
Owner

Milestone 3: Flight Mode

New Feature: Press F to Toggle Flight

Control Ground Flight
WASD Horizontal walk (7.5 u/s) 3D look-direction fly (75 u/s)
Shift Sprint (20 u/s) 2× fly speed (150 u/s)
Space Jump Ascend directly
F Toggle flight

How It Works

  • F key fires a one-frame flyToggle edge event via InputSystem
  • Go physics.Update() toggles PlayerState.Flying on receipt
  • Flight physics: gravity disabled, movement follows full 3D look direction (pitch controls vertical lift component), no slope clamping
  • Ground physics: unchanged — gravity, slope limits, coyote time, jump all work as before
  • FlySpeed = WalkSpeed × 10 = 75 u/s

Testing

  • 4 new physics tests: toggle on/off, no gravity hover, directional movement, speed constant
  • All Go physics + biome tests pass
  • All TypeScript tests pass
  • Docker prod build verified

maxfelker and others added 4 commits March 1, 2026 16:26
- PlayerState.Flying bool: tracks flight mode state (serialized to TS)
- InputState.FlyToggle bool: edge-triggered F key press (one frame only)
- FlySpeed = WalkSpeed * 10 = 75 units/s (10x ground walk speed)
- Flight physics: no gravity, moves in full 3D look direction (pitch
  controls vertical component), Jump key ascends directly
- Sprint in flight = 2x fly speed (150 units/s)
- Ground mode physics unchanged
- InputSystem: flyTogglePending flag fires once per F keydown then resets
- FPSCamera.PlayerState: added flying field
- 4 new physics tests: toggle, no-gravity, direction, speed constant

Controls:
  F          — toggle flight mode
  WASD       — move in look direction (pitch-coupled vertical in flight)
  Space      — ascend directly (flight)
  Shift      — 2x speed boost (flight + ground sprint)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three fixes for flight-mode terrain pop-in at 75 u/s:

1. Render radius: 1536 → 2560 units (~5 chunk buffer vs 3)
   DistanceThreshold: 2560 → 4608 (wider eviction window)

2. Adaptive stream trigger in GameEngine:
   - Flying: re-stream every 64 units (was 128)
   - Flying: stream position offset 1024 units ahead in look direction
     so chunks are pre-generated before the player arrives
   - Grounded: unchanged (128 unit trigger)

3. ChunkWorkerPool: 4 parallel WASM workers for chunk generation
   - Primary worker handles physics ticks + world state (unchanged)
   - Pool workers each load WASM independently, route generateChunk
     calls round-robin → up to 4 chunks generate simultaneously
   - Pool initialized lazily in WasmClient.initWorld()
   - Falls back to primary worker if pool not yet ready

Result: at 75 u/s flight speed, 5-chunk buffer + 1-chunk lookahead
+ 4x parallel generation means terrain stays ahead of the player.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pool workers each have their own WASM instance. goGenerateChunk stores
globalHeightmaps in the pool worker's instance, but goUpdatePlayer (physics)
runs on the primary worker whose globalHeightmaps was always empty.
Result: SampleHeight returned 0 → player grounded at Y≈1.25 → fell through
all terrain.

Fix: add go_storeHeightmap(cx, cz, Float32Array) to the primary worker.
After each pool chunk generation, WasmClient fires a storeHeightmap message
to the primary worker (fire-and-forget, id=-1 sentinel). Primary worker
stores the heightmap in its globalHeightmaps, making it available to physics.

go_storeHeightmap uses Uint8Array view + js.CopyBytesToGo for efficient bulk
copy, then reinterprets bytes as float32 (avoids 16641 individual JS→Go
float conversions).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
filterByFrustum tested chunks with AABB maxY=HEIGHT_SCALE(64) but mountain
terrain reaches HEIGHT_SCALE*10=640 (10x HeightMultiplier). When flying
above Y=64, the frustum bottom plane rose above the AABB top, incorrectly
culling visible chunks → flicker and disappearing terrain.

Fix: maxTerrainHeight = HEIGHT_SCALE * 10 = 640.
Also corrects minY from -64 to 0 (terrain is always non-negative).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@maxfelker maxfelker merged commit 3f04c7a into main Mar 2, 2026
1 check passed
@maxfelker maxfelker deleted the feature/biome-m3-elevation branch March 2, 2026 20:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant