fix/per-tick-run-and-rebuild-effects #72

Merged
sickday merged 2 commits from fix/per-tick-run-and-rebuild-effects into main 2026-07-31 01:43:52 +00:00
Owner
No description provided.
A viewer whose scene rebuilt on a given tick was sent no zone effects for
that tick at all. The reasoning behind the skip was right for replay and
wrong for the present: an effect is a moment, so there is nothing to
re-send in one that has already happened, but the effects of the tick
being encoded have not reached the client yet. Dropping them loses a
projectile or a hit graphic for exactly the player who crossed a zone
boundary while it was in flight — which reads as a netcode fault rather
than as a missing branch.

The distinction needed no new state. World.ZoneEffects already keys
{tick, region}, and zone_updates/3 only ever reads the bucket for the
tick it was asked to encode, so the replay the skip was guarding against
cannot arise: sending them is simply correct.

What the rebuild branch does have to get right is the base. Everything
behind a rebuild packet is addressed against the scene the client is
about to build, so the zone reads now take the scene zone rather than
helping themselves to player.scene_zone, which on a rebuilding tick is
still the old one. Both region set and set_zone prefix come from the new
scene; the assertions check the old base is absent, since the two encode
to identical bytes but for that prefix.

Costs nothing today — only ::proj and the bench harness emit effects —
and closes ahead of combat, which makes it per-attack-per-tick.

Closes #59.
A walk click resolved run-or-walk once and wrote the answer into the
player, so every tick of the route replayed a verdict taken before the
route began. Clicking at half a percent ran the whole way; clicking while
exhausted walked the whole way however far the bar recovered; and
Player.interact/3 never touched the field at all, so every approach to an
object, NPC, player, pile or item-use ran or walked on whatever the last
walk click happened to leave behind. The ctrl flag those clicks decode
was read and thrown away. None of it shows on the wire — the bar and the
orb are both right, and only the speed is wrong.

So nothing holds a verdict now. A player holds the two things that were
asked for: the orb, which is varp 173 and was always the real toggle, and
a ctrl-click, which lasts for the route it bought and is dropped on the
tick that empties the path. Contract.Run.running?/3 puts both to the bar
as it stands, Player.running?/1 asks it, and the two movement readers —
Player.tick/1 and the advance pass's stride — ask per tick.

The field is renamed run? -> ctrl_run? rather than kept, because a field
named for the answer that now holds one of the questions is a trap: every
reader had to be revisited, and the rename is what forced that rather
than leaving it to review.

Contract.Run's two floors are unchanged in value and sharpened in
wording. The 1% floor gates *enabling* run mode, which is the orb and
only the orb — the client's own script never checks energy, so refusing
the toggle and writing the varp back is still the only thing that says
no. Every tick of an actual route asks sustains? instead, which is what
lets a player keep running on the half percent they lit the orb at and
what makes the step that empties the bar the last one taken. A ctrl-click
enables nothing, so it asks the continuing question too.

Player.interact/4 takes the click's ctrl flag as a required argument, so
a new interaction kind cannot inherit somebody else's run by omission;
the retarget pass passes the route's own back in, because it is
re-routing a walk the player already asked for. Exhaustion now withdraws
both requests: a surviving ctrl-click would run again the moment a unit
came back.

Dispatch loses its private copy of varp 173 and the helper that read it.

Test fixtures that build object clicks by hand now carry the ctrl flag
the decoder always produced.

Half of #63: the run latch. The stamina seam it was filed with —
Energy.stamina/1 and Energy.gain/2 with no production caller — is
untouched and needs a stamina potion, so the issue stays open on that.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Revenant/Server!72
No description provided.