Repository navigation
Movers step 3: fading tracks and presence clues - #185
Conversation
Step 3 of the movers plan. A mover with "Tracks" on grows a trail `tracks:<tokenId>` by one timestamped cell per hex walked; a skill gate's DC climbs by `tracksDcPerDay` per day of age and cells older than `tracksExpireDays` are pruned (trail finds re-indexed). Players' trail signs carry the time the sign was made, shown in the Journal as "freshest 2 days ago". A mover may attach a content item (`contentId`) that travels with it, so its clues — distance gates, direction and distance indicators — become the mover's presence through the ordinary knowledge engine, which now re-runs (with trail evaluation) after every traveller tick so a standing party senses what approaches. Undo of a party move or a time advance restores trails, pruned finds, presence content and the discoveries the tick produced. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c3ed2980fb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| runtime.deleteTrail(mapId, trail.id); | ||
| continue; | ||
| } | ||
| runtime.upsertTrail({ ...trail, cells: trail.cells.slice(drop) }); |
There was a problem hiding this comment.
Delete trails when pruning leaves fewer than two cells
When expiration removes all but one cell, this stores a one-cell trail even though TrailSchema requires cells.min(2). The next DM snapshot therefore fails ServerMessageSchema validation in the client and is discarded, freezing visible state updates until a later tick removes the final cell. Delete the trail whenever fewer than two cells remain.
Useful? React with 👍 / 👎.
| for (const p of tick.prunes) { | ||
| runtime.upsertTrail(p.trail); |
There was a problem hiding this comment.
Restore prunes before per-move track snapshots
When one tick both lays new tracks and prunes expired cells on that same trail, the move loop first restores trailBefore, but this later loop overwrites it with p.trail, which was captured after the new cells were appended. Undo then moves the traveller back while leaving the just-laid tracks in place; a newly created-and-pruned trail is similarly resurrected. Restore prune state before the move snapshots so the pre-tick trail wins.
Useful? React with 👍 / 👎.
| const cell = trail.cells[i]!; | ||
| const distance = hexDistance(pos, cell); | ||
| if (!gateOpensPassively(trail.gate, character, distance).opens) continue; | ||
| if (!gateOpensPassively(agedGate(trail, cell, now), character, distance).opens) continue; |
There was a problem hiding this comment.
Apply the aged gate to active trail searches
Aged DCs are only passed through the passive evaluation path here. Hex searches in handleSearch still compare the roll against trail.gate.dc, so a character can find an old skill-gated track using its fresh base DC whenever the gate is searched actively (or a passive gate is explicitly searched), bypassing the new fading rule. The search path should compare against agedGate(trail, cell, campaign.time.minutes) as well.
Useful? React with 👍 / 👎.
Step 3 of the movers plan.
tracks:<tokenId>trail, one timestamped cell per hex (Trail.cells[].at,fade,moverId). Skill-gate DC climbstracksDcPerDayper day of age (agedGate); cells pasttracksExpireDaysare pruned each tick with trail finds re-indexed (pruneTracks). Journal shows how fresh a found trail is.token.contentIdattaches a content item that moves with the mover (anchor + area); its clues work through the existing knowledge engine.runTravellersre-runs knowledge and trail evaluation for every map a mover moved on.TravellerTick {moves, prunes}restores token, trail, pruned finds and presence content;time.advanceundo now also revokes discoveries/trail finds the tick produced.🤖 Generated with Claude Code