1 Commits

Author SHA1 Message Date
a6fc0431d7 feat(screens): retake the two frames a signed-in character changes
The org lead signed a character into the shard by hand — the step automation
could not reach — so shard-status and app-shard were retaken. The shard page
now reads 1 player online in Britain, and the app's card agrees.

Two things worth noticing in the retake. Presence reaches the public page as
counts and regions rather than names, which is the visibility framework working
unprompted. And the guild board's online column did not move: it refreshes only
when a guild's signature changes, which is the stale-roster defect wearing a
different hat.

A sixth defect, visible in the shipped phone capture: the app interpolates a
count into a fixed plural and says "1 players online". Raised, not fixed —
it wants a plurals resource in the app.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-25 10:08:41 -05:00
5 changed files with 29 additions and 17 deletions

32
PLAN.md
View File

@@ -1076,7 +1076,7 @@ hashed off each object's serial, so a re-run reproduces the same world and a scr
be retaken later and still match. be retaken later and still match.
**What the rig found.** A screenshot rig is an integration test with a human in the loop, and **What the rig found.** A screenshot rig is an integration test with a human in the loop, and
this one turned up five things nothing else had: this one turned up six things nothing else had:
- **A fresh `module-uo` install pinned wire protocol 3 while the sidecar speaks 4**, so a new - **A fresh `module-uo` install pinned wire protocol 3 while the sidecar speaks 4**, so a new
deployment 409s on every shard read until an admin edits the number by hand. The protocol-4 deployment 409s on every shard read until an admin edits the number by hand. The protocol-4
@@ -1096,6 +1096,9 @@ this one turned up five things nothing else had:
the site connects is therefore invisible — the page said none while the shard had two. the site connects is therefore invisible — the page said none while the shard had two.
- **The Android news list prints raw ISO timestamps.** Found while choosing the phone - **The Android news list prints raw ISO timestamps.** Found while choosing the phone
captures; the news screen was dropped from that set rather than shipping a picture of it. captures; the news screen was dropped from that set rather than shipping a picture of it.
- **The app says "1 players online".** `shard_online_count` and `ShardEventText.kt` both
interpolate a count into a fixed plural. Found in the retake after a character was signed in,
and it is in the shipped phone capture — a `plurals` resource is the fix, in the app.
The first is fixed. The rest are raised as product observations, with the rig working around The first is fixed. The rest are raised as product observations, with the rig working around
them: the guilds are built *after* the rename, and the IDOC staging is two passes with a wait them: the guilds are built *after* the rename, and the IDOC staging is two passes with a wait
@@ -1114,15 +1117,24 @@ The shard screen is the one worth having. It shows the two houses entering IDOC
activity feed — the same event that reached `/uo/houses` in the browser, on the same rig, in activity feed — the same event that reached `/uo/houses` in the browser, on the same rig, in
the same minute. the same minute.
**One thing that did not happen: a character logged in.** The org lead asked for it, so the **The character that had to be logged in by hand.** The org lead asked for a player in the
scaffolding sets a known password on a seeded account and a client was driven as far as its world, and the scaffolding does its half — it sets a known password on a seeded account,
login screen. ClassicUO stores its password crypted and mangles a plaintext one from because `BridgeSeeder` gives every account a random GUID nobody kept. Driving the client is
`settings.json`, so auto-login fails; synthetic clicks reach the client but synthetic text where automation stopped. ClassicUO stores its password crypted, so a plaintext one in
does not; and the remaining route — taking the foreground and typing — was tried once, missed `settings.json` decrypts to garbage and auto-login fails; posted mouse clicks reach the client
the client, and typed into the browser window the person at this machine was using. It was but posted text does not; and the remaining route — taking the foreground and typing — was
not tried again. **Players online therefore reads 0, and the page is honest about a quiet tried once, failed to take focus, and typed into the browser window the person at this machine
realm.** The client is left at its login screen: one manual sign-in and was using. It was not tried again.
`npm run screens:capture shard-status app-shard` retakes the two frames that would change.
The org lead signed in instead, and the two frames that depended on it were retaken: the shard
page now reads **1 player online, in Britain**, and the app's shard card agrees. Both came from
the same `npm run screens:capture shard-status app-shard`, which is the whole point of D45 —
the thing that changed was the world, not the recipe.
Two things that pass is worth noticing here. Presence reaches the public page as **counts and
regions, not names**, which is the visibility framework doing its job unprompted. And the
**guild board's "online" column did not move**: it is refreshed only when a guild's signature
changes, which is the same defect as the stale roster above wearing a different hat.
**A layout decision worth recording.** The `/features/` figures are one-up at the column's **A layout decision worth recording.** The `/features/` figures are one-up at the column's
full width, not a two-column grid. Two-up was built first and is the obvious layout for a set full width, not a two-column grid. Two-up was built first and is the obvious layout for a set

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -22,9 +22,9 @@ import Screenshot from '../Screenshot.astro';
<p class="eyebrow">What it looks like</p> <p class="eyebrow">What it looks like</p>
<h2>The other end of that diagram</h2> <h2>The other end of that diagram</h2>
<p class="prose looks__lede"> <p class="prose looks__lede">
A demo deployment with a real shard behind it. The gold supply, the uptime and the online A demo deployment with a real shard behind it. The gold supply, the state of the link and
count are read from the game server over the bridge — none of it is typed in, and the page the player online in Britain are all read from the game server over the bridge. None of it
is honest about a quiet realm. is typed in, and none of it is a mock-up.
</p> </p>
<Screenshot id="shard-status" /> <Screenshot id="shard-status" />

View File

@@ -71,9 +71,9 @@ export const screens = [
id: 'shard-status', id: 'shard-status',
route: '/uo/shard', route: '/uo/shard',
admin: false, admin: false,
alt: 'The shard page of a Runic Gateway site, showing the shard online, its gold supply, the state of the shard link and how many players are online.', alt: 'The shard page of a Runic Gateway site, showing the shard online, its gold supply, the state of the shard link, and one player online in Britain.',
caption: caption:
'The shard console. Every number on it came over the bridge from a running game server — nothing here is stored by hand.', 'The shard console. Every number on it came over the bridge from a running game server — including the player who was standing in Britain when this was taken.',
family: 'web', family: 'web',
}, },
{ {
@@ -187,9 +187,9 @@ export const screens = [
id: 'app-shard', id: 'app-shard',
route: '/shard', route: '/shard',
admin: false, admin: false,
alt: "The app's shard screen, showing the shard online with its gold supply, links to champion spawns, guilds, governors and falling houses, and a live activity feed.", alt: "The app's shard screen, showing the shard online with one player and its gold supply, links to champion spawns, guilds, governors and falling houses, and a live activity feed.",
caption: caption:
'The same bridge feeds the phone. The activity list is live — those two houses entered their final decay stage while this was open.', 'The same bridge feeds the phone: the same player online, and an activity list that is live — those houses entered their final decay stage while it was open.',
family: 'phone', family: 'phone',
}, },
{ {