Commit Graph

12 Commits

Author SHA1 Message Date
type-two
682b7d88fa Ship to monsterrobot.games, and a model card
Deployed to monsterrobot.games/games/haxtory/ — the botchat box, bind
mounted into forum-nginx, same pattern as the other games.

card.html is a model card in the AI sense rather than the arcade sense:
what the game is, the three ideas it is built on, an itemised list of
which parts are historically true (the frequencies, Strowger, the 1-in-7,
the 75 cents, SS7, the Linux dates) and which parts are invented (all the
people, the board itself, the romance), and then an honest list of what it
does not do — it is short for what it is, 75 of 200 philes, no
multiplayer, not accessible, unprofiled, and never playtested by a
stranger. Linked from the boot screen.

Also fixed: the blue box has been sitting in the far corner of the frustum
since it was built, where perspective squashed it into a sliver and half
of it fell outside the visible cone. I twice assumed occlusion and twice
wrote it off as a capture artifact. It was framing — the camera was
pointed past the only object in the level that matters. Camera now faces
it, and the routing card and Joybubbles moved to balance the shot.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 21:46:48 +10:00
type-two
cb22239363 The soundtrack is built out of the signal
The last structural promise in the design doc. No level gets a chord any
more. Every bed in the game is derived from a real number belonging to the
era it plays under, and src/score.js says which one and why in a comment
above each line.

  coldboot/stack  1000 Hz, the reference tone every piece of telecoms test
                  gear on earth agrees on. The fortress is tuned to a
                  calibration signal.
  timewait        50 Hz mains and its harmonics. The room's own hum was
                  always the entire score; now the bed agrees with it.
  war             the 1800 Hz V.32 carrier folded down, with dial-up hiss
                  under it, because everybody on EFnet was on a modem.
  smash           0x90 is the NOP. Read as a number it is 144, so the sled
                  has a pitch and the level is tuned to the byte you slide
                  down.
  worm            seven partials, and the seventh one is detuned. One in
                  seven, as a chord.
  cuckoo          45.45 baud — the Model 33 rate, 22 ms a bit. Fifty of
                  them in a basement is what he actually heard all night.
  board           the 1200 Hz V.22bis carrier folded four times, which is
                  the doc's exact phrase: a modem carrier detuned into a
                  pad.
  shell           the 750 Hz terminal bell over Helsinki's 50 Hz mains.
  handshake       silence. The fight is the score; anything underneath is
                  noise competing with the only thing in this game that
                  has to be listened to.
  copper          20 Hz ringing current, 50 Hz mains, and Strowger stepping
                  at ten pulses a second. Three real clocks, and the
                  cathedral is the beat they make against each other.
  bluebox         the six MF tones at once. That is literally what is
                  inside a blue box.
  climb           all of it, layered.
  root            2600 Hz folded six times until it is a low room tone.
                  The number the whole game turns on, finally at rest.

ESTABLISHED gets its own cue rather than a bed: 350 and 440, which is the
dial tone the handshake arena opened on and called the sound a line makes
when nothing is happening — with something finally on it.

Fixed while building: the pulse gate was driven by a bare square
oscillator swinging -1..+1, so its off half was not silence, it was the
same tone phase-inverted. Tremolo where a clock was wanted. DC offset now.

All 14 hops swept clean, and no voices leak between them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 20:17:18 +10:00
type-two
4554bfcd2d He stops arguing and edits the program, and the line changes its mind
The uname escalation. rms does not get angrier, he gets tireder — each
interjection shorter and flatter and typed faster than the last, down to
"GNU/linux.", then "...", then "no. i am not doing this again." And then
he stops trying to change your mind and goes and rebuilds uname so that it
says GNU/Linux, and installs it, and does not ask anybody.

Which is, in fairness, the entire strategy. He never won the argument
about naming and was never going to. What he did instead was write a
compiler, a linker, a shell, a libc and a debugger, put all of them under
a licence that forces everyone downstream to keep them free, and wait.
That part worked completely.

