Three networks. pstn is the public phone network, where anything with a number can be dialled from anywhere. norad is a leased line inside the building, with no number to dial. bus is local to one machine and reaches nothing outside it. W.O.P.R. answers on the first two: the same computer that picks up a call from a bedroom in Seattle is on NORAD's internal net. That is the film's premise, and it is one line in a manifest.
THE EXCHANGE — WHO CAN DIAL WHOM
THE MODULES
| # | Module | Tech | Responsibility |
|---|---|---|---|
| 1 | WOPR Core ("the Mainframe") | Fortran 90 (gfortran) | Game theory, state mechanics, brute-force simulation. Pure compute; reads state from stdin, writes state to stdout. No network, no DB. |
| 2 | Comms Simulation Layer | TypeScript/Node middleware over WebSocket | Imposes the era's constraints (baud, latency, framing, dial-up handshake) on every link between surfaces and the bridge. Toggleable — "the limitations at that time," running as real code. |
| 3 | API / Emulation Bridge | Python + FastAPI | The execution wrapper and the connection monitor. Spawns the Fortran executable per request, parses stdio, and holds what each session is attached to — a game, Joshua, or the NORAD operations console — sending every non-reserved line to that program. Owns state read/write to the databanks. |
| 4 | NORAD Databanks | Neon (plain Postgres) | Sessions, game states, historical event logs, DEFCON "clearances." Source of truth. |
| 5 | Joshua | selectable: Anthropic Claude API / Common Lisp F.D.P. / scripted | The conversational persona. Three engines behind one interface (JOSHUA_ENGINE): the modern LLM substitution, the period-Lisp Falken Dialogue Processor, or the 1983-honest keyword engine. All emit terse teletype responses. |
| 6 | Surfaces | Next.js (React) + shared CRT component lib | Five front-ends (see §5), each sitting behind a different simulated link. |
UI ENDPOINTS
| SURFACE | PATH | ROLE |
|---|---|---|
| HOME TERMINAL | /terminal/ | Bedroom dial-up console; public phone book and 300-baud carrier. |
| NORAD TERMINAL | /norad/ | Operator console; amber CRT, DEFCON header, leased-9600 command link. |
| NORAD BIG BOARD | /bigboard/ | War-room visualization; GTW feed, DEFCON board, world/polar maps. |
| WOPR PANEL | /panel/ | Machine-room cabinet face; lamp banks and launch-code readout. |
EXECUTION MODEL
The Fortran core is a stateful, interactive program. The bridge in front of it is stateless HTTP/WebSocket, with the databanks holding the truth. The two meet the simplest way we could find: spawn a fresh core process for every move, and reload the state each time.
- A move/command arrives at the bridge (through the comms layer).
- The bridge loads the relevant
game_staterow from the databanks. - The bridge spawns a short-lived Fortran process, writes the serialized state + the new input to stdin, and reads the resulting state from stdout (wire format in
games.md). - The process exits. The bridge persists the new state to the databanks and emits output back through the comms layer.
What that buys:
- The bridge holds no game state in memory, so a crash loses nothing and any instance can pick up any session.
- The same state and input always produce the same output, so the Fortran I/O is tested with golden files and every feasibility claim can be re-run.
- Concurrency is bounded by a process pool with per-call timeouts and explicit error mapping — a hung or crashing core returns a defined error frame, never a stuck socket. See
api-contract.md.
A 1980s mainframe would not fork a process per move; it would keep one resident program multiplexing many terminals. But the contract — load state, compute, store state — is the same shape as the era's batch and transaction processing. We document the difference rather than hide it.