fix(ironman): publish the mode, or only the tick can see it #229
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/ironman-modes"
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?
Found in the first live sitting: a Hardcore Iron Man could still send a
trade offer.
World.tradeable_pair/2 reads state.roster[index], and a roster entry is
written once at join and never updated. The mode was set mid-session, so
the gate saw the account as it was at login: unrestricted. The tick's
player.account was correct throughout, which is exactly what made it
invisible.
Two more readers of the same stale copy are fixed by the same push -- the
crown on a private message and the crown on a Friends Chat line. Public
chat was never affected; it is stamped from player.account in the tick.
The mechanism already existed. Requests.account_update/3 was written for
::grant and its own moduledoc already names this failure -- "or the crown
the roster puts on chat messages would be the one the player logged in
with forever". It merged only granted and root?. So: add ironman to that
merge, and cast {:account_update, account} from Ironman.record/3, which is
the single write point both pick/2 and the Hardcore death downgrade go
through. A cast, so it is safe from inside the tick.
Why seven passing gate tests missed it: all of them built an account that
was already restricted and asked the gate about it, which is not the path
a player takes. Worse, the omission cannot be reached by a unit test at
all -- World.request/2 is a cast to a named process, and a cast to an
unregistered name is a silent :ok. The regression test is therefore a
world test, verified to fail 3/3 with publish/1 removed.
Found in the first live sitting: a Hardcore Iron Man could still send a trade offer. World.tradeable_pair/2 reads state.roster[index], and a roster entry is written once at join and never updated. The mode was set mid-session, so the gate saw the account as it was at login: unrestricted. The tick's player.account was correct throughout, which is exactly what made it invisible. Two more readers of the same stale copy are fixed by the same push -- the crown on a private message and the crown on a Friends Chat line. Public chat was never affected; it is stamped from player.account in the tick. The mechanism already existed. Requests.account_update/3 was written for ::grant and its own moduledoc already names this failure -- "or the crown the roster puts on chat messages would be the one the player logged in with forever". It merged only granted and root?. So: add ironman to that merge, and cast {:account_update, account} from Ironman.record/3, which is the single write point both pick/2 and the Hardcore death downgrade go through. A cast, so it is safe from inside the tick. Why seven passing gate tests missed it: all of them built an account that was already restricted and asked the gate about it, which is not the path a player takes. Worse, the omission cannot be reached by a unit test at all -- World.request/2 is a cast to a named process, and a cast to an unregistered name is a silent :ok. The regression test is therefore a world test, verified to fail 3/3 with publish/1 removed.