THE RETRAIN — the last cross-cutting system in the design doc that was
not in. Real modems renegotiated mid-call: the copper got wet, somebody
picked up an extension, the exchange rerouted you through a worse pair,
and the two ends stopped and did the whole handshake again in the middle
of your download. So now, once per run, somewhere after hop 51, wherever
you happen to be standing, the line goes and takes a baud rate off you.

The way back is the beat you were taught at hop 47: SPACE on the ANSam
phase reversal, 450 ms, four clean ones. Spamming it fails, correctly.
Terminal levels opt out with noRetrain, because taking SPACE off somebody
mid-sentence is not a mechanic, it is a bug with a story attached.

Fixed while testing: the reversal flash was decaying on a setTimeout while
the beat it was cueing ran on dt. Two clocks for one event. Frame-based
now, which is both more correct and the reason the win path is reachable.

75 philes. All 14 hops swept clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 18:40:06 +10:00
type-two
e5ecadeab5 THE SHELL — the thing that killed the board
Day three of THE BOARD already names what kills it: about a third of you
have got shell accounts now and are not calling any more, and i do not
blame you, because it is better, it is genuinely better. The player never
got to see it. Now they do, immediately afterwards, while the board's
ghost is still warm.

kruuna.helsinki.fi, 1991. It connects instantly, with no dial tone, no
ring and no busy signal, and that silence after eight minutes of the board
is the whole opening beat. who(1) shows the people who are on the machine
at this second, against a board that had forty-four users in nine years
and could hold one at a time. talk(1) puts every character on screen as it
is typed, because that is what talk did. And make compiles a kernel in the
top four lines while you carry on using the shell underneath it — two
things at once, demonstrated rather than stated, which the board could
never do.

Then the interjection. rms has been on ttyp7 since six in the morning. He
waited until the level printed a whole operating system over a build log
in which every single line is gcc, and then he opened a talk request, and
he is right. If you never answer it he leaves mail instead, because of
course he does.

The closing speech now credits the compiler, the linker, the shell, make
and libc, which were all finished and free years before the kernel was.

74 philes. All 14 hops swept clean. README and STAGES.md brought current.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 18:18:37 +10:00
type-two
10b6c8fdf5 Seven floors, seven jobs
THE STACK had seven layers that all played identically with a different
colour of danger, which is not a layer, it is a reskin. Each floor now
asks you to do the thing that layer actually does:

  7 APPLICATION   plain. the only polite floor.
  6 PRESENTATION  transcode. the same bytes in two encodings, RAW and
                  BASE64, and only one set of platforms is real at a time.
                  Q switches representation, in mid-air.
  5 SESSION       keep it alive. a platform you have stood on begins
                  closing the moment you leave it. standing still is the
                  mistake.
  4 TRANSPORT     reassemble. they arrived out of order; only the next
                  platform in sequence is solid, and the sequence has
                  nothing to do with where they are in the room.
  3 NETWORK       route. every platform is a router and every router costs
                  a hop out of five. overrun it and the floor ASLR
                  reshuffles under you.
  2 DATA LINK     listen before transmit. shared media, each platform busy
                  on its own cycle, and landing on a busy one collides —
                  with real exponential backoff, 0.35s then 0.7 then 1.4.
  1 PHYSICAL      be a signal. no platforms at all: forty-six segments of
                  a travelling wave you ride, attenuating down the wire.

The canaries and NX floors are retired — the hazard was the only idea each
floor had, and now the verb is.

Fixed in the rebuild: the miss floor was getting a lit edge strip like
every other platform, and it is ninety metres across, so it rendered as a
bright blue disc filling half the screen.

66 philes. All 13 hops swept clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:51:24 +10:00
type-two
2d46960211 Trade Wars, and a branch you can see both sides of
TRADE WARS 2002 is real now. Ten sectors, seven ports, twenty-four turns.
The port classes are the actual ones — three letters for fuel ore,
organics and equipment, B where the port buys from you and S where it
sells to you — and the whole economy is finding two adjacent ports that
disagree with each other about what something is worth. The Ferrengi are
in sector nine and they want your cargo, and you can fight, run or pay.

