Skip to content

Say things a player can act on, and test the crash containment - #9

Merged
nicodes merged 1 commit into
mainfrom
player-facing-errors
Aug 3, 2026
Merged

Say things a player can act on, and test the crash containment#9
nicodes merged 1 commit into
mainfrom
player-facing-errors

Conversation

@nicodes

@nicodes nicodes commented Aug 3, 2026

Copy link
Copy Markdown
Member

The polish pass from the readiness audit. Four small things, all the same complaint: the arcade explained itself to a developer.

Stacked on #8 (which is stacked on #7). Merge in order and each retargets cleanly.

Errors a player can act on

The registry client turned a transport failure into Go's error, and the TUI rendered it straight into a notice — so a marketplace that was merely not running looked like a stack trace.

before  registry unreachable: Get "http://127.0.0.1:8080/v1/games/aviorstudio/tetris/resolve?abi=1": dial tcp 127.0.0.1:8080: connect: connection refused
after   the marketplace is not answering — check your connection and try again

The detail is behind TERMCADE_DEBUG for whoever is actually debugging:

$ TERMCADE_DEBUG=1 termcade add aviorstudio/tetris
termcade: the marketplace is not answering — check your connection and try again: Get "http://127.0.0.1:59999/..." dial tcp ...: connection refused

Fixed in the client, so the CLI and the TUI both get it — they were rendering the same string. The registry's own messages now pass through unprefixed, since termcade: registry: ... was a stutter rather than attribution, and the TUI stopped prefixing marketplace unreachable: onto a message that already says so.

Empty state for list

With nothing installed it printed nothing at all and exited 0, which reads as a broken command rather than an empty arcade. The TUI has empty states on every screen; the CLI had none.

$ termcade list
no games installed — run `termcade` and press m for the marketplace

A bare slug says what's wrong with it

Forgetting the author is the likeliest way to get an id wrong, and the old answer was about the filesystem.

before  open asteroid: no such file or directory
after   "asteroid" is missing an author — marketplace ids look like author/slug, e.g. aviorstudio/asteroid

Anything with a slash, a scheme, or a .tcade on the end still means a file or a URL and is left alone.

SafeGame has tests now

It had none, which was the wrong place for the gap — it is the whole of "a broken game can never take the arcade down". Eight tests:

  • every method (Reset, HandleKey, HandleKeyUp, Draw, Update, Score, HUD) contains a panic rather than propagating it
  • a panic in Info, which happens inside Safe itself before the caller holds anything
  • the first crash latches and nothing reaches the game afterwards — a game panicking every frame doesn't burn the arcade's time
  • Close still runs after a crash, which is exactly when a wasm instance needs releasing
  • a panic in Close is contained too, and a real Close error is passed through
  • a healthy game is untouched

Verification

go vet clean, full suite passes. Every message above was checked against a clean install with the registry pointed at a dead port.

🤖 Generated with Claude Code

@nicodes
nicodes force-pushed the marketplace-through-the-api branch from 4714f37 to 14f6813 Compare August 3, 2026 01:40
@nicodes
nicodes changed the base branch from marketplace-through-the-api to main August 3, 2026 01:41
Four small things, all the same complaint: the arcade explained itself
to a developer.

The registry client turned a transport failure into Go's error, which
names a host, a port, a query string and a syscall. None of that is
actionable, and the TUI rendered it straight into a notice — so a
marketplace that was merely not running looked like a stack trace. It
is one message now, with the detail behind TERMCADE_DEBUG for whoever
is actually debugging.

    before: registry unreachable: Get "http://127.0.0.1:8080/v1/games/
            aviorstudio/tetris/resolve?abi=1": dial tcp 127.0.0.1:8080:
            connect: connection refused
    after:  the marketplace is not answering — check your connection
            and try again

The registry writes its own messages for a person to read, so they pass
through unprefixed; "termcade: registry: ..." was a stutter rather than
attribution. Same reason the TUI stopped prefixing "marketplace
unreachable:" onto a message that already says so.

`list` printed nothing at all with nothing installed, which reads as a
broken command rather than an empty arcade. The TUI has empty states on
every screen; the CLI had none.

A bare slug is the likeliest way to get an id wrong, and "open
asteroid: no such file or directory" answers a question about the
filesystem that nobody asked.

SafeGame had no tests, which was the wrong place for the gap: it is the
whole of "a broken game can never take the arcade down". It now has
eight, including that every method contains a panic, that the first
crash latches and nothing reaches the game afterwards, and that Close
still runs after a crash — which is exactly when a wasm instance needs
releasing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@nicodes
nicodes force-pushed the player-facing-errors branch from 7f81e26 to dc150ff Compare August 3, 2026 01:44
@nicodes
nicodes merged commit ffdeadd into main Aug 3, 2026
1 check passed
@nicodes
nicodes deleted the player-facing-errors branch August 3, 2026 01:46
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