fix(events): the atlas import, and a teardown that was a no-op (Phase 16a) #33
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/events-p16a-walk"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two defects the Phase 16 acceptance walk found in code already merged to
edge. Both suites were green on either side of each of them.1. The spawn atlas cannot import on a stock ServUO tree — blocking
spawnAtlasSource.jsdedupes decoration types with a case-sensitiveMap.shard_decor_types.typeis a PRIMARY KEY under MariaDB's default..._ai_cicollation, which folds case. Stock ServUO 57.4's ownData/Decoration/names four types under two spellings each —CheckerBoard/Checkerboard,ChessBoard/Chessboard,MetalChest/Metalchest,SpinningWheelEastAddon/SpinningwheelEastAddon— and in every pair exactly one is a real class; the other is a mis-cased line the shard's own loader resolves anyway.The second row raises
1062 Duplicate entryand takes the whole import transaction down.The blast radius is not decoration. With no atlas, every option source answers
{ok: true, options: []}and no Phase 12 world verb can be authored at all — the authoring form's dropdowns are simply empty, with nothing to say why.The shard end already knew:
BridgeWorld.csresolves a decor type withFindTypeByName(name, ignoreCase: true)and its comment says "the atlas and the decoration files disagree about casing". One end of the feature knew and the other did not. Folding here is the two ends agreeing rather than a new rule.2. Teardown of every world verb was a no-op that reported success — critical
revertOwned()forwarded core'sidempotencyKeyas the despawn's own key. That key is the step's — the very keyplaceOwned()spawned under.BridgeIdempotency.Interceptkeys on_byKey.TryGetValue(key, …), the key alone and not (key, command), so the despawn was recognised as a repeat and answered with the spawn's stored reply.OnDespawnnever ran. Core sawokwith norefusedand marked every rowreverted.Proven end to end on the rig, not inferred:
world | reverted | 21world.owned→ 21 objects,pruned: 0(all alive)removed= all 21,owned: 0It is the shared
revert:for all five Phase 12a world verbs, so an invasion's creatures, its boss, its oracle, its gate and its decoration all stayed in the world for ever while the run console reported a clean teardown. The town-crier and news reverts are unaffected — they pass no key.MODULE_API.mdsays what that key is for, and it is not this: "it will sometimes be called with the key and an EMPTY list, meaning a command went out under this key and core never learned what it did". It identifies a lost dispatch to ask about; it does not address the undo.No key is needed on a despawn. A repeat is already safe by the handler's own three-answer design — the second pass answers
gone, which §L and the module both treat as success. Dropping it also makes the documented empty-resourcescase work correctly, since no serials means "everything this run owns". The parameter is removed fromdespawnWorld's signature rather than left optional, so it cannot be handed one again.Verification
Against a real rig — ServUO 57.4 (208k items, 42k mobiles) →
cargo --releasesidecar on protocol 7 → core with this module installed from a release-shaped bundle:Both new tests were confirmed to FAIL without their fix. The despawn test asserts the absence of the key rather than pinning the body's shape — every other stub in that file ignores the body, which is exactly why the suite stayed green while teardown did nothing.
Pairs with
website#,servuo-plugins#anddocs#(Phase 16a).🤖 Generated with Claude Code
https://claude.ai/code/session_016wDDVXWMDz82WqE1i969r4