chore(tools): dress a seeded world so it can be screenshotted

BridgeSeeder builds a world at realistic scale, which is what the bridge needed;
it never needed the world to look like anything. So a vendor is `seed vendor`
trading as `Seed Shop 810`, a character is `Seed004A` and a house sign reads
`Seed House 12` — and every one of those strings travels the whole bridge and
lands on the marketplace, the guild roster and the housing pages of the website.
That is fine for a protocol test and wrong for the marketing site's screenshots
(runicgateway.com PLAN.md §13 phase 9, D42/D46).

BridgeDemoDress renames them in place and seeds nothing: prices, listing counts,
decay stages, fame and skills stay exactly as the seeder left them, so the data
keeps its provenance and only the strings a human reads change. Names come from
fixed tables hashed off each object's serial, so a re-run reproduces the same
world and screenshots can be retaken later and still match.

It also does two things the screenshots needed and nothing else provides:

- stages a few condemned houses back into the last decay levels, because decay
  is a live process and "Houses in danger" is empty by the time anyone looks
- sets a known password on seed_000, because logging a character in is the only
  way to make the online roster non-empty and the seeder assigns a random GUID.
  The password is read from Bridge.cfg, never compiled in.

Test scaffolding, in tools/, never deployed — deploy.ps1 copies overlay/ only.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-24 19:22:46 -05:00
parent 0d9ac7fda8
commit 158c0596d8
2 changed files with 438 additions and 0 deletions

View File

@@ -13,6 +13,7 @@ These two scripts produced the measured budget in [PLAN.md](https://gitea.whitlo
| `BridgeLinkProbe.cs` | `Scripts/Custom/BridgeLinkProbe.cs` | Triggers `[link` for seed_001 without a client, then saves so the `WebsiteUserId` tag reaches `accounts.xml`. Flag: `LinkProbeOnStart`. Pair with a sidecar that reads the code and sends `link.confirm`. |
| `BridgeCrierProbe.cs` | `Scripts/Custom/BridgeCrierProbe.cs` | Logs the global town-crier entry list every 3s so `towncrier.add` / `remove` can be seen landing in game state. Flag: `CrierProbeOnStart`. |
| `BridgeVendorSaleProbe.cs` | `Scripts/Custom/BridgeVendorSaleProbe.cs` | Fires `PlayerVendorSale` (Phase 7) with real seeded-vendor data so `vendor.sale` can be verified without a live buy. Requires the Phase 7 patches applied. Flag: `VendorSaleProbeOnStart`. |
| `BridgeDemoDress.cs` | `Scripts/Custom/BridgeDemoDress.cs` | Renames a seeded world so it is presentable in a screenshot: shop signs, vendor and character names, house signs. Also stages a few condemned houses back into IDOC, and sets a known password on `seed_000` so a character can be logged in. Flags: `DemoDressOnStart`, `DemoDressPassword`. In game: `[demodress`. |
## Deploy overwrites Bridge.cfg
@@ -34,6 +35,41 @@ Because `Config.Get` returns `false` for a missing key, a server whose `Bridge.c
In-game, `[seedworld` and `[unseedworld` (Administrator) do the same work on a live shard.
## Dressing a seeded world for screenshots
`BridgeSeeder` builds a world at realistic **scale**, which is all the bridge ever needed. It does not
build one that looks like anything: a vendor is `seed vendor` trading as `Seed Shop 810`, a character
is `Seed004A`, a house sign says `Seed House 12`. Those strings travel the whole bridge and land on
the marketplace, the guild roster and the housing pages of the website — fine for a protocol test,
wrong for a screenshot.
`BridgeDemoDress.cs` renames them in place. It seeds nothing: prices, listing counts, decay stages,
fame and skills stay exactly as the seeder left them and as the shard has moved them since, so the
data keeps its provenance and only the strings a human reads change. Names are drawn from fixed
tables by a hash of each object's serial, so a re-run reproduces the same world, and shop and house
names are re-dressed when they are names the pass itself produced — so a change to the tables can be
applied to a world that has already been through here.
```ini
DemoDressOnStart=True
DemoDressPassword=<a password you choose>
```
Boot once, then set `DemoDressOnStart=False`. The password is written to `seed_000` so a real client
can log a character in — the only way to make the website's online roster non-empty — and it is read
from the config rather than compiled in, so it never lands in source control.
**It dresses seeded objects only, which means your own characters keep their names.** That is the
right behaviour for a test shard and a thing to remember before pointing a camera at one: a dev
world usually also holds the accounts, characters, guilds and houses of whoever built it, and those
are real identifiers on a page that may end up public.
**The sidecar's board is cached, so the website lags a rename.** A shop name reaches the site on the
next market sweep, and a sweep advances `MarketSweepBatch` vendors per tick — 27 vendors at the
defaults is two ticks. Allow a couple of minutes before concluding that a rename failed. This cost a
debugging detour once: the shard had the new names all along and the sidecar was still serving the
previous ones.
## Back up `Saves/` first
`[seedworld` and `SeedOnStart` **write to the live world**. Copy `Saves/` somewhere outside the repo before running either. `Backups/Automatic` is rotated by `AutoSave.cs` and `Backups/Temp` is deleted outright, so neither is a safe destination.