rigging: the fabric bet is reachable — F cycles cloth/membrane in prep
FABRIC and setFabric() shipped in SPRINT6 and the sim honoured porosity all along, but no key, click or HUD line ever reached them — every rig ever played was DEFAULT_FABRIC. F toggles the two entries, the panel shows the fabric, the splash teaches it, the blurb announces the switch. Session-level assert pins the cycle, the $0 price, and the refusal of unknown ids. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b7a069069d
commit
b74dfd80db
@ -516,6 +516,7 @@ export function createHud(d) {
|
|||||||
['click', 'pick an anchor · again to unpick'],
|
['click', 'pick an anchor · again to unpick'],
|
||||||
['[ ]', 'tension the rig — tighter holds shape, and breaks harder'],
|
['[ ]', 'tension the rig — tighter holds shape, and breaks harder'],
|
||||||
['S', 'buy a spare shackle'],
|
['S', 'buy a spare shackle'],
|
||||||
|
['F', 'choose the fabric — cloth breathes, membrane stops the rain'],
|
||||||
['E', 'repair a blown corner (ladder if it is up high)'],
|
['E', 'repair a blown corner (ladder if it is up high)'],
|
||||||
['C', 'brace against the wind'],
|
['C', 'brace against the wind'],
|
||||||
['Enter', 'commit the rig and start the night'],
|
['Enter', 'commit the rig and start the night'],
|
||||||
|
|||||||
@ -514,6 +514,15 @@ export async function createRiggingUI({
|
|||||||
if (ev.key === '[') session.setTension(session.tension - 0.05);
|
if (ev.key === '[') session.setTension(session.tension - 0.05);
|
||||||
else if (ev.key === ']') session.setTension(session.tension + 0.05);
|
else if (ev.key === ']') session.setTension(session.tension + 0.05);
|
||||||
else if (ev.key.toLowerCase() === 's') say(session.setSpares(session.spares ? 0 : 1));
|
else if (ev.key.toLowerCase() === 's') say(session.setSpares(session.spares ? 0 : 1));
|
||||||
|
else if (ev.key.toLowerCase() === 'f') {
|
||||||
|
// The forecast bet, finally reachable. FABRIC and setFabric() shipped in
|
||||||
|
// SPRINT6 and the sim honoured porosity all along — but no key, click or
|
||||||
|
// HUD line ever reached them, so every rig ever played was DEFAULT_FABRIC.
|
||||||
|
// Two entries, so F is a toggle; announce the blurb because the panel
|
||||||
|
// line alone doesn't say what the bet IS.
|
||||||
|
const next = FABRIC[(FABRIC.indexOf(session.fabric) + 1) % FABRIC.length];
|
||||||
|
if (say(session.setFabric(next.id)).ok) onMessage(`${next.name} — ${next.blurb}`);
|
||||||
|
}
|
||||||
else return;
|
else return;
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
refresh();
|
refresh();
|
||||||
@ -585,14 +594,14 @@ export async function createRiggingUI({
|
|||||||
: null;
|
: null;
|
||||||
el.textContent = [
|
el.textContent = [
|
||||||
`PREP — rig four corners $${s.budget} left`,
|
`PREP — rig four corners $${s.budget} left`,
|
||||||
`tension ${s.tension.toFixed(2)} spare x${s.spares}${area ? ` sail ${area.toFixed(0)} m2` : ''}`,
|
`tension ${s.tension.toFixed(2)} spare x${s.spares} ${s.fabric.name}${area ? ` sail ${area.toFixed(0)} m2` : ''}`,
|
||||||
'',
|
'',
|
||||||
...rows,
|
...rows,
|
||||||
...(standingLine ? ['', standingLine] : []),
|
...(standingLine ? ['', standingLine] : []),
|
||||||
'',
|
'',
|
||||||
s.canStart ? 'ENTER to start the storm' : `pick ${MAX_CORNERS - session.picks.length} more corner(s)`,
|
s.canStart ? 'ENTER to start the storm' : `pick ${MAX_CORNERS - session.picks.length} more corner(s)`,
|
||||||
'click anchor: rig / cycle hw shift-click: remove',
|
'click anchor: rig / cycle hw shift-click: remove',
|
||||||
'[ ] tension S spare RMB orbit',
|
'[ ] tension S spare F fabric RMB orbit',
|
||||||
].join('\n');
|
].join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
* js/tests/b.test.js) and node.
|
* js/tests/b.test.js) and node.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { RiggingSession } from './rigging.js';
|
import { RiggingSession, FABRIC } from './rigging.js';
|
||||||
import { SailRig, TENSION_MIN, TENSION_MAX } from './sail.js';
|
import { SailRig, TENSION_MIN, TENSION_MAX } from './sail.js';
|
||||||
import { HARDWARE, START_BUDGET, SPARE_COST } from './contracts.js';
|
import { HARDWARE, START_BUDGET, SPARE_COST } from './contracts.js';
|
||||||
|
|
||||||
@ -344,6 +344,21 @@ test('reset() returns a used session to a fresh prep phase', () => {
|
|||||||
return 'budget, picks, tension, spares all fresh; rig-able again';
|
return 'budget, picks, tension, spares all fresh; rig-able again';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('fabric is a bet the F key can actually place (SPRINT15 — the dead mechanic)', () => {
|
||||||
|
const s = session();
|
||||||
|
assert(s.fabric.id === 'cloth', `default fabric should be cloth, got ${s.fabric.id}`);
|
||||||
|
// the exact call the F key makes: cycle to the other entry by id
|
||||||
|
const next = FABRIC[(FABRIC.indexOf(s.fabric) + 1) % FABRIC.length];
|
||||||
|
assert(s.setFabric(next.id).ok, 'cycling to membrane refused');
|
||||||
|
assert(s.fabric.id === 'membrane' && s.fabric.porosity === 0, 'membrane not applied');
|
||||||
|
assert(s.budget === START_BUDGET, 'fabric is a bet, not a purchase — budget must not move');
|
||||||
|
assert(s.summary.fabric.id === 'membrane', 'the panel reads fabric off summary and must see the change');
|
||||||
|
// wrap-around brings it home, and garbage is refused loudly
|
||||||
|
assert(s.setFabric(FABRIC[(FABRIC.indexOf(s.fabric) + 1) % FABRIC.length].id).ok && s.fabric.id === 'cloth', 'cycle should wrap back to cloth');
|
||||||
|
assert(s.setFabric('hessian').ok === false, 'unknown fabric must refuse, not default');
|
||||||
|
return 'cloth -> membrane -> cloth, $0 both ways, hessian refused';
|
||||||
|
});
|
||||||
|
|
||||||
export const RIGGING_TESTS = TESTS;
|
export const RIGGING_TESTS = TESTS;
|
||||||
|
|
||||||
export function runRiggingSelftest() {
|
export function runRiggingSelftest() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user