diff --git a/assets/__pycache__/_regen.cpython-314.pyc b/assets/__pycache__/_regen.cpython-314.pyc index 7865d69..fbc0b26 100644 Binary files a/assets/__pycache__/_regen.cpython-314.pyc and b/assets/__pycache__/_regen.cpython-314.pyc differ diff --git a/assets/_regen.py b/assets/_regen.py index 4cef2f3..0b060f5 100644 --- a/assets/_regen.py +++ b/assets/_regen.py @@ -149,6 +149,48 @@ def kit_off(outs, ref_name, tol=(12, 10, 1.5)): f'(tolerance {tol})') return None +# ---- THE STRIDE GATE. A walk cycle is ONE DRAWING WITH THE LEGS MOVED. The generator does not know +# that: asked for "frame 2, then the same with the other leg forward", it draws two independent +# illustrations of the character — different torso twist, different arm positions, different camera +# distance — and every other check in this file passes on that happily (the frame count is right, the +# background is magenta, nothing touches an edge, the detail is fine). So the failure has been +# INVISIBLE and it has shipped repeatedly: the turned CPU's z_c1/z_c2 differ by 0.85 above the hip. +# +# Three numbers, silhouette only, on a feet-aligned centred overlay — which is how drawStatic puts +# them on screen, so this measures what the eye actually sees: +# HGT height ratio. drawStatic sizes every frame by its own PNG height, so anything off 1.00 is a +# body that GROWS AND SHRINKS once per step (the shambler's walk does, by 8%). +# TOP how much differs ABOVE the hip. Near zero for a real stride pair — same man, same camera. +# LEG how much differs BELOW it. This is the step. Near zero means the legs never moved. +# Calibrated on the pairs that read: the brute's wound lurch is (1.00, 0.000, 0.638) and the +# shambler's is (1.00, 0.070, 0.520); the failures sit at TOP 0.47-0.85 or LEG 0.09. The player's +# four-frame RUN sits at TOP 0.23 and is fine — a run swings the arms too — which is why this gate is +# opt-in per batch (`stride: [[i, j]]`) rather than applied to everything with two frames in it. +STRIDE_H, STRIDE_TOP, STRIDE_LEG, STRIDE_HIP = 0.04, 0.20, 0.30, 0.62 + +def stride_stats(pa, pb): + a, b = Image.open(pa).convert('RGBA'), Image.open(pb).convert('RGBA') + w, h = max(a.width, b.width), max(a.height, b.height) + def m(im): + c = Image.new('RGBA', (w, h)); c.paste(im, ((w - im.width) // 2, h - im.height)) + return np.array(c)[..., 3] > 110 + ma, mb = m(a), m(b) + hip = int(h * STRIDE_HIP) + d = lambda x, y: round(float((x ^ y).sum() / max(1, (x | y).sum())), 3) + return round(a.height / max(1, b.height), 3), d(ma[:hip], mb[:hip]), d(ma[hip:], mb[hip:]) + +def stride_off(outs, pairs): + for i, j in pairs: + hgt, top, leg = stride_stats(outs[i], outs[j]) + why = ('body pulsates' if abs(hgt - 1) > STRIDE_H else + 'whole body redrawn, not a leg swap' if top > STRIDE_TOP else + 'the legs do not move' if leg < STRIDE_LEG else None) + if why: + return (f'frames {i}/{j} are not one body with the legs moved — {why} ' + f'(height x{hgt:.2f}, upper {top:.3f}, legs {leg:.3f}; ' + f'want ~1.00 / <={STRIDE_TOP} / >={STRIDE_LEG})') + return None + def not_magenta(sheet): """The generator sometimes ignores the magenta and paints its own background. That was written off as harmless — the key uses the corner colour — right up until it returned a GREEN sheet and @@ -231,7 +273,10 @@ def run(name, spec, dry=False): if sum(after) / len(after) < sum(before) / len(before) * bar: print(f'[{name}] REJECTED: not finer than what it replaces {before} -> {after}'); return False if spec.get('palette_ref'): - bad = kit_off(outs, spec['palette_ref']) + bad = kit_off(outs, spec['palette_ref'], tuple(spec.get('palette_tol', (12, 10, 1.5)))) + if bad: print(f'[{name}] REJECTED: {bad}'); return False + if spec.get('stride'): + bad = stride_off(outs, spec['stride']) if bad: print(f'[{name}] REJECTED: {bad}'); return False for o, s in zip(outs, sprites): if spec.get('check', 'finer') == 'finer': colour_match(o, s) @@ -239,9 +284,30 @@ def run(name, spec, dry=False): print(f'[{name}] installed. detail {before} -> {after}') return True +# --audit runs the stride gate over the sprites ALREADY INSTALLED, which is the other half of it +# being useful: a gate that only fires on new rolls says nothing about the art already in the game, +# and the art already in the game is where this was first noticed. +def audit(B, names): + print(f"{'':34s} {'HGT':>6s} {'TOP':>6s} {'LEG':>6s} verdict") + bad = [] + for n in names: + for i, j in B[n].get('stride', []): + a, b = (os.path.join(HERE, B[n]['sprites'][k] + '.png') for k in (i, j)) + if not (os.path.exists(a) and os.path.exists(b)): continue + hgt, top, leg = stride_stats(a, b) + why = stride_off([a, b], [[0, 1]]) + label = f"{n} {B[n]['sprites'][i]}/{B[n]['sprites'][j]}" + print(f'{label:34s} {hgt:6.2f} {top:6.3f} {leg:6.3f} {"FAIL" if why else "ok"}') + if why: bad.append(label) + print('\nFAILS THE GATE:', ', '.join(bad) if bad else 'none') + return not bad + if __name__ == '__main__': args = sys.argv[1:] B = batches() + if '--audit' in args: + names = [a for a in args if not a.startswith('--')] or [k for k, v in B.items() if v.get('stride')] + sys.exit(0 if audit(B, names) else 1) if not args or '--list' in args: for k, v in B.items(): print(f'{k:16s} {len(v["sprites"]):2d} frames {", ".join(v["sprites"])}') sys.exit() diff --git a/assets/_regen_batches.json b/assets/_regen_batches.json index 0480794..1100bb7 100644 --- a/assets/_regen_batches.json +++ b/assets/_regen_batches.json @@ -1135,7 +1135,13 @@ "state": true, "check": "same", "anchor": 0, - "subject": "Four frames of the ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead man: yellow hair, red headband, red shirt, grey shorts, grey-green corpse skin, sunken eyes, a wooden racket in his hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. HIS KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: dirty yellow-blond hair, a RED CLOTH HEADBAND tied round his forehead, a torn red short-sleeved tennis shirt, SHORT GREY TENNIS SHORTS ENDING ABOVE THE KNEE (never long trousers), bare grey-green dead legs below them, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: the READY STANCE — copy the pose of reference image 2 exactly: knees bent, weight forward on the toes, the racket held UP in front of the body in both hands, chest and face square to the viewer, waiting to return a serve. Frame 2: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready in front. Frame 3: the same shuffle with the RIGHT leg driving out instead — identical to frame 2 in every other respect, only the legs swapped. Frame 4: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4 exactly: the body rotated, the arm extended across, the racket head out to the side at waist height, weight on the front foot. Output exactly 4 figures side by side in ONE horizontal row, all the same height. " + "subject": "Four frames of the ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead man: yellow hair, red headband, red shirt, grey shorts, grey-green corpse skin, sunken eyes, a wooden racket in his hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. HIS KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: dirty yellow-blond hair, a RED CLOTH HEADBAND tied round his forehead, a torn red short-sleeved tennis shirt, SHORT GREY TENNIS SHORTS ENDING ABOVE THE KNEE (never long trousers), bare grey-green dead legs below them, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: the READY STANCE — copy the pose of reference image 2 exactly: knees bent, weight forward on the toes, the racket held UP in front of the body in both hands, chest and face square to the viewer, waiting to return a serve. Frame 2: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready in front. Frame 3: the same shuffle with the RIGHT leg driving out instead — identical to frame 2 in every other respect, only the legs swapped. Frame 4: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4 exactly: the body rotated, the arm extended across, the racket head out to the side at waist height, weight on the front foot. Output exactly 4 figures side by side in ONE horizontal row, all the same height. ", + "stride": [ + [ + 1, + 2 + ] + ] }, "racket_w1": { "sprites": [ @@ -1152,7 +1158,19 @@ "state": true, "check": "same", "anchor": 0, - "subject": "Three frames of the ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead man: yellow hair, red headband, red shirt, grey shorts, grey-green corpse skin, sunken eyes, a wooden racket in his hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames his LEFT arm — the one WITHOUT the racket — has been torn off at the shoulder and the stump is gushing blood down his side, and his shirt is slashed open across the ribs. He still swings the racket with his remaining arm. HIS KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: dirty yellow-blond hair, a RED CLOTH HEADBAND tied round his forehead, a torn red short-sleeved tennis shirt, SHORT GREY TENNIS SHORTS ENDING ABOVE THE KNEE (never long trousers), bare grey-green dead legs below them, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. " + "subject": "Three frames of the ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead man: yellow hair, red headband, red shirt, grey shorts, grey-green corpse skin, sunken eyes, a wooden racket in his hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames his LEFT arm — the one WITHOUT the racket — has been torn off at the shoulder and the stump is gushing blood down his side, and his shirt is slashed open across the ribs. He still swings the racket with his remaining arm. HIS KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: dirty yellow-blond hair, a RED CLOTH HEADBAND tied round his forehead, a torn red short-sleeved tennis shirt, SHORT GREY TENNIS SHORTS ENDING ABOVE THE KNEE (never long trousers), bare grey-green dead legs below them, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. ", + "stride": [ + [ + 0, + 1 + ] + ], + "palette_ref": "z_r1", + "palette_tol": [ + 12, + 10, + 6 + ] }, "racket_w2": { "sprites": [ @@ -1169,7 +1187,19 @@ "state": true, "check": "same", "anchor": 0, - "subject": "Three frames of the ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead man: yellow hair, red headband, red shirt, grey shorts, grey-green corpse skin, sunken eyes, a wooden racket in his hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames he is HEADLESS: his head is gone entirely and the neck is a ragged gushing stump, so this figure is A CLEAR HEAD SHORTER than a whole man. He still holds and swings the racket. HIS KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: dirty yellow-blond hair, a RED CLOTH HEADBAND tied round his forehead, a torn red short-sleeved tennis shirt, SHORT GREY TENNIS SHORTS ENDING ABOVE THE KNEE (never long trousers), bare grey-green dead legs below them, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. " + "subject": "Three frames of the ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead man: yellow hair, red headband, red shirt, grey shorts, grey-green corpse skin, sunken eyes, a wooden racket in his hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames he is HEADLESS: his head is gone entirely and the neck is a ragged gushing stump, so this figure is A CLEAR HEAD SHORTER than a whole man. He still holds and swings the racket. HIS KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: dirty yellow-blond hair, a RED CLOTH HEADBAND tied round his forehead, a torn red short-sleeved tennis shirt, SHORT GREY TENNIS SHORTS ENDING ABOVE THE KNEE (never long trousers), bare grey-green dead legs below them, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. ", + "stride": [ + [ + 0, + 1 + ] + ], + "palette_ref": "z_r1", + "palette_tol": [ + 12, + 10, + 6 + ] }, "racket_f_play": { "sprites": [ @@ -1187,7 +1217,13 @@ "state": true, "check": "loose", "anchor": 0, - "subject": "Four frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead woman: matted ponytail, red headband, torn red shirt, dark pleated tennis skirt, grey-green corpse skin, sunken eyes, a wooden racket in her hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. HER KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: matted blond hair in a PONYTAIL, a RED CLOTH HEADBAND tied round her forehead, a torn red short-sleeved tennis shirt, a DARK PLEATED TENNIS SKIRT ENDING ABOVE THE KNEE, bare grey-green dead legs below it, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: the READY STANCE — copy the pose of reference image 2 exactly: knees bent, weight forward on the toes, the racket held UP in front of the body in both hands, chest and face square to the viewer, waiting to return a serve. Frame 2: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready in front. Frame 3: the same shuffle with the RIGHT leg driving out instead — identical to frame 2 in every other respect, only the legs swapped. Frame 4: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4 exactly: the body rotated, the arm extended across, the racket head out to the side at waist height, weight on the front foot. Output exactly 4 figures side by side in ONE horizontal row, all the same height. The four figures MUST NOT TOUCH OR OVERLAP each other in any way — leave a WIDE band of empty magenta between every pair, wider than a figure, including between their rackets and their outstretched arms. " + "subject": "Four frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead woman: matted ponytail, red headband, torn red shirt, dark pleated tennis skirt, grey-green corpse skin, sunken eyes, a wooden racket in her hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. HER KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: matted blond hair in a PONYTAIL, a RED CLOTH HEADBAND tied round her forehead, a torn red short-sleeved tennis shirt, a DARK PLEATED TENNIS SKIRT ENDING ABOVE THE KNEE, bare grey-green dead legs below it, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: the READY STANCE — copy the pose of reference image 2 exactly: knees bent, weight forward on the toes, the racket held UP in front of the body in both hands, chest and face square to the viewer, waiting to return a serve. Frame 2: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready in front. Frame 3: the same shuffle with the RIGHT leg driving out instead — identical to frame 2 in every other respect, only the legs swapped. Frame 4: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4 exactly: the body rotated, the arm extended across, the racket head out to the side at waist height, weight on the front foot. Output exactly 4 figures side by side in ONE horizontal row, all the same height. The four figures MUST NOT TOUCH OR OVERLAP each other in any way — leave a WIDE band of empty magenta between every pair, wider than a figure, including between their rackets and their outstretched arms. ", + "stride": [ + [ + 1, + 2 + ] + ] }, "racket_f_w1": { "sprites": [ @@ -1204,7 +1240,19 @@ "state": true, "check": "same", "anchor": 0, - "subject": "Three frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead woman: matted ponytail, red headband, torn red shirt, dark pleated tennis skirt, grey-green corpse skin, sunken eyes, a wooden racket in her hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames her LEFT arm — the one WITHOUT the racket — IS COMPLETELY GONE. She has ONLY ONE ARM: there is no left arm, no left hand and no left sleeve anywhere in the drawing, just a ragged torn stump at the left shoulder gushing blood down her side, and her shirt is slashed open across the ribs. She still swings the racket with her remaining arm. HER KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: matted blond hair in a PONYTAIL, a RED CLOTH HEADBAND tied round her forehead, a torn red short-sleeved tennis shirt, a DARK PLEATED TENNIS SKIRT ENDING ABOVE THE KNEE, bare grey-green dead legs below it, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. " + "subject": "Three frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead woman: matted ponytail, red headband, torn red shirt, dark pleated tennis skirt, grey-green corpse skin, sunken eyes, a wooden racket in her hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames her LEFT arm — the one WITHOUT the racket — IS COMPLETELY GONE. She has ONLY ONE ARM: there is no left arm, no left hand and no left sleeve anywhere in the drawing, just a ragged torn stump at the left shoulder gushing blood down her side, and her shirt is slashed open across the ribs. She still swings the racket with her remaining arm. HER KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: matted blond hair in a PONYTAIL, a RED CLOTH HEADBAND tied round her forehead, a torn red short-sleeved tennis shirt, a DARK PLEATED TENNIS SKIRT ENDING ABOVE THE KNEE, bare grey-green dead legs below it, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. ", + "stride": [ + [ + 0, + 1 + ] + ], + "palette_ref": "z_r1_f", + "palette_tol": [ + 12, + 10, + 6 + ] }, "racket_f_w2": { "sprites": [ @@ -1221,6 +1269,18 @@ "state": true, "check": "same", "anchor": 0, - "subject": "Three frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead woman: matted ponytail, red headband, torn red shirt, dark pleated tennis skirt, grey-green corpse skin, sunken eyes, a wooden racket in her hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames she is HEADLESS: her head IS COMPLETELY GONE and SO IS HER PONYTAIL — no head, no face, no hair, no scalp and no ponytail anywhere above the shoulders, only a ragged gushing neck stump where the head was, so this figure is A CLEAR HEAD SHORTER than a whole woman. She still holds and swings the racket. HER KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: matted blond hair in a PONYTAIL, a RED CLOTH HEADBAND tied round her forehead, a torn red short-sleeved tennis shirt, a DARK PLEATED TENNIS SKIRT ENDING ABOVE THE KNEE, bare grey-green dead legs below it, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. " + "subject": "Three frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — the same dead woman: matted ponytail, red headband, torn red shirt, dark pleated tennis skirt, grey-green corpse skin, sunken eyes, a wooden racket in her hand. The OTHER reference images are a LIVING tennis player and are there ONLY to show the POSES to copy — never the character, never the clothes, never the skin. In ALL THREE frames she is HEADLESS: her head IS COMPLETELY GONE and SO IS HER PONYTAIL — no head, no face, no hair, no scalp and no ponytail anywhere above the shoulders, only a ragged gushing neck stump where the head was, so this figure is A CLEAR HEAD SHORTER than a whole woman. She still holds and swings the racket. HER KIT IS FIXED AND MUST BE IDENTICAL IN EVERY FRAME: matted blond hair in a PONYTAIL, a RED CLOTH HEADBAND tied round her forehead, a torn red short-sleeved tennis shirt, a DARK PLEATED TENNIS SKIRT ENDING ABOVE THE KNEE, bare grey-green dead legs below it, white socks and white tennis shoes, and a wooden racket with a pale strung head. Frame 1: a SIDE SHUFFLE STEP toward the viewer — copy the legs of reference image 3, left leg driving out, the racket still held up ready. Frame 2: the same shuffle with the RIGHT leg driving out instead, identical otherwise. Frame 3: a FOREHAND SWING at the moment of contact — copy the pose of reference image 4: body rotated, the racket head out to the side at waist height. Output exactly 3 figures side by side in ONE horizontal row, all the same height. ", + "stride": [ + [ + 0, + 1 + ] + ], + "palette_ref": "z_r1_f", + "palette_tol": [ + 12, + 10, + 6 + ] } } \ No newline at end of file diff --git a/index.html b/index.html index 97a3b69..e90138f 100644 --- a/index.html +++ b/index.html @@ -430,6 +430,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') { - + diff --git a/src/render.js b/src/render.js index 9a86b80..2def838 100644 --- a/src/render.js +++ b/src/render.js @@ -631,9 +631,12 @@ function drawZombie(zb) { if (st && rNew) { // every wound stage carries the SAME three poses as the healthy body, so a one-armed // opponent still plays tennis rather than reverting to a shamble the moment you wound it + // ...stepped off GROUND COVERED, the same clock the healthy cycle two blocks up uses. It was + // walkT — a wall clock — so a wounded opponent's legs cycled at a fixed cadence however fast + // it was actually moving, which is the foot-slide this project banned for the heavy bodies. const base = 'z_rw' + st; const want = zb.pose === 'swing' ? base + 's' - : zb.pose === 'run' && SPR[base + 'b'] && stepFrame(zb.walkT * 5.2, 2) ? base + 'b' + : zb.pose === 'run' && SPR[base + 'b'] && stepFrame((zb.dist || 0) / TUNE.racketStride, 2) ? base + 'b' : base; if (SPR[want]) name = want; else if (SPR[base]) name = base; } else if (st) { // the old borrowed 'c' skins, while they are all there is