v0.8.0.11 — sixteen fixes from the second multiplayer playtest
Arrivals name whose Office they reached, and no longer tell every seat they can work the train. The turn chart follows the animation queue, so being five behind looks five behind across the whole screen rather than half of it. Pause sits beside Skip and preserves the dwell a held step still owed. A one-render look at another player's Office Area. The district summary counts the board being shown. LIMITS is printed beneath its card instead of through its border. The Mainline region divider is visible. Only Hilly mentions FAST/SLOW, because it is the only card that reads it. A passenger Modifier on a Whistle Post reports itself dormant rather than claiming the facility "only receives". An automatic phase says what the Division is doing instead of answering by negation. The version appears once in the header rather than twice on every .s9pk. Save files carry the join code, the Stage and the date. The New Train phase, reviewed before being changed: the make-up panel now says what the train STILL needs rather than only what its card calls for, explains that a player adds one car before the round passes on, marks the train being loaded on the Division map, and gives an addable car in the yard the same amber every other clickable thing on the page wears. Reasoning, measurements and the reports behind each are in CHANGELOG.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017nnuCv8UodHucFfx3LWEoX
This commit is contained in:
co-authored by
Claude Opus 5
parent
4adf149ba5
commit
9a9e50b3c6
@@ -109,6 +109,61 @@ describe('the step queue', () => {
|
||||
assert.equal(q2.behind(), 4, 'and must be replaced once its dwell is up');
|
||||
});
|
||||
|
||||
/**
|
||||
* PAUSE — Jesse, playtest 2026-09-16, asking for one beside Skip.
|
||||
*
|
||||
* The property that matters is not "it stops", which any flag gives you. It is that a hold COSTS
|
||||
* THE STEP NOTHING: a move paused half-way through its dwell has to resume with half a dwell left,
|
||||
* or pausing to look at something would punish you by throwing the rest of it away the moment you
|
||||
* let go. That is the whole assertion below, measured against `DWELL.switching` rather than a
|
||||
* hand-picked number so it follows the tuning table.
|
||||
*/
|
||||
it('pause holds the board where it is, and resume gives the step back the dwell it had left', () => {
|
||||
const { steps } = realSteps(1917398, 400);
|
||||
const switching = steps.filter((s) => s.cause.startsWith('switch.') && s.cause !== 'switch.end');
|
||||
assert.ok(switching.length >= 6, `only ${switching.length} switching steps found`);
|
||||
|
||||
const q = createStepQueue();
|
||||
q.reset(baseline(1917398));
|
||||
q.push(switching.slice(0, 6));
|
||||
q.advance(0);
|
||||
assert.equal(q.behind(), 5, 'the first is shown at once; five are still to watch');
|
||||
|
||||
// Held half-way through the first move's dwell, and left held for ten times that long.
|
||||
const half = DWELL.switching / 2;
|
||||
assert.equal(q.pause(half), true);
|
||||
assert.equal(q.paused(), true);
|
||||
const held = q.showing()?.seq;
|
||||
q.advance(half + 10_000);
|
||||
assert.equal(q.behind(), 5, 'a held queue consumed a step');
|
||||
assert.equal(q.showing()?.seq, held, 'the board moved while it was supposed to be held');
|
||||
assert.equal(q.busy(), true, 'a held queue must still read busy, or the render loop stops');
|
||||
|
||||
// Resumed, the move still owes exactly the half-dwell it had left — no more, and no less.
|
||||
const at = half + 10_000;
|
||||
assert.equal(q.resume(at), true);
|
||||
assert.equal(q.paused(), false);
|
||||
q.advance(at + half - 1);
|
||||
assert.equal(q.behind(), 5, 'the step was robbed of time it was owed while held');
|
||||
q.advance(at + half);
|
||||
assert.equal(q.behind(), 4, 'and it never gave way once the rest of its dwell was up');
|
||||
});
|
||||
|
||||
it('refuses to hold an idle queue, and Skip lifts a hold rather than leaving it stuck', () => {
|
||||
const q = createStepQueue();
|
||||
q.reset(baseline(1917398));
|
||||
assert.equal(q.pause(0), false, 'an idle queue has no playback to hold');
|
||||
assert.equal(q.paused(), false);
|
||||
|
||||
const { steps } = realSteps(1917398, 400);
|
||||
q.push(steps);
|
||||
q.advance(0);
|
||||
assert.equal(q.pause(10), true);
|
||||
assert.equal(q.skip(), true, 'Skip must still work while held');
|
||||
assert.equal(q.paused(), false, 'Skip left the queue held, with a Resume that does nothing');
|
||||
assert.equal(q.busy(), false);
|
||||
});
|
||||
|
||||
it('counts only what will be watched, so the countdown is steady', () => {
|
||||
// The counter's whole purpose: a backlog of mostly-bookkeeping must not read as a huge number
|
||||
// that collapses the instant it starts.
|
||||
|
||||
Reference in New Issue
Block a user