THE SEASON, phases 1-4: the front door is the fixture, and the club remembers

The tournament is the canonical path, so the game finally says so. The splash's
primary button names the next cup fixture and enters the draw; the poster wall
moved one tap down and deals three named rooms (the season, the training, out of
competition) with the cup at the top. Two profile fields remember every attempt
— rounds ever reached per league, and the body that put you out — so a lost cup
is a line on the board instead of a null event, and the training court offers
that body first, marked. The promotion names what waits in the new league.

Overlays consolidated in the same pass: three modal drawers became one box with
a masthead, hairline-separated rows and a real footer button (any tap still
dismisses), and the run-end summary wears the same box — headline, xp, mark, and
the fixture with ENTER THE DRAW beside PLAY AGAIN. The cup's own exit is a
ceremony now: OUT IN THE QUARTER-FINAL, your best standing beside it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-08-31 11:14:25 +02:00
1 parent 063b01d2a5
commit 5c7521f867
10 files changed
+603 -204

No files matched your search

+54
View File
@@ -115,6 +115,9 @@ function freshSplatter() {
// XP is zeroed too: the level feeds real dials now (legs, window), and accumulated awards from
// earlier tests would silently buff every later one.
prof.prof.lg = 1; prof.prof.ch = 0; prof.prof.xp = 0; prof.takePromo();
// THE SEASON: the cup record is written by a real cup ending, so it leaks between tests exactly
// the way the promotion did — the training court reads `out`, and a stale one reorders its list
prof.prof.cups = {}; prof.prof.out = 0;
G.mode = 'splatter';
G.everTransitioned = true;
setupPoint();
@@ -1235,6 +1238,57 @@ test('THE TOURNAMENT: bands draw, bodies deepen, rounds hold their body, the cha
assert.ok(pr && pr.to === 2, 'the ceremony is parked for the menu to play');
});
// ---- THE SEASON: the tournament is the story, so the club has to remember the attempts --------
test('THE SEASON: the fixture names the league, its rounds and the body that opens it', () => {
for (const l of cfg.LEAGUES) {
const fx = cfg.cupFixture(l.id), R = cfg.cupRoundsFor(l.id);
assert.equal(fx.rung, R[0].band[0], l.name + ': the fixture opens on round one\'s rung');
assert.equal(fx.foe.name, cfg.matchFoe(R[0].band[0]).name, l.name + ': and names that body');
assert.ok(fx.title.includes(String(l.id)) || fx.title === 'DEFEND THE TITLE',
l.name + ': the title carries the league');
assert.ok(fx.line.includes(R[0].name) && fx.line.startsWith(String(R.length)),
l.name + ': the line counts the rounds and names the first');
}
// the champion has nothing above him: his fixture is a defence, not a promotion
assert.equal(cfg.cupFixture(cfg.LEAGUES.length, 1).title, 'DEFEND THE TITLE');
// ...and a record reads in the rounds' own words
const R3 = cfg.cupRoundsFor(3);
assert.equal(cfg.cupRoundName(3, 1), R3[0].name, 'one round reached is round one');
assert.equal(cfg.cupRoundName(3, R3.length), 'THE FINAL', 'the last round is the final');
});
test('THE SEASON: a cup exit is recorded, forward only, and names who put you out', () => {
prof.prof.lg = 3;
_startMatch(true); // league 3's cup, round one
G.modal = null; G.modalQ.length = 0;
G.match.cup.round = 2; // deep: the semi-final
const rung = G.match.cup.rung;
killPlayer();
assert.equal(prof.cupBest(3), 3, 'the round you were in is the round you reached');
assert.equal(prof.prof.out, rung, 'the body holding the racket is the one that put you out');
assert.equal(prof.cupBest(1), 0, 'and it is that league\'s record, not the club\'s');
// a shallower attempt afterwards leaves the record standing — and still updates the eliminator
restartRun();
G.mode = 'splatter'; G.everTransitioned = true; setupPoint();
prof.prof.lg = 3;
_startMatch(true);
G.modal = null; G.modalQ.length = 0;
G.match.cup.round = 0;
const rung2 = G.match.cup.rung;
killPlayer();
assert.equal(prof.cupBest(3), 3, 'a worse run never erases a better one');
assert.equal(prof.prof.out, rung2, 'but the LAST body to end an attempt is always the offer');
// the training court is not an attempt and writes nothing
const out = prof.prof.out;
restartRun();
G.mode = 'splatter'; G.everTransitioned = true; setupPoint();
_startMatch(false, null, 2);
G.modal = null; G.modalQ.length = 0;
killPlayer();
assert.equal(prof.prof.out, out, 'a training rep is a rep, not a cup attempt');
});
test('THE CUP CLIMBS: rounds run easy to hard, deterministic, the final the top of the band', () => {
// the shuffle retired with the draw screen (Oliver: "warum sollten wir noch mischen?") — a bad
// roll paired the strongest challenger with the shortest round, inverting the tuned curve