Skip to content

Architecture ​

SKYWARD separates the render loop, deterministic simulation, decision policy, and gateway boundary so the game can keep flying when a remote answer is late.

Runtime map ​

text
Three.js renderer (requestAnimationFrame)
        ▲ reads current state
        │
simulation state (60 Hz) ── observe() ── telemetry
        ▲                              │
        │ controlsForDecision()        │ async /api/decide
        │                              ▼
localDecision() ◄── fallback ◄── Express + JevClient

Simulation contract ​

src/simulation.ts owns fixed-step arcade physics: aircraft attitude, throttle, targets, projectiles, swept collision, terrain danger, stall recovery, flares, score, and win/loss. observe() exposes bounded tactical telemetry. localDecision() is deterministic and needs no network.

The browser advances physics at 60 Hz and renders Three.js scenery, HUD, radar, and camera views. A JEV answer is translated into bounded controls; it never replaces the physics clock.

Gateway boundary ​

server/index.ts exposes GET /api/status and POST /api/decide on 127.0.0.1:4173. server/validation.ts rejects malformed or unbounded telemetry. server/jev.ts loads the key on the server, calls the evaluation endpoint, parses Choice/Boolean/Score answers, enforces a deadline, and exposes safe errors.

Public/static boundary ​

The Pages site documents the game and links to /play/, a static manual/local-AI experience. Live JEV remains a local Node-server feature because a public static page must not expose AI_GATEWAY_API_KEY.

For the original model and rendering investigations, use the permanent GitHub investigation notes.

SKYWARD / JEV Flight Lab