# 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. | | `BridgeEventProbe.cs` | `Scripts/Custom/BridgeEventProbe.cs` | Fires gold/fame/karma/save events through their real code paths so the emit path can be verified without a game client. **Mutates the world and saves.** Flag: `EventProbeOnStart`. | | `BridgeSweepProbe.cs` | `Scripts/Custom/BridgeSweepProbe.cs` | Bumps one seeded house's decay stage after baseline so the decay sweep's transition detection can be observed without waiting a real IDOC stage. Flag: `SweepProbeOnStart`. Pair with short `*SweepSeconds` overrides. | ## Deploy overwrites Bridge.cfg `deploy.ps1` copies `overlay/Config/Bridge.cfg`, which deliberately omits the scaffolding flags. So **every deploy strips `SeedOnStart` / `EventProbeOnStart` / etc.** Re-append the flag you need after deploying, or the probe silently does nothing on the next boot. (This bit once during Phase 2 testing.) ## 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.