SPECTRE is a real split screen. Two viewports scissored into the same
render target, two cameras, one post pass over both, and a hard seam down
the middle. The speculative timeline lives on render layer 1, which only
the second camera can see — so the right-hand pane genuinely contains
things the left-hand pane never will, which is the entire point of the
section. Steering is mirrored. The token you carry out of the branch that
gets discarded is only reachable in the pane that stops existing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 17:43:50 +10:00
type-two
594fd584fa An arms race, a cure that cannot get there, and a board that closes
THE WAR — the trojan arms race. WinNuke, Sub7, Smurf, DCC send. Each one
works, and then the level patches it seventy seconds after you first use
it, with the countdown on screen and a line about how it died: a hotfix
went out; the scanners caught up; the amplifiers stopped answering
broadcast; the client asks before it accepts now. You cannot finish the
level on one tactic. An exploit is not a tool you own, it is a window that
is already closing while you are climbing through it.

Plus a rival crew who turn up after the first rejoin, who have read the
same text files you have, and who will take the ghost crown out from under
you during a split.

THE WORM — you can try to stop it. An antidote, three seeds, and it
travels only over live links while you are killing links. It cures fast
and then stops dead with its component severed, while the death count
climbs past it. Measured: 4, 12, 18, 19, stall — dead 20 through 30. It
works perfectly on everything it can reach. It cannot reach the rest,
because you already took the road. The phones ring all night and nobody
can send mail to warn anybody, because the broken thing is the thing you
would have used.

Pacing fix: spread rate now scales with the infection, since every
infected host is running a copy. Correct, and the only way the level ever
reached its own milestones — before this, nothing died inside ten minutes.

THE BOARD — three days.

Day one as before, and you post to FidoNet on the way out. Then the 04:00
run dials five nodes across the world while nobody is awake. Day two the
board knows you: last on yesterday, calls 2, user #44 of 44 — and the
first message is FIDONET quoting what you actually typed, with an answer.
Four days, three boards, a long distance call somebody else paid for.
Received. Hello. If you over-took on the files, your ratio has been
adjusted to 1:1, because he said it would be.

Day three is LAST CALL. Not raided, not busted: the second line was never
coming, the long distance is forty dollars a month out of a job he does
not much like, and a third of them have shell accounts now and are not
calling any more, and he does not blame them, because it is better, it is
genuinely better. Nine years. Forty-four users. Six real names. Never met
one of them. Ratio off, elite board open, the NUP given away because it
does not matter now. He asks nobody to say anything sad in the message
base. They all ignore him.

65 philes. All 13 hops swept clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:54:14 +10:00
type-two
8e194d677e The bridge, the card, and one call followed all the way through
THE BLUE BOX: you are not told the digits any more. The routing card is
on the wall — worked out by hand, traded, kept in a pocket, the only
documentation the long distance network ever had that was written by the
people using it. The objective names a destination and Joybubbles
explicitly refuses to give you the code.

And 2111 is up. A loop-around somebody left in a switch in Kansas,
dialable from anywhere at any point by anyone who knows the number, which
was exactly the problem with it. Six voices, no faces, nobody says their
name, it loops indefinitely, and holding 2600 drops the bridge. After SS7
there is nothing on it.

THE COPPER: start a call at the MDF and follow it. Seven banks of relays
down the aisles, each digit counted out at ten pulses a second because
that is how a step-by-step switch dials — the wiper steps once per pulse
and stops where the pulses stop. It connects. It is a wrong number. The
switch does not mind; it does not know what a number is.

Also fixed in kit: labelTexture ignored newlines, so any multi-line panel
rendered as one enormous single line. The routing card was nine metres
wide before this.

51 philes. All 13 hops swept clean. STAGES.md updated with what landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:34:54 +10:00
type-two
45b3cdfb00 ret2libc, and a climb that is a final exam
SMASHING THE STACK: NX now arrives at the exact moment you reach the
shellcode. Your sixteen bytes are still there, every one of them correct,
and none of them will ever run. Then libc appears — already mapped,
already executable, already somebody else's — and the only way on is to
land on four gadgets in the right order and walk the bridges the chain
builds behind you. The chain is the real one: ret, pop rdi, "/bin/sh",
system. The four decoys are real gadgets that are genuinely no use to you
here, which is what building one of these is actually like.

