BridgeSeeder and BridgeProbe are not part of the bridge, but living under overlay/Scripts/Custom/ meant deploy.ps1 would copy them onto any server we deployed to. Move them to tools/scaffolding/, which nothing syncs. overlay/Config/Bridge.cfg now carries the bridge's own settings (host, port, queue cap, sweep intervals) rather than the scaffolding flags. Config.Get returns false for a missing key, so a deployed server never runs the seeder or probe even if their .cs files are present. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
64 lines
4.0 KiB
Markdown
64 lines
4.0 KiB
Markdown
# Test scaffolding
|
||
|
||
**Not part of the bridge. Never deployed.** `deploy.ps1` only copies `overlay/`, so nothing here reaches a server unless you put it there by hand.
|
||
|
||
These two scripts produced the measured budget in `docs/PLAN.md` §1. They are kept because those numbers should be reproducible, and because re-running the probe is the only honest way to check whether a change to the plugin's read path got more expensive.
|
||
|
||
| File | Server path when testing | What |
|
||
|------|--------------------------|------|
|
||
| `BridgeSeeder.cs` | `Scripts/Custom/BridgeSeeder.cs` | Populates a synthetic world: 50 accounts, 150 characters, 30 houses, 30 player vendors with 40 listings each. |
|
||
| `BridgeProbe.cs` | `Scripts/Custom/BridgeProbe.cs` | Times every read the plugin performs, on the Core thread. Read-only. |
|
||
|
||
## Using them
|
||
|
||
Copy both into `Scripts/Custom/`, then append the flags to `Config/Bridge.cfg`:
|
||
|
||
```ini
|
||
SeedOnStart=True
|
||
CensusOnStart=False
|
||
ProbeOnStart=False
|
||
```
|
||
|
||
Boot once to seed and save, then set `SeedOnStart=False`. `CensusOnStart` reports what the loaded world actually contains; `ProbeOnStart` prints timings two seconds after `ServerStarted`.
|
||
|
||
Because `Config.Get` returns `false` for a missing key, a server whose `Bridge.cfg` lacks these keys never runs the scaffolding — even if the `.cs` files are sitting in `Scripts/Custom/`. That is the safety net, not an excuse to ship them.
|
||
|
||
In-game, `[seedworld` and `[unseedworld` (Administrator) do the same work on a live shard.
|
||
|
||
## 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.
|
||
|
||
`[unseedworld` deletes every `seed_*` account, which takes their characters and houses with it — but not necessarily their `PlayerVendor` mobiles. Restoring a backup is the reliable reset.
|
||
|
||
## What the seeder had to work around
|
||
|
||
Worth knowing before you trust its output:
|
||
|
||
- **Plate needs strength.** `BaseArmor.CanEquip` rejects when `from.Str < strReq` (`PlateChest` needs 95). A rejected `EquipItem` leaves the item parentless, and the `Cleanup` pass later deletes it en masse. The seeder gives characters `Str` 100–125 and deletes any item whose equip is refused, rather than orphaning it.
|
||
- **`VendorItem.Price` is get-only** and `PlayerVendor.SetVendorItem` is private. Dropping an item into a vendor's pack fires `OnSubItemAdded`, which registers the item at the default price of 999. The seeder reaches `SetVendorItem` by reflection to set a real price. Acceptable in throwaway scaffolding; do not do this in the plugin.
|
||
- **Houses only decay when condemned.** `BaseHouse.CanDecay` is true only for `DecayType.Condemned` or `ManualRefresh`. An active owner's newest house is `AutoRefresh` and never decays. The seeder backdates 18 accounts past `Account.InactiveDuration` (180 days) to condemn them, then forces stages with `SetDynamicDecay` — not by backdating `LastRefreshed`, because `DynamicDecay.Enabled` is true on this expansion and `GetOldDecayLevel` is unreachable.
|
||
|
||
## Reference output
|
||
|
||
Census after a fresh load of the seeded world:
|
||
|
||
```
|
||
[BridgeSeeder] houses=35
|
||
[BridgeSeeder] decay Ageless 13, Slightly 3, Somewhat 7, Fairly 3, Greatly 3, IDOC 6
|
||
[BridgeSeeder] seeded chars=150 avgEquipped=8.00 naked=0
|
||
[BridgeSeeder] playervendors=30
|
||
```
|
||
|
||
Probe, best-of-20 on the Core thread:
|
||
|
||
```
|
||
[BridgeProbe] char.profile 0.069 ms/char 2386 bytes json
|
||
[BridgeProbe] vitals sweep 0.223 ms for 150 chars (0.0015 ms/char)
|
||
[BridgeProbe] decay sweep 0.007 ms for 35 houses (0.0002 ms/house)
|
||
[BridgeProbe] economy sweep 0.001 ms for 51 accounts (supply 110,478,209 gold)
|
||
[BridgeProbe] vendor snap 0.343 ms for 30 vendors (1200 listings)
|
||
```
|
||
|
||
Seeded characters carry 8 items with ~6 mods each and ~12 trained skills. A real endgame character has more of both, so profile cost and payload are a **floor** — budget 2–4× for a fully-kitted character.
|