The twelve-rung ladder: director, champion, physio and mascot walk on
Oliver's four picks, each rolled off its own settled BOSS frame through the family pipeline (rows in _famroll.py) — the rung and the chapter boss are the same person. matchFoe decoupled from bossArt's cycling on his call: the match ladder is 12 with the champion capping rung 12; chapters keep their ten. The champion refused to bulk through four rolls (words lost, then a new pair-reference in char_ref only half-won), so his mass is stature: OPPONENTS rows carry an optional world height h read by zombieH — champion 2.1 m, the Bulk 2.0 m — and the serve aims at the body actually drawn. HEAD_CROP measured for all four; ramp test extended to 12 rungs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
99a87115b3
commit
9a49acff51
130 files changed
+98
-22
No files matched your search
+28
-12
@@ -756,9 +756,10 @@ export const bossArt = ch => ch % 10 === 0 ? BOSS_ART[BOSS_ART.length - 1]
|
||||
// is a property of the table rather than something the code has to arrange.
|
||||
// 1-2 the ones who fetch and sweep. Slow, wild, forgiving.
|
||||
// 3-4 the ones who keep order. They start covering ground.
|
||||
// 5-6 the ones who judge. Width arrives: they begin painting lines.
|
||||
// 7-8 the ones who actually played. The club pro's own body, and the brute behind him.
|
||||
// 9-10 management, and then the man whose name is on the honours board.
|
||||
// 5 the entertainment. The costume still fits.
|
||||
// 6-8 the ones who cover and judge. Width arrives: they begin painting lines.
|
||||
// 9-10 the ones who actually played. The club pro's own body, and the brute behind him.
|
||||
// 11-12 management, and then the man whose name is on the honours board.
|
||||
const OPPONENTS = [
|
||||
{ short: 'SHAMBLER', name: 'THE SHAMBLER', fam: 'sh',
|
||||
line: 'HE WAS HERE BEFORE ANY OF THIS.', speed: 0.72, pace: 0.72, wide: 0.75, flub: 1.35 },
|
||||
@@ -768,25 +769,36 @@ const OPPONENTS = [
|
||||
line: 'HE MOWED THIS LAWN FOR THIRTY YEARS.', speed: 0.9, pace: 0.88, wide: 0.9, flub: 1.05 },
|
||||
{ short: 'STEWARD', name: 'THE STEWARD', fam: 'st',
|
||||
line: 'HE IS ASKING YOU TO LEAVE.', speed: 0.98, pace: 0.95, wide: 1.0 },
|
||||
// 5-6: the entertainment, and then width arrives with the ones who judge
|
||||
{ short: 'MASCOT', name: 'THE MASCOT', fam: 'ma',
|
||||
line: 'THE CROWD STILL LOVES HIM.', speed: 1.02, pace: 0.98, wide: 1.05, flub: 1.0 },
|
||||
{ short: 'RUNNER', name: 'THE RUNNER', fam: 'ru',
|
||||
line: 'HE COVERS THE COURT. ALL OF IT.', speed: 1.22, pace: 1.0, wide: 1.05, flub: 0.95 },
|
||||
{ short: 'JUDGE', name: 'THE LINE JUDGE', fam: 'lj',
|
||||
line: 'EVERY BALL OF YOURS IS OUT.', speed: 1.05, pace: 1.05, wide: 1.28, flub: 0.85 },
|
||||
{ short: 'PHYSIO', name: 'THE PHYSIO', fam: 'ph',
|
||||
line: 'HE KNOWS EXACTLY WHERE IT HURTS.', speed: 1.1, pace: 1.1, wide: 1.22, flub: 0.82 },
|
||||
{ short: 'CLUB PRO', name: 'THE CLUB PRO',
|
||||
line: 'HE GAVE LESSONS ON THIS COURT.', speed: 1.12, pace: 1.15, wide: 1.15, flub: 0.8 },
|
||||
{ short: 'THE BULK', name: 'THE BULK', fam: 'br',
|
||||
{ short: 'THE BULK', name: 'THE BULK', fam: 'br', h: 2.0,
|
||||
line: 'NOTHING GETS PAST HIM TWICE.', speed: 1.0, pace: 1.3, wide: 1.2, flub: 0.75 },
|
||||
{ short: 'DIRECTOR', name: 'THE DIRECTOR',
|
||||
{ short: 'DIRECTOR', name: 'THE DIRECTOR', fam: 'dr',
|
||||
line: 'HE CAN HAVE YOU REMOVED.', speed: 1.22, pace: 1.22, wide: 1.25, flub: 0.65 },
|
||||
{ short: 'CHAMPION', name: 'THE CHAMPION',
|
||||
// 12: the man whose name is on the honours board. `h` is WORLD height (zombieH reads it, so the
|
||||
// serve aims at the body actually drawn): four family rolls could not make the art itself bulky
|
||||
// against the pose sheet — see _famroll.py's pair-reference note — so his size is stature.
|
||||
{ short: 'CHAMPION', name: 'THE CHAMPION', fam: 'ch', h: 2.1,
|
||||
line: 'HE RETURNS EVERYTHING.', speed: 1.35, pace: 1.3, wide: 1.3, flub: 0.5 },
|
||||
];
|
||||
|
||||
// Who opponent N is. The chapter roster's own order is reused wholesale (bossArt), so the champion
|
||||
// lands on opponent 10 exactly as he lands on chapter 10 and the two rosters can never drift apart.
|
||||
// Who opponent N is. This used to reuse the chapter roster's cycling (bossArt) so the two lists
|
||||
// could never drift — DECOUPLED 2026-08-13 on Oliver's call: the match ladder is 12 rungs with the
|
||||
// champion capping rung 12, while the chapter bosses stay a 10-design rotation with the champion
|
||||
// on every tenth. The lists share CHARACTERS (a rung and a boss are the same person, anchored on
|
||||
// the same art), just not arithmetic. The ladder cycles past 12 exactly as bossArt cycles past 10.
|
||||
export const matchFoe = n => {
|
||||
const art = bossArt(n), i = BOSS_ART.indexOf(art);
|
||||
return { name: art.name, key: 'L' + i, fam: 'r', ...OPPONENTS[i] };
|
||||
const i = (n - 1) % OPPONENTS.length;
|
||||
return { key: 'L' + i, fam: 'r', ...OPPONENTS[i] };
|
||||
};
|
||||
|
||||
// ---- THE SPRITE BENCH's stops (back room only, see beats.startBench). Each is either an ANIMATED
|
||||
@@ -821,7 +833,7 @@ export const BENCH_STAGES = ['HEALTHY', 'ARM OFF', 'HEADLESS'];
|
||||
// that (15 to 48 away from z_br1, where a good frame scores under 8.5) and refuses them, which is
|
||||
// the gate working, not the gate being wrong. Re-registering it is one entry here; see the note at
|
||||
// the top of _master.py for the fix its next attempt needs.
|
||||
export const ZFAMS = ['r', 'br', 'sh', 'bb', 'st', 'ru', 'gk', 'lj'];
|
||||
export const ZFAMS = ['r', 'br', 'sh', 'bb', 'st', 'ru', 'gk', 'lj', 'dr', 'ch', 'ph', 'ma'];
|
||||
|
||||
// HEAD CROPS for the opponent intro card — a straight source-pixel crop out of each family's own
|
||||
// healthy frame (z_<fam>1.png), so the card's icon is the body on court, never separate art.
|
||||
@@ -838,6 +850,10 @@ export const HEAD_CROP = {
|
||||
ru: { x: 14, y: 0, w: 57, h: 55 },
|
||||
gk: { x: 6, y: 0, w: 73, h: 65 },
|
||||
lj: { x: 6, y: 0, w: 74, h: 56 },
|
||||
dr: { x: 10, y: 0, w: 62, h: 49 },
|
||||
ch: { x: 3, y: 0, w: 68, h: 63 },
|
||||
ph: { x: 12, y: 0, w: 63, h: 58 },
|
||||
ma: { x: 0, y: 0, w: 124, h: 81 }, // the mascot's head IS the ball rim too — hand-deepened
|
||||
};
|
||||
|
||||
// THE RACKET FAMILY'S THREE STAGES, as a FRACTION of the pool — never against literal hp, the rule
|
||||
@@ -1007,7 +1023,7 @@ export const MACH_H = 1.55; // was 1.15 — waist high read as a prop you could
|
||||
export const zombieH = zb => zb.variant === 'o' ? TUNE.barrelH
|
||||
: zb.variant === 'g' ? 2.7 : zb.variant === 'd' ? 2.15
|
||||
: zb.variant === 'k' ? 3.2 : zb.variant === 'h' ? 2.4
|
||||
: zb.variant === 'r' ? 1.85 : zb.variant === 'm' ? MACH_H
|
||||
: zb.variant === 'r' ? ((zb.foe && zb.foe.h) || 1.85) : zb.variant === 'm' ? MACH_H
|
||||
: zb.variant === 'B' ? 1.8 * (zb.scale || 1.5) : 1.8;
|
||||
// Where on that body the ball is aimed, and where the aim mark is drawn. Solving the shot to the
|
||||
// GROUND under a shambler meant the ball came down past it and struck at the ankles — the wound is
|
||||
|
||||
Reference in new issue
Block a user