THE CLIMB: each era now hands back the verb it taught you, once. Seize
the trunk. Mind the wiper. Count the 450 ms reversal. Take the ANSI bomb
and lose your steering for six seconds. Dodge what is still infectious.
Ride the live half. Do not stand on the red. Plus embers, and Log4Shell
finally gets its beat of silence — the world stops and the fortress walks
over and reads your sign.

Balance fix found while testing: the climb is hop 63, so you arrive with
TTL 2 by design, and it had seven gates that each cost a TTL. Two
failures killed you. Nothing in the climb spends TTL now — the ascent is
graded, not lethal, and ROOT's receipt reads the grade. That keeps "TTL
only goes down" intact instead of inventing a heal.

All 13 hops swept: clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:22:38 +10:00
type-two
df02345a61 Tuesday, and a room with people in it
ROOT now reads the save it has been carrying the whole game. The receipt
names your philes, your expiries, the baud you negotiated and lived with,
whether somebody vouched for you, whether you hung up without saying
goodbye. It had all of that and used none of it.

And the FidoNet message comes back. You wrote it at hop 35 and handed it
to the 04:00 mail run and it said it would reach the rest of the world by
Tuesday. Twenty-nine hops later it is Tuesday, and somebody replied,
because somebody always did. The loop now keeps your philes and resets
everything else.

TIME_WAIT is a room instead of six chairs. Sixteen seated, one or two
lines each, most of it not about you. One of them ages out mid-sentence
and nobody in the room looks up. FIN will not tell you about the door
until you have listened to three people who are not him. Stay a full
two-minute lap of the clock and the room notices.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 16:09:46 +10:00
type-two
8030547e3c Philes you can read, a save, and MTU that costs you something
Three holes closed:

  philes  — 40 written, all in src/philes.js so the next 160 is a writing
            job and not a code job. P opens a reader: list on the left,
            the text on the right, attributed to whoever wrote it in
            whatever year they wrote it. Every level now drops at least
            one; previously you collected files you could never open.

  save    — ESTABLISHED. Every hop writes level/ttl/hop/baud/philes/
            cargo/flags to localStorage, and the boot screen offers
            R — RESUME. A 64-hop game with no save is not a 64-hop game.

  MTU     — the HUD has been showing your MTU drop as you take files off
            the board while nothing happened. Now two files are free and
            after that you arrive in pieces, one TTL per extra fragment,
            every hop. You can put things down again from the traceroute
            map. Lore costs distance, which is the economy the whole
            design is built on.

All 13 hops re-swept: clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 15:46:18 +10:00
type-two
696b0c65e8 HANDSHAKE — 13 playable hops, one renderer
You are SYN. You want ACK. Root is the only one who can give it to you.

Three load-bearing ideas, all working:
  - TTL is the health bar and it only goes down. 64 hops, no healing.
  - Bandwidth is resolution. One render target, one shader; at 1200 baud
    and below the 3D scene renders as ASCII glyphs.
  - Every header you drop is a piece of clothing. Seven wireframe shells,
    one per OSI layer, shed on the way down.

Every frequency is the real frequency, synthesised, nothing sampled:
350+440 dial tone, the DTMF matrix, R1 MF pairs at real KP/digit timing,
2600 Hz, ANSam at 2100 reversing phase every 450 ms, Bell 103 FSK.

Thirteen hops, each a different genre over one renderer — FP tutorial,
OSI descent platformer, walking sim, EFnet twin-stick, 2D buffer overflow,
Morris worm RTS, LBL terminal stealth, a whole BBS with a playable LORD,
the five-boss handshake arena, the copper, a playable blue box, the climb,
and an empty room with an ACK in it.

No engine, no build step, one vendored three.js.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-02 15:34:58 +10:00