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'],
|
||||
['[ ]', 'tension the rig — tighter holds shape, and breaks harder'],
|
||||
['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)'],
|
||||
['C', 'brace against the wind'],
|
||||
['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);
|
||||
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() === '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;
|
||||
ev.preventDefault();
|
||||
refresh();
|
||||
@ -585,14 +594,14 @@ export async function createRiggingUI({
|
||||
: null;
|
||||
el.textContent = [
|
||||
`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,
|
||||
...(standingLine ? ['', standingLine] : []),
|
||||
'',
|
||||
s.canStart ? 'ENTER to start the storm' : `pick ${MAX_CORNERS - session.picks.length} more corner(s)`,
|
||||
'click anchor: rig / cycle hw shift-click: remove',
|
||||
'[ ] tension S spare RMB orbit',
|
||||
'[ ] tension S spare F fabric RMB orbit',
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
* 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 { 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';
|
||||
});
|
||||
|
||||
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 function runRiggingSelftest() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user