feat(bridge): lease deadlines and the participation ledger (Phase 11b)
Protocol 6 amended in place. Two mechanisms behind one new default-off gate,
`Bridge.EventsEnabled` -- deliberately not `AdminWriteEnabled`, because enabling
the admin plane is consenting to staff moderation from a screen a human is
looking at, and this is consenting to the world being changed and watched on a
schedule, unattended.
BridgeLeases: a live config value held for a bounded time, with the deadline
honoured on the shard whether or not the website is heard from again, and a
compare-and-set restore that reports `drifted` rather than overwriting a GM's
deliberate change. Memory-only -- nothing calls Config.Save() -- so a restart is
a free restore.
BridgeParticipation: presence in a declared area plus kill credit inside it,
keyed by character serial, persisted in the world save. The Bridge's first
persisted state, because a run spans hours and an in-memory tally would regress
every attendee's score after one restart. Its snapshot is also the first handler
that DEFERS, which makes `bridge.busy` reachable for the first time.
And it immediately found a defect in 11a: BridgeIdempotency.Busy built its frame
with Begin("bridge.busy") and then appended a diagnostic `.Str("kind", ...)`, so
the object carried two `kind` fields and every JSON parser takes the last. The
sidecar answered 200 instead of 425. Renamed `busyKind`.
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -202,6 +202,8 @@ namespace Server.Custom.Bridge
|
||||
BridgeHousing.Rearm();
|
||||
BridgePoints.Rearm();
|
||||
BridgeMarket.Rearm();
|
||||
BridgeParticipation.Rearm();
|
||||
BridgeLeases.Rearm();
|
||||
// Not a sweep, so it has nothing to re-arm — but an operator who just edited a
|
||||
// .cfg wants the change on the site now, not after a shard restart.
|
||||
BridgeRuleset.Emit();
|
||||
@@ -223,6 +225,7 @@ namespace Server.Custom.Bridge
|
||||
BridgeHousing.SweepOnce();
|
||||
BridgePoints.SweepOnce();
|
||||
BridgeMarket.SweepOnce();
|
||||
BridgeParticipation.SweepOnce();
|
||||
e.Mobile.SendMessage("Bridge: ran one sweep of each stream.");
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeSweeps.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeChamps.Status());
|
||||
@@ -232,6 +235,7 @@ namespace Server.Custom.Bridge
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeHousing.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgePoints.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeMarket.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeParticipation.Status());
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -251,6 +255,8 @@ namespace Server.Custom.Bridge
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgePages.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeRuleset.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeIdempotency.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeLeases.Status());
|
||||
e.Mobile.SendMessage("Bridge: {0}", BridgeParticipation.Status());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user