Cards say one thing: trimmed copy, and a title that fits the band

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
wuwiandClaude Fable 5 committed 2026-08-10 22:14:32 +02:00
1 parent 9fab26eec9
commit 4e80bd8cb2
4 files changed
+13 -15

No files matched your search

+2 -5
View File
@@ -541,7 +541,6 @@ export function proceedAfterClear() {
if (mode === 'set') {
G.card = { title: 'SET ' + (G.sets[0] + G.sets[1]), // the set just banked (sets already ++'d at game over)
sub1: side === 'P' ? 'THE SET IS YOURS' : 'SET TO THEM',
sub2: 'SETS ' + G.sets[0] + ' – ' + G.sets[1],
color: side === 'P' ? UI.pick : UI.hot, t: TUNE.setCardT };
G.pendingHorde = true; // the horde begins when the card's pause ends
ball.active = false; G.phase = 'over'; G.overT = TUNE.setCardT;
@@ -741,8 +740,7 @@ export function startBossFight(chapter) {
zombieDuck(true); // the music drops out for it
voice('ump_boss_arrives', 0, 0.9); voice('sudden_death', 2.6, 0.85);
const art = bossArt(chapter);
G.card = { title: 'CHAPTER ' + chapter, sub1: art.name, sub2: art.line || 'IT THROWS. RETURN IT.',
color: UI.bad, t: TUNE.setCardT };
G.card = { title: art.name, color: UI.bad, t: TUNE.setCardT };
G.flash = null;
if (!G.seen.boss) { // the rules change: a wall, and a thing that shoots back
G.seen.boss = true;
@@ -769,8 +767,7 @@ export function endBossFight() {
// long hold — the chapter and the crowd move down to the subs where they belong.
// (no 'GAME n NEXT' line: the bar under the scoreboard prints the game number permanently, and a
// card that repeats what the HUD already says is the clutter this pass is meant to remove.)
G.card = { title: 'EPIC!', sub1: 'CHAPTER ' + c + ' DOWN',
sub2: 'THE STANDS ARE ON THEIR FEET', color: UI.pick, t: TUNE.bossWinT,
G.card = { title: 'YOU DID IT', color: UI.pick, t: TUNE.bossWinT,
wait: TUNE.bossDeathT }; // ...after the body has finished coming apart
ball.active = false;
// a duel the handback just started owns the phase; otherwise hold the boss beat, and never
+1 -1
View File
@@ -398,6 +398,6 @@
</div>
</div>
</div>
<script type="module" src="main.js?v=144"></script>
<script type="module" src="main.js?v=145"></script>
</body>
</html>
+7 -1
View File
@@ -1348,7 +1348,13 @@ function cardBody(c, dx) {
// scoreboard and the ads, and 30 read as oversized the moment it left centre court. The stack
// keeps its own line rhythm (0/30/44) and is centred as ONE block, so a one-line card and a
// three-line card sit on the same axis instead of both hanging off the band's top edge.
const lines = [[title, B(22), 0, color]];
// ...and the title FITS. Cards carry whole sentences now ("SWING TO RETURN — OR SWISH IT AWAY")
// and boss names of any length, and Bangers 22 ran a long one off both edges of a phone. Measure
// once and shrink to the band; 22 stays 22 for everything that already fit.
ctx.font = B(22);
const tw = ctx.measureText(title).width;
const tSize = tw > W - 24 ? Math.max(13, Math.floor(22 * (W - 24) / tw)) : 22;
const lines = [[title, B(tSize), 0, color]];
if (sub1) lines.push([sub1, F(8), 30, UI.cream]);
if (sub2) lines.push([sub2, F(8), 44, UI.cream]);
const s = inkSpan(lines);
+3 -8
View File
@@ -103,7 +103,7 @@ export function spawnBarrel() {
if (!G.seen.barrel) {
G.seen.barrel = true;
G.card = { title: 'A GLOWING BARREL', sub1: 'A WEAPON IS INSIDE — SHOOT IT',
sub2: 'PINK MEANS TAKE THE SHOT', color: UI.pink, t: 2.6 };
color: UI.pink, t: 2.6 };
}
}
@@ -114,8 +114,7 @@ export function spawnMachine() {
voice('ump_machine', 0.4, 0.95);
if (!G.seen.mach) {
G.seen.mach = true;
G.card = { title: 'A BALL MACHINE', sub1: 'IT FIRES AT YOU ON A TIMER',
sub2: 'SWING TO RETURN — OR SWISH IT AWAY', color: UI.warm, t: 2.6 };
G.card = { title: 'SWING TO RETURN — OR SWISH IT AWAY', color: UI.warm, t: 2.6 };
}
}
@@ -799,11 +798,7 @@ export function spawnRacketZombie() { // one takes up residence on the far court
zombies.push({ x: (Math.random() * 2 - 1) * 2.5, z: 3.5, v: 0, walkT: Math.random() * 9,
variant: 'r', side: 'O', facing: 1, pose: 'idle', poseT: 0, swingT: -1, swingCool: 0, runT: 0,
hp, hpMax: hp });
if (!G.seen.racket) { // it is not a shambler and it does not behave like one — say so, once
G.seen.racket = true;
G.card = { title: 'IT HAS A RACKET', sub1: 'IT RETURNS YOUR WEAK SHOTS',
sub2: 'ONLY A FULL PULL WOUNDS IT', color: UI.hot, t: 2.6 };
}
// (the IT HAS A RACKET card is gone — the racket in its hand is the announcement)
}
function endHorde() {
G.horde = null; pellets.length = 0;