Three modes, picked up front — and CLASSIC TENNIS is one of them
The setup screen picks WHAT before WHO and WHERE. Three rows out of a table, in the court row's own markup: CLASSIC TENNIS is not the opener with the turn switched off and left there — it is the mode the other two are built on, so it gets real match scoring: six games with a two-game lead is a set, best of TUNE.classicSets is the match, the board shows the sets column (hidden until now outside splatter) and the bar under it says which set this is. The CPU stops rubber-banding and flubs less: aiFlubLoss exists to get a new player PAST the opener, and a mode whose whole promise is a real match cannot be won by an opponent that falls apart the moment he goes ahead. No tiebreak — 6-6 plays on to 8-6. Marked ponytail. That needed a second ENDING, the one with no corpse in it: G.done, the same summary and gated tap as the death screen, its own words (GAME, SET, MATCH. / BEATEN.) and the man still standing. The three endings now share one block rather than three copies of it. Caught by the first classic test: stats banked only the FIRST classic run of a session. `banked` was cleared by the next KILL, and a classic match has no kills in it at all — every later match was swallowed by the double-bank guard. beginRun() is the honest reset and restartRun calls it. ZOMBIE TENNIS from the menu is one line; the back room keeps its door. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
No files matched your search
@@ -9,7 +9,7 @@
|
||||
# rather than a blurred photo of pixel art.
|
||||
# Usage: _fine.py sheet.png out1.png out2.png ... [--h 224] [--cut X,Y,...]
|
||||
import sys
|
||||
from PIL import Image
|
||||
from PIL import Image, ImageDraw
|
||||
import numpy as np
|
||||
|
||||
TARGET_H = 224
|
||||
@@ -22,7 +22,27 @@ def key(im, defringe=2):
|
||||
bg = a[0, 0, :3].astype(int)
|
||||
d = ((a[..., :3].astype(int) - bg) ** 2).sum(2)
|
||||
magenta = np.minimum(a[..., 0], a[..., 2]).astype(int) > a[..., 1].astype(int) + 40
|
||||
a[(d < KEY_D2) | magenta] = 0
|
||||
bgish = (d < KEY_D2) | magenta
|
||||
# ONLY THE OUTSIDE IS BACKGROUND. This used to punch out every magenta pixel on the sheet
|
||||
# wherever it was, and the generator paints a racket's STRINGS in the backdrop colour more often
|
||||
# than not — so frame after frame installed a man holding an empty hoop. Background is the region
|
||||
# CONNECTED TO THE BORDER (which touches_edge already guarantees no figure reaches), so an
|
||||
# enclosed patch of it inside a racket head is not background and does not become a hole.
|
||||
# .copy() is load-bearing: an Image.fromarray image is READ-ONLY, and ImageDraw.floodfill's
|
||||
# first write raises inside its own try/except and returns having filled nothing — a silent
|
||||
# no-op that looks exactly like "the whole sheet is one figure".
|
||||
m = Image.fromarray(np.where(bgish, 255, 0).astype('uint8'), 'L').copy()
|
||||
ImageDraw.floodfill(m, (0, 0), 128)
|
||||
outside = np.array(m) == 128
|
||||
if not outside.any(): sys.exit('ERROR: background flood filled nothing — is (0,0) not background?')
|
||||
a[outside] = 0
|
||||
# ...and what that leaves — magenta INSIDE a body — is repainted as pale grey rather than kept,
|
||||
# because bright pink strings are as wrong as no strings. Luminance is preserved, so the drawn
|
||||
# crosshatch survives as crosshatch; only the hue goes.
|
||||
inner = magenta & ~outside
|
||||
if inner.any():
|
||||
lum = a[..., :3].mean(2)
|
||||
a[inner, 0] = a[inner, 1] = a[inner, 2] = np.clip(lum[inner] * 0.5 + 115, 0, 255).astype('uint8')
|
||||
# De-fringe. The generator does not always give you a pure key colour, and whatever it does give
|
||||
# bleeds a halo one pixel into the sprite — which survives as a magenta rim once the sprite is on
|
||||
# a green court. Anything on the EDGE that is still leaning towards the background goes too.
|
||||
|
||||
@@ -41,7 +41,15 @@ FIDELITY = (
|
||||
)
|
||||
CANVAS = (
|
||||
"Hard black outline around each figure. The background must be ONE FLAT solid magenta "
|
||||
"#FF00FF across the entire canvas — no scenery, no gradient, no vignette. Keep at least 200 "
|
||||
"#FF00FF across the entire canvas — no scenery, no gradient, no vignette. "
|
||||
# NOTHING ON THE FIGURE MAY BE MAGENTA. The background colour is the transparency key, so any
|
||||
# magenta the generator paints INSIDE a body is cut out of the sprite. It filled a racket's
|
||||
# strings with the backdrop colour and installed four men holding an empty hoop — and the
|
||||
# not_magenta check cannot see it, because that check only reads the corner pixel.
|
||||
"MAGENTA AND PINK ARE THE BACKGROUND COLOUR AND MAY NOT APPEAR ANYWHERE ON A FIGURE: no magenta "
|
||||
"clothing, no pink skin, and racket strings are drawn as fine pale grey-white crosshatch over "
|
||||
"the figure's own body or clothes — NEVER left as the background colour showing through. "
|
||||
"Keep at least 200 "
|
||||
"pixels of empty magenta between figures and at least 150 pixels of empty magenta at every edge "
|
||||
"of the canvas: no figure or limb may touch or run off an edge. No shadow, no ground line, no text. "
|
||||
"The canvas is a WIDE LANDSCAPE STRIP and every figure stands side by side in ONE SINGLE HORIZONTAL "
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"z_dw",
|
||||
"z_dwb"
|
||||
],
|
||||
"subject": "Two frames of the same badly wounded zombie stadium steward in a torn high-visibility ORANGE vest \u2014 one arm mangled, a deep bloody gash across the chest, head lolling \u2014 walking, two stages of one stride, drawn as coarse low-resolution pixel art.",
|
||||
"subject": "Two frames of the same badly wounded zombie stadium steward in a torn high-visibility ORANGE vest — one arm mangled, a deep bloody gash across the chest, head lolling — walking, two stages of one stride, drawn as coarse low-resolution pixel art.",
|
||||
"anchor": 0,
|
||||
"state": true
|
||||
},
|
||||
@@ -76,7 +76,7 @@
|
||||
"z_c3",
|
||||
"z_c4"
|
||||
],
|
||||
"subject": "Four frames of the same zombie tennis player facing the viewer \u2014 yellow hair, red headband, red shirt, grey shorts, a wooden racket hanging from one hand \u2014 a four-frame shuffle towards the camera, drawn as coarse low-resolution pixel art.",
|
||||
"subject": "Four frames of the same zombie tennis player facing the viewer — yellow hair, red headband, red shirt, grey shorts, a wooden racket hanging from one hand — a four-frame shuffle towards the camera, drawn as coarse low-resolution pixel art.",
|
||||
"anchor": 0
|
||||
},
|
||||
"cpu_wounds": {
|
||||
@@ -109,7 +109,7 @@
|
||||
],
|
||||
"ref": "p_idle1",
|
||||
"anchor": 0,
|
||||
"subject": "Five frames of the same tennis player in a white shirt and blue shorts, drawn as coarse low-resolution pixel art. Every figure is seen strictly FROM BEHIND \u2014 the back of his head and the back of his shirt face the viewer, no face, no eyes, no nose, he is running or standing AWAY from the camera. First a standing frame for scale, then a four-frame run cycle, running away from the camera with no racket.",
|
||||
"subject": "Five frames of the same tennis player in a white shirt and blue shorts, drawn as coarse low-resolution pixel art. Every figure is seen strictly FROM BEHIND — the back of his head and the back of his shirt face the viewer, no face, no eyes, no nose, he is running or standing AWAY from the camera. First a standing frame for scale, then a four-frame run cycle, running away from the camera with no racket.",
|
||||
"check": "same"
|
||||
},
|
||||
"player_death": {
|
||||
@@ -155,7 +155,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is ONE tennis opponent in a RED polo shirt, dark grey shorts and a RED HEADBAND, seen from the front, gripping a tennis racket in his right hand. Draw FOUR frames of that same man RUNNING towards the camera. THE FOUR FRAMES MUST BE FOUR DIFFERENT BODY POSITIONS \u2014 no two frames alike, do not repeat a pose: (1) his RIGHT knee lifted high in front of him, left leg stretched out straight behind, left arm forward; (2) his right foot planted flat on the ground under him taking his weight, left knee just beginning to swing forward, both arms low; (3) his LEFT knee lifted high in front of him, right leg stretched out straight behind, right arm forward; (4) his left foot planted flat on the ground under him taking his weight, right knee just beginning to swing forward, both arms low. Every figure is the SAME man as the reference and the SAME size: red polo shirt, dark grey shorts, RED HEADBAND, blond hair, seen from the FRONT. Same face, same colours, same proportions, standing the same height. IN EVERY ONE OF THE FOUR FRAMES he is HOLDING THE TENNIS RACKET in his right hand \u2014 the full racket, with its oval head, its strings, its throat and its grip all drawn, exactly like the reference's racket, carried close in front of his chest. NO FRAME MAY HAVE AN EMPTY RIGHT HAND and no frame may show a racket with the head missing. The whole figure and the whole racket sit fully inside the canvas with clear space around them. The canvas must contain EXACTLY FOUR figures and no others. Do NOT redraw the standing reference pose as an extra figure.",
|
||||
"subject": "The reference is ONE tennis opponent in a RED polo shirt, dark grey shorts and a RED HEADBAND, seen from the front, gripping a tennis racket in his right hand. Draw FOUR frames of that same man RUNNING towards the camera. THE FOUR FRAMES MUST BE FOUR DIFFERENT BODY POSITIONS — no two frames alike, do not repeat a pose: (1) his RIGHT knee lifted high in front of him, left leg stretched out straight behind, left arm forward; (2) his right foot planted flat on the ground under him taking his weight, left knee just beginning to swing forward, both arms low; (3) his LEFT knee lifted high in front of him, right leg stretched out straight behind, right arm forward; (4) his left foot planted flat on the ground under him taking his weight, right knee just beginning to swing forward, both arms low. Every figure is the SAME man as the reference and the SAME size: red polo shirt, dark grey shorts, RED HEADBAND, blond hair, seen from the FRONT. Same face, same colours, same proportions, standing the same height. IN EVERY ONE OF THE FOUR FRAMES he is HOLDING THE TENNIS RACKET in his right hand — the full racket, with its oval head, its strings, its throat and its grip all drawn, exactly like the reference's racket, carried close in front of his chest. NO FRAME MAY HAVE AN EMPTY RIGHT HAND and no frame may show a racket with the head missing. The whole figure and the whole racket sit fully inside the canvas with clear space around them. The canvas must contain EXACTLY FOUR figures and no others. Do NOT redraw the standing reference pose as an extra figure.",
|
||||
"palette_ref": "o_idle1"
|
||||
},
|
||||
"ump_boy": {
|
||||
@@ -224,7 +224,7 @@
|
||||
"z_sdown"
|
||||
],
|
||||
"anchor": 0,
|
||||
"subject": "One frame of a zombie spectator in a grey-brown coat who has just had his wooden folding chair knocked DOWN out of his hands \u2014 the chair is falling beside him and he is staggering with his arms up \u2014 drawn as coarse low-resolution pixel art."
|
||||
"subject": "One frame of a zombie spectator in a grey-brown coat who has just had his wooden folding chair knocked DOWN out of his hands — the chair is falling beside him and he is staggering with his arms up — drawn as coarse low-resolution pixel art."
|
||||
},
|
||||
"boy_run_2": {
|
||||
"sprites": [
|
||||
@@ -260,7 +260,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is one zombie drawn FACING THE VIEWER. Draw FOUR frames of a DIFFERENT zombie in that same front-facing style, same size: a lean SPRINTING zombie in a torn grey-green tracksuit, charging straight down the court AT THE VIEWER. In every frame his chest and face point at you and he is coming towards you, foreshortened \u2014 one knee driven up high towards the camera, the other leg trailing far behind, arms pumping across his chest, body leaning into the run. The four frames are four stages of that charge: left knee up, mid-air stretch, right knee up, mid-air stretch the other way. He must NEVER be running sideways across the frame. Torn tracksuit, exposed ribs, green skin, sunken eyes and teeth. Output exactly four figures in one row."
|
||||
"subject": "The reference is one zombie drawn FACING THE VIEWER. Draw FOUR frames of a DIFFERENT zombie in that same front-facing style, same size: a lean SPRINTING zombie in a torn grey-green tracksuit, charging straight down the court AT THE VIEWER. In every frame his chest and face point at you and he is coming towards you, foreshortened — one knee driven up high towards the camera, the other leg trailing far behind, arms pumping across his chest, body leaning into the run. The four frames are four stages of that charge: left knee up, mid-air stretch, right knee up, mid-air stretch the other way. He must NEVER be running sideways across the frame. Torn tracksuit, exposed ribs, green skin, sunken eyes and teeth. Output exactly four figures in one row."
|
||||
},
|
||||
"brute_all_wounds": {
|
||||
"sprites": [
|
||||
@@ -270,7 +270,7 @@
|
||||
"z_gw2b"
|
||||
],
|
||||
"anchor": 0,
|
||||
"subject": "Four frames of the same enormous fat zombie brute, drawn as coarse low-resolution pixel art. The FIRST TWO are the same damage stage \u2014 his LEFT arm torn off at the shoulder leaving a ragged bloody stump, the right arm dragging a rusty pole \u2014 shown as two stages of one stride. The LAST TWO are the next damage stage, BOTH arms gone at the shoulders, again two stages of one stride. Within each pair the injuries must be IDENTICAL and on the same side of the body: only the legs change.",
|
||||
"subject": "Four frames of the same enormous fat zombie brute, drawn as coarse low-resolution pixel art. The FIRST TWO are the same damage stage — his LEFT arm torn off at the shoulder leaving a ragged bloody stump, the right arm dragging a rusty pole — shown as two stages of one stride. The LAST TWO are the next damage stage, BOTH arms gone at the shoulders, again two stages of one stride. Within each pair the injuries must be IDENTICAL and on the same side of the body: only the legs change.",
|
||||
"check": "same",
|
||||
"state": true
|
||||
},
|
||||
@@ -282,7 +282,7 @@
|
||||
"z_gw4b"
|
||||
],
|
||||
"anchor": 0,
|
||||
"subject": "Four frames of the same enormous fat zombie brute, drawn as coarse low-resolution pixel art. The FIRST TWO are the same damage stage \u2014 chest and belly torn wide open with the ribs showing \u2014 as two stages of one stride. The LAST TWO are the final stage, HEADLESS with the ribs out, still standing, again two stages of one stride. Within each pair the injuries must be IDENTICAL and in the same place: only the legs change.",
|
||||
"subject": "Four frames of the same enormous fat zombie brute, drawn as coarse low-resolution pixel art. The FIRST TWO are the same damage stage — chest and belly torn wide open with the ribs showing — as two stages of one stride. The LAST TWO are the final stage, HEADLESS with the ribs out, still standing, again two stages of one stride. Within each pair the injuries must be IDENTICAL and in the same place: only the legs change.",
|
||||
"check": "same"
|
||||
},
|
||||
"player_swing": {
|
||||
@@ -293,7 +293,7 @@
|
||||
"ref": "p_idle1",
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "Three frames of the same tennis player in a white shirt, blue shorts and a white headband, seen from BEHIND, drawn as coarse low-resolution pixel art. First a plain standing frame for scale, then two frames of a forehand swing \u2014 racket drawn back across the body, then followed through. In both he faces AWAY from the camera, up the court \u2014 the back of his head towards you, no face."
|
||||
"subject": "Three frames of the same tennis player in a white shirt, blue shorts and a white headband, seen from BEHIND, drawn as coarse low-resolution pixel art. First a plain standing frame for scale, then two frames of a forehand swing — racket drawn back across the body, then followed through. In both he faces AWAY from the camera, up the court — the back of his head towards you, no face."
|
||||
},
|
||||
"brute_w1": {
|
||||
"sprites": [
|
||||
@@ -306,7 +306,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"scale": 1.5,
|
||||
"subject": "The reference is one enormous fat zombie brute whose arm on the RIGHT-HAND SIDE OF THE IMAGE is torn off at the shoulder, leaving a ragged bloody stump, while the arm on the LEFT-HAND SIDE of the image is whole and drags a rusty pole. Draw TWO frames of that exact body as two stages of one stride. In BOTH frames the bloody stump must stay on the RIGHT-HAND SIDE OF THE IMAGE and the pole-dragging arm on the LEFT \u2014 do not mirror the body. Only the legs and the lean change: first left leg forward, then legs swapped with the weight sunk lower. Output exactly two figures in one row."
|
||||
"subject": "The reference is one enormous fat zombie brute whose arm on the RIGHT-HAND SIDE OF THE IMAGE is torn off at the shoulder, leaving a ragged bloody stump, while the arm on the LEFT-HAND SIDE of the image is whole and drags a rusty pole. Draw TWO frames of that exact body as two stages of one stride. In BOTH frames the bloody stump must stay on the RIGHT-HAND SIDE OF THE IMAGE and the pole-dragging arm on the LEFT — do not mirror the body. Only the legs and the lean change: first left leg forward, then legs swapped with the weight sunk lower. Output exactly two figures in one row."
|
||||
},
|
||||
"brute_w2": {
|
||||
"sprites": [
|
||||
@@ -318,7 +318,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is one enormous fat zombie brute with BOTH arms torn off at the shoulders, two ragged bloody stumps. Draw TWO frames of that EXACT same body \u2014 same injury, on the SAME side, same clothes, same size, same facing \u2014 as two stages of one stride: the first with his left leg forward and right leg back, the second with the legs swapped and his weight sunk lower. The injury must be pixel-identical in both frames; ONLY the legs and the lean change. Output exactly two figures in one row."
|
||||
"subject": "The reference is one enormous fat zombie brute with BOTH arms torn off at the shoulders, two ragged bloody stumps. Draw TWO frames of that EXACT same body — same injury, on the SAME side, same clothes, same size, same facing — as two stages of one stride: the first with his left leg forward and right leg back, the second with the legs swapped and his weight sunk lower. The injury must be pixel-identical in both frames; ONLY the legs and the lean change. Output exactly two figures in one row."
|
||||
},
|
||||
"brute_w3": {
|
||||
"sprites": [
|
||||
@@ -330,7 +330,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is one enormous fat zombie brute with his chest and belly torn wide open with the ribs showing through. Draw TWO frames of that EXACT same body \u2014 same injury, on the SAME side, same clothes, same size, same facing \u2014 as two stages of one stride: the first with his left leg forward and right leg back, the second with the legs swapped and his weight sunk lower. The injury must be pixel-identical in both frames; ONLY the legs and the lean change. Output exactly two figures in one row."
|
||||
"subject": "The reference is one enormous fat zombie brute with his chest and belly torn wide open with the ribs showing through. Draw TWO frames of that EXACT same body — same injury, on the SAME side, same clothes, same size, same facing — as two stages of one stride: the first with his left leg forward and right leg back, the second with the legs swapped and his weight sunk lower. The injury must be pixel-identical in both frames; ONLY the legs and the lean change. Output exactly two figures in one row."
|
||||
},
|
||||
"brute_w4": {
|
||||
"sprites": [
|
||||
@@ -342,7 +342,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "Draw TWO frames of an enormous fat zombie brute that has NO HEAD AT ALL \u2014 the neck ends in a ragged red stump at shoulder height, there is no skull, no face, no jaw, nothing above the shoulders \u2014 and whose chest is torn open with the ribs showing. Same body, same clothes and same size as the reference, as two stages of one stride: first left leg forward, then legs swapped with the weight lower. The missing head and the chest wound must be identical in both frames; only the legs change. Output exactly two figures in one row."
|
||||
"subject": "Draw TWO frames of an enormous fat zombie brute that has NO HEAD AT ALL — the neck ends in a ragged red stump at shoulder height, there is no skull, no face, no jaw, nothing above the shoulders — and whose chest is torn open with the ribs showing. Same body, same clothes and same size as the reference, as two stages of one stride: first left leg forward, then legs swapped with the weight lower. The missing head and the chest wound must be identical in both frames; only the legs change. Output exactly two figures in one row."
|
||||
},
|
||||
"brute_stages": {
|
||||
"sprites": [
|
||||
@@ -357,7 +357,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"scale": 1.5,
|
||||
"subject": "The reference is an enormous fat zombie brute \u2014 huge belly, stained shirt, brown trousers, dragging a rusty pole. Draw FOUR frames of that SAME body at that SAME size and bulk, standing, as four stages of damage: (1) the arm on the right-hand side of the image torn off at the shoulder leaving a ragged bloody stump, the other arm still dragging the pole; (2) BOTH arms torn off at the shoulders, two bloody stumps, no pole; (3) both arms gone and the chest and belly torn wide open with ribs showing through; (4) all of that AND no head at all \u2014 the neck ends in a ragged red stump at shoulder height, no skull, no face. He must stay the same enormous size and shape in all four \u2014 do not slim him down as the damage grows. Output exactly four figures in one row, evenly spaced."
|
||||
"subject": "The reference is an enormous fat zombie brute — huge belly, stained shirt, brown trousers, dragging a rusty pole. Draw FOUR frames of that SAME body at that SAME size and bulk, standing, as four stages of damage: (1) the arm on the right-hand side of the image torn off at the shoulder leaving a ragged bloody stump, the other arm still dragging the pole; (2) BOTH arms torn off at the shoulders, two bloody stumps, no pole; (3) both arms gone and the chest and belly torn wide open with ribs showing through; (4) all of that AND no head at all — the neck ends in a ragged red stump at shoulder height, no skull, no face. He must stay the same enormous size and shape in all four — do not slim him down as the damage grows. Output exactly four figures in one row, evenly spaced."
|
||||
},
|
||||
"brute_s12": {
|
||||
"sprites": [
|
||||
@@ -370,7 +370,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"scale": 1.4,
|
||||
"subject": "The reference is an enormous fat zombie brute \u2014 huge belly, stained shirt, brown trousers. Draw TWO frames of that SAME body at that SAME enormous size and bulk, standing, as two stages of damage: (1) the arm on the right-hand side of the image torn off at the shoulder leaving a ragged bloody stump, the other arm still dragging a rusty pole; (2) BOTH arms torn off at the shoulders, two bloody stumps, no pole. Do not slim him down. Output exactly two figures in one row, far apart."
|
||||
"subject": "The reference is an enormous fat zombie brute — huge belly, stained shirt, brown trousers. Draw TWO frames of that SAME body at that SAME enormous size and bulk, standing, as two stages of damage: (1) the arm on the right-hand side of the image torn off at the shoulder leaving a ragged bloody stump, the other arm still dragging a rusty pole; (2) BOTH arms torn off at the shoulders, two bloody stumps, no pole. Do not slim him down. Output exactly two figures in one row, far apart."
|
||||
},
|
||||
"brute_s34": {
|
||||
"sprites": [
|
||||
@@ -383,7 +383,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"scale": 1.4,
|
||||
"subject": "The reference is an enormous fat zombie brute \u2014 huge belly, stained shirt, brown trousers. Draw TWO frames of that SAME body at that SAME enormous size and bulk, standing, as two stages of damage: (1) both arms gone and the chest and belly torn wide open with the ribs showing through; (2) all of that AND no head at all \u2014 the neck ends in a ragged red stump at shoulder height, no skull, no face, nothing above the shoulders. Do not slim him down. Output exactly two figures in one row, far apart."
|
||||
"subject": "The reference is an enormous fat zombie brute — huge belly, stained shirt, brown trousers. Draw TWO frames of that SAME body at that SAME enormous size and bulk, standing, as two stages of damage: (1) both arms gone and the chest and belly torn wide open with the ribs showing through; (2) all of that AND no head at all — the neck ends in a ragged red stump at shoulder height, no skull, no face, nothing above the shoulders. Do not slim him down. Output exactly two figures in one row, far apart."
|
||||
},
|
||||
"player_stance_r": {
|
||||
"sprites": [
|
||||
@@ -397,7 +397,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is ONE tennis player in a white shirt, blue shorts and a white headband, seen from behind, serving with the racket high in his right hand. Draw FOUR frames of that same man. Every figure is seen strictly FROM BEHIND \u2014 the back of his head and the back of his shirt towards you, NO face, NO eyes, NO nose, NO mouth. Every figure is drawn from exactly the same viewpoint: same camera height, same distance, straight on, standing on the same level ground line, with no perspective distortion, no foreshortening, no worm's-eye or bird's-eye angle and no three-quarter turn. Same size, same body, same style, same BRIGHT WHITE shirt and BRIGHT BLUE shorts as the reference \u2014 do not wash the colours out. He is RIGHT-HANDED and the racket NEVER changes hands: in every single frame the racket is in his RIGHT hand, which \u2014 because he is drawn from behind \u2014 is on the RIGHT-HAND SIDE OF THE IMAGE, exactly as in the reference. His empty left arm is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball anywhere in any frame \u2014 the game draws the ball. Frame 1: he STANDS upright and relaxed at the baseline, arms down, the racket hanging at his right side. Frame 2: he leans forward a little and his empty LEFT hand reaches down and out to the LEFT-HAND SIDE OF THE IMAGE, palm down, as if patting a ball on the ground beside his left foot; the racket stays in his right hand at his right side. Frame 3 IS THE SAME DRAWING AS FRAME 2 \u2014 identical stance, identical legs, identical head, identical racket, identical everything \u2014 and the ONLY difference is that his left elbow is bent a little more so that left hand has risen about one hand's width higher, as if the ball had bounced back up into it. Frame 4: the ball toss \u2014 he leans back and throws that same empty LEFT arm up high above him on the LEFT-HAND SIDE OF THE IMAGE, having just released the ball, while the racket stays in his right hand down at his right side. Output exactly four figures in one row, evenly spaced and far apart."
|
||||
"subject": "The reference is ONE tennis player in a white shirt, blue shorts and a white headband, seen from behind, serving with the racket high in his right hand. Draw FOUR frames of that same man. Every figure is seen strictly FROM BEHIND — the back of his head and the back of his shirt towards you, NO face, NO eyes, NO nose, NO mouth. Every figure is drawn from exactly the same viewpoint: same camera height, same distance, straight on, standing on the same level ground line, with no perspective distortion, no foreshortening, no worm's-eye or bird's-eye angle and no three-quarter turn. Same size, same body, same style, same BRIGHT WHITE shirt and BRIGHT BLUE shorts as the reference — do not wash the colours out. He is RIGHT-HANDED and the racket NEVER changes hands: in every single frame the racket is in his RIGHT hand, which — because he is drawn from behind — is on the RIGHT-HAND SIDE OF THE IMAGE, exactly as in the reference. His empty left arm is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball anywhere in any frame — the game draws the ball. Frame 1: he STANDS upright and relaxed at the baseline, arms down, the racket hanging at his right side. Frame 2: he leans forward a little and his empty LEFT hand reaches down and out to the LEFT-HAND SIDE OF THE IMAGE, palm down, as if patting a ball on the ground beside his left foot; the racket stays in his right hand at his right side. Frame 3 IS THE SAME DRAWING AS FRAME 2 — identical stance, identical legs, identical head, identical racket, identical everything — and the ONLY difference is that his left elbow is bent a little more so that left hand has risen about one hand's width higher, as if the ball had bounced back up into it. Frame 4: the ball toss — he leans back and throws that same empty LEFT arm up high above him on the LEFT-HAND SIDE OF THE IMAGE, having just released the ball, while the racket stays in his right hand down at his right side. Output exactly four figures in one row, evenly spaced and far apart."
|
||||
},
|
||||
"opponent_swing": {
|
||||
"sprites": [
|
||||
@@ -407,7 +407,7 @@
|
||||
"ref": "o_idle1",
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "Three frames of the same tennis opponent, drawn as coarse low-resolution pixel art, side by side. FRAME 1: a plain standing frame for scale, exactly like the reference. FRAME 2 \u2014 THE BACKSWING: he has turned his shoulders and taken the racket BACK BEHIND HIS RIGHT HIP, low and well behind his body, arm coiled, racket head pointing backwards away from the net, weight on his back foot. He has NOT hit the ball yet. FRAME 3 \u2014 THE FOLLOW-THROUGH: the swing is FINISHED. His arm has swept all the way ACROSS HIS CHEST to the OTHER SIDE of his body and the racket head is now UP AND OVER HIS LEFT SHOULDER, near his left ear, his chest turned to face the net, weight on his front foot. FRAMES 2 AND 3 MUST LOOK COMPLETELY DIFFERENT FROM EACH OTHER \u2014 in frame 2 the racket is BEHIND him on his RIGHT, in frame 3 it is HIGH on his LEFT. This contrast is the whole point of the pair. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, DARK CHARCOAL GREY shorts, RED cloth headband, blond hair, white shoes, seen from the FRONT. Same face, same colours, same proportions. His headband is RED, never white or cream. In both swing frames he stays UPRIGHT at his full standing height \u2014 head at the same level as the standing frame, back straight, knees only slightly bent, never crouching or lunging low. The whole racket is drawn and fully inside the canvas. His shoes are WHITE with RED socks and his shirt is a BRIGHT PURE RED, exactly like the reference \u2014 not brick, not brown, not orange.",
|
||||
"subject": "Three frames of the same tennis opponent, drawn as coarse low-resolution pixel art, side by side. FRAME 1: a plain standing frame for scale, exactly like the reference. FRAME 2 — THE BACKSWING: he has turned his shoulders and taken the racket BACK BEHIND HIS RIGHT HIP, low and well behind his body, arm coiled, racket head pointing backwards away from the net, weight on his back foot. He has NOT hit the ball yet. FRAME 3 — THE FOLLOW-THROUGH: the swing is FINISHED. His arm has swept all the way ACROSS HIS CHEST to the OTHER SIDE of his body and the racket head is now UP AND OVER HIS LEFT SHOULDER, near his left ear, his chest turned to face the net, weight on his front foot. FRAMES 2 AND 3 MUST LOOK COMPLETELY DIFFERENT FROM EACH OTHER — in frame 2 the racket is BEHIND him on his RIGHT, in frame 3 it is HIGH on his LEFT. This contrast is the whole point of the pair. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, DARK CHARCOAL GREY shorts, RED cloth headband, blond hair, white shoes, seen from the FRONT. Same face, same colours, same proportions. His headband is RED, never white or cream. In both swing frames he stays UPRIGHT at his full standing height — head at the same level as the standing frame, back straight, knees only slightly bent, never crouching or lunging low. The whole racket is drawn and fully inside the canvas. His shoes are WHITE with RED socks and his shirt is a BRIGHT PURE RED, exactly like the reference — not brick, not brown, not orange.",
|
||||
"palette_ref": "o_idle1"
|
||||
},
|
||||
"opponent_idle": {
|
||||
@@ -420,7 +420,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is ONE tennis opponent standing and waiting, gripping a tennis racket in his right hand. Draw TWO frames of that same man waiting to receive, standing at the SAME FULL HEIGHT as the reference: the two frames are one relaxed weight shift, first with his weight on his left foot, then on his right, racket held ready in front of him in both. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, dark grey shorts, RED headband, blond hair, seen from the FRONT across the net. Same face, same colours, same proportions. CRITICAL: the ENTIRE racket \u2014 head, strings, throat and grip \u2014 is fully inside the canvas in both frames, with clear empty space between the racket and every edge. Nothing is cut off at an edge. He stands upright and does not crouch. His headband is RED, the same red as his shirt \u2014 it is NEVER white, cream or grey."
|
||||
"subject": "The reference is ONE tennis opponent standing and waiting, gripping a tennis racket in his right hand. Draw TWO frames of that same man waiting to receive, standing at the SAME FULL HEIGHT as the reference: the two frames are one relaxed weight shift, first with his weight on his left foot, then on his right, racket held ready in front of him in both. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, dark grey shorts, RED headband, blond hair, seen from the FRONT across the net. Same face, same colours, same proportions. CRITICAL: the ENTIRE racket — head, strings, throat and grip — is fully inside the canvas in both frames, with clear empty space between the racket and every edge. Nothing is cut off at an edge. He stands upright and does not crouch. His headband is RED, the same red as his shirt — it is NEVER white, cream or grey."
|
||||
},
|
||||
"opponent_toss": {
|
||||
"sprites": [
|
||||
@@ -430,7 +430,7 @@
|
||||
"ref": "o_idle1",
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "Three frames of the same tennis opponent, drawn as coarse low-resolution pixel art. FIRST a plain standing frame for scale, exactly like the reference. THEN the ball TOSS \u2014 standing tall, his free hand stretched straight up above his head having just released the ball, racket back and low. THEN the SMASH \u2014 at full stretch, the racket swung up overhead to hit. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, dark grey shorts, RED cloth headband, blond hair, seen from the FRONT. Same face, same colours, same proportions. His headband is RED, the same red as his shirt \u2014 never white, cream or grey. In the toss and smash frames his FEET STAY ON THE GROUND LINE and his body stays the same size as the standing frame; only his arms reach above his head. The whole racket is drawn and fully inside the canvas. His shorts are DARK CHARCOAL GREY, almost black \u2014 the same dark grey as the reference figure standing beside them, definitely NOT pale grey, light grey or blue. His shoes are white. Match the reference palette exactly in every frame.",
|
||||
"subject": "Three frames of the same tennis opponent, drawn as coarse low-resolution pixel art. FIRST a plain standing frame for scale, exactly like the reference. THEN the ball TOSS — standing tall, his free hand stretched straight up above his head having just released the ball, racket back and low. THEN the SMASH — at full stretch, the racket swung up overhead to hit. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, dark grey shorts, RED cloth headband, blond hair, seen from the FRONT. Same face, same colours, same proportions. His headband is RED, the same red as his shirt — never white, cream or grey. In the toss and smash frames his FEET STAY ON THE GROUND LINE and his body stays the same size as the standing frame; only his arms reach above his head. The whole racket is drawn and fully inside the canvas. His shorts are DARK CHARCOAL GREY, almost black — the same dark grey as the reference figure standing beside them, definitely NOT pale grey, light grey or blue. His shoes are white. Match the reference palette exactly in every frame.",
|
||||
"palette_ref": "o_idle1"
|
||||
},
|
||||
"opponent_bounce": {
|
||||
@@ -441,7 +441,7 @@
|
||||
"ref": "o_idle1",
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "Three frames of the same tennis opponent, drawn as coarse low-resolution pixel art. FIRST a plain standing frame for scale, exactly like the reference. THEN TWO frames of him standing at the baseline BOUNCING A BALL on the ground before serving, with NO ball drawn. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, dark grey shorts, RED cloth headband, blond hair, seen from the FRONT. Same face, same colours, same proportions. His headband is RED, the same red as his shirt \u2014 never white, cream or grey. In both bouncing frames his racket is held out to the side in his RIGHT hand \u2014 which is on the LEFT-HAND SIDE OF THE IMAGE \u2014 and his other arm is stretched DOWN AND OUT to the RIGHT-HAND SIDE OF THE IMAGE, well clear of his body, with the palm open and facing the ground as if patting a ball. CRITICAL: the two bouncing frames are otherwise the IDENTICAL drawing \u2014 same stance, same legs, same head, same racket, same size \u2014 and the ONLY difference between them is the height of that patting hand: in the first it is low, near knee height; in the second it is higher, near his waist. Draw NO ball in any frame.",
|
||||
"subject": "Three frames of the same tennis opponent, drawn as coarse low-resolution pixel art. FIRST a plain standing frame for scale, exactly like the reference. THEN TWO frames of him standing at the baseline BOUNCING A BALL on the ground before serving, with NO ball drawn. Every figure is the SAME man as the reference and the SAME size: RED polo shirt, dark grey shorts, RED cloth headband, blond hair, seen from the FRONT. Same face, same colours, same proportions. His headband is RED, the same red as his shirt — never white, cream or grey. In both bouncing frames his racket is held out to the side in his RIGHT hand — which is on the LEFT-HAND SIDE OF THE IMAGE — and his other arm is stretched DOWN AND OUT to the RIGHT-HAND SIDE OF THE IMAGE, well clear of his body, with the palm open and facing the ground as if patting a ball. CRITICAL: the two bouncing frames are otherwise the IDENTICAL drawing — same stance, same legs, same head, same racket, same size — and the ONLY difference between them is the height of that patting hand: in the first it is low, near knee height; in the second it is higher, near his waist. Draw NO ball in any frame.",
|
||||
"palette_ref": "o_idle1"
|
||||
},
|
||||
"ballboy_walk": {
|
||||
@@ -497,7 +497,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is one big walking zombie seen from the SIDE and facing LEFT. Draw FOUR frames of a walk cycle, seen from the SIDE and facing LEFT, of a dead SECURITY STEWARD working the tournament gate: a big heavy-set man with a shaven head and a thick neck, wearing an open BLACK bomber jacket over a bright YELLOW high-visibility vest with SECURITY in black block letters, a white shirt collar showing at the throat, a red accreditation lanyard, grey-green cargo trousers with deep pockets and visible seams, a chunky leather belt with a silver buckle, tan boots, tattoos down one bare forearm, and a coiled clear earpiece wire running up to one ear. Green-grey dead skin, jaw hanging, teeth bared. He is broad and slab-shouldered \u2014 noticeably heavier than the reference, but still a normal human silhouette \u2014 and he walks with his arms held out from his body, shoving forward. Draw him at the same overall height as the reference. The four frames are the four stages of ONE shambling stride: front leg reaching forward with the GAP BETWEEN THE FEET WIDE; then the feet together and passing; then the other leg reaching forward with the gap wide the other way; then the feet together again. The gap between his feet must visibly open and close, and the arms swing opposite the legs. Output exactly four figures in one row, evenly spaced.",
|
||||
"subject": "The reference is one big walking zombie seen from the SIDE and facing LEFT. Draw FOUR frames of a walk cycle, seen from the SIDE and facing LEFT, of a dead SECURITY STEWARD working the tournament gate: a big heavy-set man with a shaven head and a thick neck, wearing an open BLACK bomber jacket over a bright YELLOW high-visibility vest with SECURITY in black block letters, a white shirt collar showing at the throat, a red accreditation lanyard, grey-green cargo trousers with deep pockets and visible seams, a chunky leather belt with a silver buckle, tan boots, tattoos down one bare forearm, and a coiled clear earpiece wire running up to one ear. Green-grey dead skin, jaw hanging, teeth bared. He is broad and slab-shouldered — noticeably heavier than the reference, but still a normal human silhouette — and he walks with his arms held out from his body, shoving forward. Draw him at the same overall height as the reference. The four frames are the four stages of ONE shambling stride: front leg reaching forward with the GAP BETWEEN THE FEET WIDE; then the feet together and passing; then the other leg reaching forward with the gap wide the other way; then the feet together again. The gap between his feet must visibly open and close, and the arms swing opposite the legs. Output exactly four figures in one row, evenly spaced.",
|
||||
"state": true
|
||||
},
|
||||
"bouncer_w1": {
|
||||
@@ -536,7 +536,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is the dead SECURITY steward in his black bomber jacket over a bright yellow hi-vis vest, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same size and bulk and the same clothes, still walking, now WOUNDED: both arms are gone at the shoulders AND he has no head at all \u2014 the neck ends in a ragged red stump at shoulder height, no skull, no face \u2014 the earpiece wire dangling loose into the wound. Do not slim him down. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"subject": "The reference is the dead SECURITY steward in his black bomber jacket over a bright yellow hi-vis vest, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same size and bulk and the same clothes, still walking, now WOUNDED: both arms are gone at the shoulders AND he has no head at all — the neck ends in a ragged red stump at shoulder height, no skull, no face — the earpiece wire dangling loose into the wound. Do not slim him down. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"roller_walk": {
|
||||
@@ -551,7 +551,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is one enormous walking zombie brute seen from the SIDE and facing LEFT. Draw FOUR frames of a heavy walk cycle, seen from the SIDE and facing LEFT, of a dead GROUNDSMAN hauling a heavy court roller: a colossal man in filthy green overalls with the sleeves cut off, a leather tool belt, mud-caked rubber boots, leaning hard into a two-handed steel T-handle. The roller itself is a squat heavy cylinder on a short frame close behind his heels \u2014 it must stay small and entirely INSIDE his own frame, never reaching toward the next figure. Green-grey dead skin, one eye gone, teeth bared with effort. He is even bigger and heavier than the reference, hunched forward under the load. The four frames are the four stages of ONE shambling stride: front leg reaching forward with the GAP BETWEEN THE FEET WIDE; then the feet together and passing; then the other leg reaching forward with the gap wide the other way; then the feet together again. The gap between his feet must visibly open and close, and the arms swing opposite the legs. Output exactly four figures in one row, evenly spaced.",
|
||||
"subject": "The reference is one enormous walking zombie brute seen from the SIDE and facing LEFT. Draw FOUR frames of a heavy walk cycle, seen from the SIDE and facing LEFT, of a dead GROUNDSMAN hauling a heavy court roller: a colossal man in filthy green overalls with the sleeves cut off, a leather tool belt, mud-caked rubber boots, leaning hard into a two-handed steel T-handle. The roller itself is a squat heavy cylinder on a short frame close behind his heels — it must stay small and entirely INSIDE his own frame, never reaching toward the next figure. Green-grey dead skin, one eye gone, teeth bared with effort. He is even bigger and heavier than the reference, hunched forward under the load. The four frames are the four stages of ONE shambling stride: front leg reaching forward with the GAP BETWEEN THE FEET WIDE; then the feet together and passing; then the other leg reaching forward with the gap wide the other way; then the feet together again. The gap between his feet must visibly open and close, and the arms swing opposite the legs. Output exactly four figures in one row, evenly spaced.",
|
||||
"state": true
|
||||
},
|
||||
"roller_w1": {
|
||||
@@ -564,7 +564,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "any",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: the arm on the right-hand side of the image is COMPLETELY GONE \u2014 severed at the shoulder joint, no upper arm, no forearm, no hand, nothing below it but a ragged red stump of bone and muscle at the shoulder \u2014 while his other arm still grips the roller handle. He must stay exactly as enormous \u2014 do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: the arm on the right-hand side of the image is COMPLETELY GONE — severed at the shoulder joint, no upper arm, no forearm, no hand, nothing below it but a ragged red stump of bone and muscle at the shoulder — while his other arm still grips the roller handle. He must stay exactly as enormous — do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"roller_w2": {
|
||||
@@ -577,7 +577,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "any",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: BOTH arms are torn off at the shoulders leaving two bloody stumps and the roller is gone entirely. He must stay exactly as enormous \u2014 do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: BOTH arms are torn off at the shoulders leaving two bloody stumps and the roller is gone entirely. He must stay exactly as enormous — do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"roller_w3": {
|
||||
@@ -590,7 +590,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: both arms are gone AND his chest and belly are torn wide open with the ribs showing through, the overalls hanging in bloody strips. He must stay exactly as enormous \u2014 do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: both arms are gone AND his chest and belly are torn wide open with the ribs showing through, the overalls hanging in bloody strips. He must stay exactly as enormous — do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"roller_w4": {
|
||||
@@ -603,7 +603,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: both arms are gone, the chest is torn open with ribs showing, AND he has no head at all \u2014 the neck ends in a ragged red stump at shoulder height. He must stay exactly as enormous \u2014 do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"subject": "The reference is the dead groundsman in filthy green overalls, seen from the SIDE and facing LEFT. Draw TWO frames of that SAME man, the same colossal size and bulk and the same overalls, still walking, now WOUNDED: both arms are gone, the chest is torn open with ribs showing, AND he has no head at all — the neck ends in a ragged red stump at shoulder height. He must stay exactly as enormous — do not slim him down as the damage grows. The two frames are the two halves of ONE stride: in the first the front foot is far forward and the GAP BETWEEN THE FEET IS WIDE, in the second the feet are together and passing. Output exactly two figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"boss_coach_walk": {
|
||||
@@ -617,7 +617,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE HEAD COACH \u2014 a towering dead tennis coach facing the viewer, in a zipped navy and white tracksuit with a national-team crest on the chest and white piping down the sleeves, a steel whistle on a cord round his neck, wraparound sunglasses pushed up on his forehead, and a wire ball-hopper basket full of tennis balls gripped in one huge fist. Green-grey dead skin, hollow cheeks, teeth bared in a shout. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE HEAD COACH — a towering dead tennis coach facing the viewer, in a zipped navy and white tracksuit with a national-team crest on the chest and white piping down the sleeves, a steel whistle on a cord round his neck, wraparound sunglasses pushed up on his forehead, and a wire ball-hopper basket full of tennis balls gripped in one huge fist. Green-grey dead skin, hollow cheeks, teeth bared in a shout. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_coach_wounds": {
|
||||
"sprites": [
|
||||
@@ -630,7 +630,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "The reference is THE HEAD COACH \u2014 a towering dead tennis coach facing the viewer, in a zipped navy and white tracksuit with a national-team crest on the chest and white piping down the sleeves, a steel whistle on a cord round his neck, wraparound sunglasses pushed up on his forehead, and a wire ball-hopper basket full of tennis balls gripped in one huge fist. Green-grey dead skin, hollow cheeks, teeth bared in a shout, facing the viewer. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row.",
|
||||
"subject": "The reference is THE HEAD COACH — a towering dead tennis coach facing the viewer, in a zipped navy and white tracksuit with a national-team crest on the chest and white piping down the sleeves, a steel whistle on a cord round his neck, wraparound sunglasses pushed up on his forehead, and a wire ball-hopper basket full of tennis balls gripped in one huge fist. Green-grey dead skin, hollow cheeks, teeth bared in a shout, facing the viewer. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"boss_coach_throw": {
|
||||
@@ -648,7 +648,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row.",
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"boss_physio_walk": {
|
||||
@@ -662,7 +662,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE PHYSIO \u2014 a towering dead sports physiotherapist facing the viewer, in a white medical polo with a red cross on the breast and blood to the elbows, torn blue latex gloves, a bandolier of rolled strapping tape across the chest, a folding massage table strapped flat to his back, an ice pack gripped in one huge fist. Green-grey dead skin, wire-framed glasses cracked across one lens, jaw slack. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE PHYSIO — a towering dead sports physiotherapist facing the viewer, in a white medical polo with a red cross on the breast and blood to the elbows, torn blue latex gloves, a bandolier of rolled strapping tape across the chest, a folding massage table strapped flat to his back, an ice pack gripped in one huge fist. Green-grey dead skin, wire-framed glasses cracked across one lens, jaw slack. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_physio_wounds": {
|
||||
"sprites": [
|
||||
@@ -675,7 +675,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "The reference is THE PHYSIO \u2014 a towering dead sports physiotherapist facing the viewer, in a white medical polo with a red cross on the breast and blood to the elbows, torn blue latex gloves, a bandolier of rolled strapping tape across the chest, a folding massage table strapped flat to his back, an ice pack gripped in one huge fist. Green-grey dead skin, wire-framed glasses cracked across one lens, jaw slack, facing the viewer. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row.",
|
||||
"subject": "The reference is THE PHYSIO — a towering dead sports physiotherapist facing the viewer, in a white medical polo with a red cross on the breast and blood to the elbows, torn blue latex gloves, a bandolier of rolled strapping tape across the chest, a folding massage table strapped flat to his back, an ice pack gripped in one huge fist. Green-grey dead skin, wire-framed glasses cracked across one lens, jaw slack, facing the viewer. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"boss_physio_throw": {
|
||||
@@ -693,7 +693,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row.",
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"boss_mascot_walk": {
|
||||
@@ -707,7 +707,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE SPONSOR MASCOT \u2014 a towering dead tournament mascot facing the viewer, wearing a giant fuzzy tennis-ball costume: an enormous yellow-green foam sphere for a head and body with the white curved seam painted across it, stubby green sleeves and leggings, oversized cartoon shoes, white gloves. Through a dark mesh mouth-hole in the ball a rotting green face is just visible. He grips a tennis ball in one glove. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE SPONSOR MASCOT — a towering dead tournament mascot facing the viewer, wearing a giant fuzzy tennis-ball costume: an enormous yellow-green foam sphere for a head and body with the white curved seam painted across it, stubby green sleeves and leggings, oversized cartoon shoes, white gloves. Through a dark mesh mouth-hole in the ball a rotting green face is just visible. He grips a tennis ball in one glove. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_mascot_wounds": {
|
||||
"sprites": [
|
||||
@@ -720,7 +720,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "The reference is THE SPONSOR MASCOT \u2014 a towering dead tournament mascot facing the viewer, wearing a giant fuzzy tennis-ball costume: an enormous yellow-green foam sphere for a head and body with the white curved seam painted across it, stubby green sleeves and leggings, oversized cartoon shoes, white gloves. Through a dark mesh mouth-hole in the ball a rotting green face is just visible. He grips a tennis ball in one glove, facing the viewer. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row.",
|
||||
"subject": "The reference is THE SPONSOR MASCOT — a towering dead tournament mascot facing the viewer, wearing a giant fuzzy tennis-ball costume: an enormous yellow-green foam sphere for a head and body with the white curved seam painted across it, stubby green sleeves and leggings, oversized cartoon shoes, white gloves. Through a dark mesh mouth-hole in the ball a rotting green face is just visible. He grips a tennis ball in one glove, facing the viewer. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"boss_mascot_throw": {
|
||||
@@ -738,7 +738,7 @@
|
||||
],
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row.",
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row.",
|
||||
"state": true
|
||||
},
|
||||
"barrel": {
|
||||
@@ -753,7 +753,7 @@
|
||||
"check": "any",
|
||||
"newart": true,
|
||||
"h": 150,
|
||||
"subject": "The reference is a piece of tennis-court equipment drawn as pixel art, seen from the side. Draw TWO frames of a DIFFERENT object in that same style: a squat STEEL DRUM lying on its side like a barrel about to be rolled, banded with two raised hoops, its curved end-cap facing the viewer. The drum is DARK GUNMETAL GREY steel, heavily dented and streaked with rust, with bold YELLOW AND BLACK hazard chevrons stencilled around the middle band and a thin band of glowing PALE CYAN-WHITE light leaking from the seams between the staves. IMPORTANT: no part of the drum may be pink, magenta, purple or violet \u2014 use only grey steel, rust brown, yellow, black and pale cyan-white. It is a wide low object, clearly wider than it is tall, and it sits ON THE GROUND. The two frames are the same drum rotated part of a turn, so the hoops, chevrons and dents sit at visibly DIFFERENT angles \u2014 frame two is rolled about a third of a turn from frame one. Output exactly two objects in one row, evenly spaced."
|
||||
"subject": "The reference is a piece of tennis-court equipment drawn as pixel art, seen from the side. Draw TWO frames of a DIFFERENT object in that same style: a squat STEEL DRUM lying on its side like a barrel about to be rolled, banded with two raised hoops, its curved end-cap facing the viewer. The drum is DARK GUNMETAL GREY steel, heavily dented and streaked with rust, with bold YELLOW AND BLACK hazard chevrons stencilled around the middle band and a thin band of glowing PALE CYAN-WHITE light leaking from the seams between the staves. IMPORTANT: no part of the drum may be pink, magenta, purple or violet — use only grey steel, rust brown, yellow, black and pale cyan-white. It is a wide low object, clearly wider than it is tall, and it sits ON THE GROUND. The two frames are the same drum rotated part of a turn, so the hoops, chevrons and dents sit at visibly DIFFERENT angles — frame two is rolled about a third of a turn from frame one. Output exactly two objects in one row, evenly spaced."
|
||||
},
|
||||
"player_f_stance": {
|
||||
"sprites": [
|
||||
@@ -768,7 +768,7 @@
|
||||
"newart": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Four frames of a female tennis player in a bright white short-sleeved shirt and a WHITE PLEATED TENNIS SKIRT (a short flared skirt, clearly NOT shorts), white socks and white tennis shoes, her hair tied back in a PONYTAIL. She is the same height and the same drawing style as the reference and stands on the same ground line, but she is a woman, not the man in the reference. Every figure is seen strictly FROM BEHIND \u2014 the back of her head, her ponytail and the back of her shirt face the viewer, NO face, NO eyes, NO nose, NO mouth. Every figure is drawn from exactly the same viewpoint: same camera height, same distance, straight on, no foreshortening, no worm's-eye or bird's-eye angle, no three-quarter turn. She is RIGHT-HANDED and the racket NEVER changes hands: in every frame the racket is in her RIGHT hand, which \u2014 because she is drawn from behind \u2014 is on the RIGHT-HAND SIDE OF THE IMAGE. Her empty left arm is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball anywhere in any frame \u2014 the game draws the ball. Frame 1: she stands upright and relaxed at the baseline, weight on her left foot, racket hanging at her right side. Frame 2: the same stance with her weight shifted onto her right foot \u2014 identical otherwise. Frame 3: she leans forward slightly and her empty LEFT hand reaches DOWN and out to the LEFT, palm low near her knee, as if she had just patted a ball to the ground. Frame 4: the same stance with that same LEFT hand raised, palm out at about waist height, as if the ball had bounced back up to it. Frames 3 and 4 must be the SAME drawing with only the left hand's height changed \u2014 identical legs, identical body, identical racket."
|
||||
"subject": "Four frames of a female tennis player in a bright white short-sleeved shirt and a WHITE PLEATED TENNIS SKIRT (a short flared skirt, clearly NOT shorts), white socks and white tennis shoes, her hair tied back in a PONYTAIL. She is the same height and the same drawing style as the reference and stands on the same ground line, but she is a woman, not the man in the reference. Every figure is seen strictly FROM BEHIND — the back of her head, her ponytail and the back of her shirt face the viewer, NO face, NO eyes, NO nose, NO mouth. Every figure is drawn from exactly the same viewpoint: same camera height, same distance, straight on, no foreshortening, no worm's-eye or bird's-eye angle, no three-quarter turn. She is RIGHT-HANDED and the racket NEVER changes hands: in every frame the racket is in her RIGHT hand, which — because she is drawn from behind — is on the RIGHT-HAND SIDE OF THE IMAGE. Her empty left arm is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball anywhere in any frame — the game draws the ball. Frame 1: she stands upright and relaxed at the baseline, weight on her left foot, racket hanging at her right side. Frame 2: the same stance with her weight shifted onto her right foot — identical otherwise. Frame 3: she leans forward slightly and her empty LEFT hand reaches DOWN and out to the LEFT, palm low near her knee, as if she had just patted a ball to the ground. Frame 4: the same stance with that same LEFT hand raised, palm out at about waist height, as if the ball had bounced back up to it. Frames 3 and 4 must be the SAME drawing with only the left hand's height changed — identical legs, identical body, identical racket."
|
||||
},
|
||||
"opp_f_stance": {
|
||||
"sprites": [
|
||||
@@ -807,7 +807,7 @@
|
||||
"newart": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Five frames of the same FEMALE ZOMBIE TENNIS PLAYER facing the viewer \u2014 she is the turned opponent: grey-green dead skin, sunken eyes, a red headband, a RED shirt torn and bloodstained, a DARK PLEATED TENNIS SKIRT, her hair still in a matted PONYTAIL, a wooden racket hanging from one hand. She is the same height and drawing style as the reference but she is a woman, not the man in the reference. First a plain STANDING frame for scale, then a four-frame shuffle straight TOWARDS the camera, arms hanging, the stride alternating."
|
||||
"subject": "Five frames of the same FEMALE ZOMBIE TENNIS PLAYER facing the viewer — she is the turned opponent: grey-green dead skin, sunken eyes, a red headband, a RED shirt torn and bloodstained, a DARK PLEATED TENNIS SKIRT, her hair still in a matted PONYTAIL, a wooden racket hanging from one hand. She is the same height and drawing style as the reference but she is a woman, not the man in the reference. First a plain STANDING frame for scale, then a four-frame shuffle straight TOWARDS the camera, arms hanging, the stride alternating."
|
||||
},
|
||||
"cpu_f_wounds": {
|
||||
"sprites": [
|
||||
@@ -824,7 +824,7 @@
|
||||
"newart": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Four frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image \u2014 same woman, same red torn shirt, same dark pleated tennis skirt, same grey-green skin, facing the viewer. The second and third reference images show the two DAMAGE STAGES to copy onto her. Frame 1: her racket arm has been torn off at the shoulder, the stump gushing, still walking, left leg forward. Frame 2: HEADLESS \u2014 her head and ponytail are gone entirely and the neck is a ragged stump, so this figure is A CLEAR HEAD SHORTER THAN THE OTHERS, still walking, left leg forward. Frame 3: identical to frame 1 but with the RIGHT leg forward instead. Frame 4: identical to frame 2 but with the RIGHT leg forward instead. Frames 1 and 3 must be the same drawing with only the legs swapped, and so must frames 2 and 4."
|
||||
"subject": "Four frames of the FEMALE ZOMBIE TENNIS PLAYER shown in the FIRST reference image — same woman, same red torn shirt, same dark pleated tennis skirt, same grey-green skin, facing the viewer. The second and third reference images show the two DAMAGE STAGES to copy onto her. Frame 1: her racket arm has been torn off at the shoulder, the stump gushing, still walking, left leg forward. Frame 2: HEADLESS — her head and ponytail are gone entirely and the neck is a ragged stump, so this figure is A CLEAR HEAD SHORTER THAN THE OTHERS, still walking, left leg forward. Frame 3: identical to frame 1 but with the RIGHT leg forward instead. Frame 4: identical to frame 2 but with the RIGHT leg forward instead. Frames 1 and 3 must be the same drawing with only the legs swapped, and so must frames 2 and 4."
|
||||
},
|
||||
"player_f_serve": {
|
||||
"sprites": [
|
||||
@@ -841,7 +841,7 @@
|
||||
"pose": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Three frames of the woman shown in the FIRST reference figure \u2014 same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt, same height and drawing style. The SECOND, THIRD and FOURTH reference figures show a MALE player performing the three serve poses: copy each of those POSES EXACTLY \u2014 the same body position, the same lean, the same knee bend, the same racket arm angle, the same degree of coil or stretch \u2014 but performed BY HER, with her ponytail, her white shirt and her white pleated skirt, never his shorts and never his body. She is seen strictly FROM BEHIND \u2014 the back of her head, her ponytail and the back of her shirt face the viewer, NO face, NO eyes, NO nose, NO mouth. She is RIGHT-HANDED and the racket NEVER changes hands: in every frame the racket is in her RIGHT hand, on the RIGHT-HAND SIDE OF THE IMAGE, exactly as in the male reference poses. Draw NO ball anywhere in any frame \u2014 the game draws the ball. Frame 1: the pose of the SECOND reference figure \u2014 the serve toss, her empty LEFT arm thrown straight UP above her head, fingers open, the racket in her right hand still held low behind her. Frame 2: the pose of the THIRD reference figure \u2014 the smash, at FULL STRETCH, up on her toes, body fully extended and clearly TALLER than in any other frame, the racket swung high overhead mid-strike. Frame 3: the pose of the FOURTH reference figure, copied silhouette for silhouette \u2014 the slingshot wind-up. She leans BACKWARD, never forward: her shoulders are BEHIND her hips, her chest and face tilt UP toward the sky, her back is ARCHED like a drawn bow, her hips pushed forward, knees slightly bent, up on the balls of her feet. The racket in her right hand hangs DOWN AND BEHIND her arched back, its head pointing at the ground. Her whole body is a backward C-curve exactly like the fourth reference figure. She is NOT crouching, NOT bending forward at the waist, NOT in a ready stance \u2014 if her shoulders are in front of her hips the frame is WRONG."
|
||||
"subject": "Three frames of the woman shown in the FIRST reference figure — same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt, same height and drawing style. The SECOND, THIRD and FOURTH reference figures show a MALE player performing the three serve poses: copy each of those POSES EXACTLY — the same body position, the same lean, the same knee bend, the same racket arm angle, the same degree of coil or stretch — but performed BY HER, with her ponytail, her white shirt and her white pleated skirt, never his shorts and never his body. She is seen strictly FROM BEHIND — the back of her head, her ponytail and the back of her shirt face the viewer, NO face, NO eyes, NO nose, NO mouth. She is RIGHT-HANDED and the racket NEVER changes hands: in every frame the racket is in her RIGHT hand, on the RIGHT-HAND SIDE OF THE IMAGE, exactly as in the male reference poses. Draw NO ball anywhere in any frame — the game draws the ball. Frame 1: the pose of the SECOND reference figure — the serve toss, her empty LEFT arm thrown straight UP above her head, fingers open, the racket in her right hand still held low behind her. Frame 2: the pose of the THIRD reference figure — the smash, at FULL STRETCH, up on her toes, body fully extended and clearly TALLER than in any other frame, the racket swung high overhead mid-strike. Frame 3: the pose of the FOURTH reference figure, copied silhouette for silhouette — the slingshot wind-up. She leans BACKWARD, never forward: her shoulders are BEHIND her hips, her chest and face tilt UP toward the sky, her back is ARCHED like a drawn bow, her hips pushed forward, knees slightly bent, up on the balls of her feet. The racket in her right hand hangs DOWN AND BEHIND her arched back, its head pointing at the ground. Her whole body is a backward C-curve exactly like the fourth reference figure. She is NOT crouching, NOT bending forward at the waist, NOT in a ready stance — if her shoulders are in front of her hips the frame is WRONG."
|
||||
},
|
||||
"player_f_run": {
|
||||
"sprites": [
|
||||
@@ -856,7 +856,7 @@
|
||||
"pose": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Four frames of the woman in the reference \u2014 same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt. She is seen strictly FROM BEHIND, RUNNING DIRECTLY AWAY FROM THE CAMERA up the court, so you see her back and the soles of her shoes lifting behind her \u2014 NEVER in profile, NEVER from the side, NO face. She leans forward, arms swinging, ponytail lifting, and carries NO racket. The four frames are ONE FULL STRIDE and each must be a clearly DIFFERENT leg position: Frame 1 \u2014 her LEFT leg is kicked up and bent behind her with the sole of her LEFT shoe turned towards the camera, while her RIGHT leg is straight and planted on the ground. Frame 2 \u2014 both legs are together underneath her, passing each other, neither lifted, both shoes near the ground. Frame 3 \u2014 the MIRROR of frame 1: her RIGHT leg is kicked up and bent behind her with the sole of her RIGHT shoe turned towards the camera, while her LEFT leg is straight and planted. Frame 4 \u2014 both legs together passing again, the opposite arm forward from frame 2. Frames 1 and 3 must lift OPPOSITE legs and must not be the same drawing; frames 2 and 4 must swing opposite arms. All four figures are exactly the same height."
|
||||
"subject": "Four frames of the woman in the reference — same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt. She is seen strictly FROM BEHIND, RUNNING DIRECTLY AWAY FROM THE CAMERA up the court, so you see her back and the soles of her shoes lifting behind her — NEVER in profile, NEVER from the side, NO face. She leans forward, arms swinging, ponytail lifting, and carries NO racket. The four frames are ONE FULL STRIDE and each must be a clearly DIFFERENT leg position: Frame 1 — her LEFT leg is kicked up and bent behind her with the sole of her LEFT shoe turned towards the camera, while her RIGHT leg is straight and planted on the ground. Frame 2 — both legs are together underneath her, passing each other, neither lifted, both shoes near the ground. Frame 3 — the MIRROR of frame 1: her RIGHT leg is kicked up and bent behind her with the sole of her RIGHT shoe turned towards the camera, while her LEFT leg is straight and planted. Frame 4 — both legs together passing again, the opposite arm forward from frame 2. Frames 1 and 3 must lift OPPOSITE legs and must not be the same drawing; frames 2 and 4 must swing opposite arms. All four figures are exactly the same height."
|
||||
},
|
||||
"player_f_swing": {
|
||||
"sprites": [
|
||||
@@ -869,7 +869,7 @@
|
||||
"pose": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Two frames of the woman in the reference \u2014 same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt, same FULL-COLOUR drawing style. She is seen strictly FROM BEHIND \u2014 the back of her head, her ponytail and the back of her shirt face the viewer, NO face, NO eyes, NO nose, NO mouth \u2014 from exactly the reference's viewpoint: same camera height, same distance, straight on, no foreshortening and no three-quarter turn. She is RIGHT-HANDED and the racket NEVER changes hands: in every frame the racket is in her RIGHT hand, which \u2014 because she is drawn from behind \u2014 is on the RIGHT-HAND SIDE OF THE IMAGE. Her empty left arm is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball anywhere in any frame \u2014 the game draws the ball. Frame 1: a forehand wound up \u2014 the racket drawn back low across her body to her right, shoulders turned. Frame 2: the same forehand followed through \u2014 the racket swung up and across to her left, hips turned through. In both she still faces AWAY from the camera, up the court."
|
||||
"subject": "Two frames of the woman in the reference — same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt, same FULL-COLOUR drawing style. She is seen strictly FROM BEHIND — the back of her head, her ponytail and the back of her shirt face the viewer, NO face, NO eyes, NO nose, NO mouth — from exactly the reference's viewpoint: same camera height, same distance, straight on, no foreshortening and no three-quarter turn. She is RIGHT-HANDED and the racket NEVER changes hands: in every frame the racket is in her RIGHT hand, which — because she is drawn from behind — is on the RIGHT-HAND SIDE OF THE IMAGE. Her empty left arm is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball anywhere in any frame — the game draws the ball. Frame 1: a forehand wound up — the racket drawn back low across her body to her right, shoulders turned. Frame 2: the same forehand followed through — the racket swung up and across to her left, hips turned through. In both she still faces AWAY from the camera, up the court."
|
||||
},
|
||||
"player_f_fall": {
|
||||
"sprites": [
|
||||
@@ -883,7 +883,7 @@
|
||||
"pose": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Three frames of the woman in the reference \u2014 same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt \u2014 falling over, each one clearly and measurably shorter than the one before it: arched over backwards with both arms flung up, still at full standing height; dropped onto her knees, about four fifths of that height; pitched forward onto one hand, about half of it."
|
||||
"subject": "Three frames of the woman in the reference — same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt — falling over, each one clearly and measurably shorter than the one before it: arched over backwards with both arms flung up, still at full standing height; dropped onto her knees, about four fifths of that height; pitched forward onto one hand, about half of it."
|
||||
},
|
||||
"opp_f_play": {
|
||||
"sprites": [
|
||||
@@ -898,7 +898,7 @@
|
||||
"pose": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Four frames of the woman in the reference \u2014 same hair, same ponytail, same RED shirt, same dark pleated tennis skirt \u2014 seen from the FRONT across the net, from exactly the reference's viewpoint. Draw NO ball. Frame 1: the serve toss, her free arm thrown straight up above her head. Frame 2: the smash at full stretch, up on her toes, racket high overhead. Frame 3: a forehand wound up, racket drawn back across her body. Frame 4: the same forehand followed through, racket swung up and across."
|
||||
"subject": "Four frames of the woman in the reference — same hair, same ponytail, same RED shirt, same dark pleated tennis skirt — seen from the FRONT across the net, from exactly the reference's viewpoint. Draw NO ball. Frame 1: the serve toss, her free arm thrown straight up above her head. Frame 2: the smash at full stretch, up on her toes, racket high overhead. Frame 3: a forehand wound up, racket drawn back across her body. Frame 4: the same forehand followed through, racket swung up and across."
|
||||
},
|
||||
"player_f_bounce": {
|
||||
"sprites": [
|
||||
@@ -911,7 +911,7 @@
|
||||
"pose": true,
|
||||
"check": "same",
|
||||
"anchor": 0,
|
||||
"subject": "Two frames of the woman in the reference \u2014 same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt. She is seen strictly FROM BEHIND, the back of her head and her ponytail towards the viewer, NO face, from exactly the reference's viewpoint. The racket stays in her RIGHT hand (the RIGHT-HAND SIDE OF THE IMAGE) in both frames; her empty LEFT hand is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball. She is patting a ball against the ground before serving, so her empty LEFT hand stays LOW in BOTH frames \u2014 it NEVER rises above her waist and NEVER comes near her shoulder or her head. Frame 1: she leans forward slightly and her LEFT arm reaches DOWN and out to the left, the palm turned down at about KNEE height. Frame 2: the SAME stance with that same LEFT hand lifted only a little, the palm still turned down, now at about HIP height. Frames 1 and 2 must be the same drawing with ONLY the left hand's height changed \u2014 identical legs, identical body, identical racket, identical height."
|
||||
"subject": "Two frames of the woman in the reference — same DARK ALMOST-BLACK ponytail, same white shirt, same white pleated tennis skirt. She is seen strictly FROM BEHIND, the back of her head and her ponytail towards the viewer, NO face, from exactly the reference's viewpoint. The racket stays in her RIGHT hand (the RIGHT-HAND SIDE OF THE IMAGE) in both frames; her empty LEFT hand is on the LEFT-HAND SIDE OF THE IMAGE. Draw NO ball. She is patting a ball against the ground before serving, so her empty LEFT hand stays LOW in BOTH frames — it NEVER rises above her waist and NEVER comes near her shoulder or her head. Frame 1: she leans forward slightly and her LEFT arm reaches DOWN and out to the left, the palm turned down at about KNEE height. Frame 2: the SAME stance with that same LEFT hand lifted only a little, the palm still turned down, now at about HIP height. Frames 1 and 2 must be the same drawing with ONLY the left hand's height changed — identical legs, identical body, identical racket, identical height."
|
||||
},
|
||||
"boss_string_walk": {
|
||||
"sprites": [
|
||||
@@ -924,7 +924,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE STRINGER \u2014 a towering dead racket stringer facing the viewer, in a scuffed leather work apron over a sweat-stained club polo with the sleeves rolled up, both forearms wound with loops of pale gut string, a bandolier of string spools across his chest, long-nosed pliers and an awl hanging from his belt, and three bare racket frames strapped across his back. Green-grey dead skin, a length of string bitten between his teeth, sunken eyes. He grips a tennis ball in one huge fist. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE STRINGER — a towering dead racket stringer facing the viewer, in a scuffed leather work apron over a sweat-stained club polo with the sleeves rolled up, both forearms wound with loops of pale gut string, a bandolier of string spools across his chest, long-nosed pliers and an awl hanging from his belt, and three bare racket frames strapped across his back. Green-grey dead skin, a length of string bitten between his teeth, sunken eyes. He grips a tennis ball in one huge fist. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_string_wounds": {
|
||||
"sprites": [
|
||||
@@ -938,7 +938,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"state": true,
|
||||
"subject": "The reference is THE STRINGER \u2014 a towering dead racket stringer facing the viewer, in a scuffed leather work apron over a sweat-stained club polo with the sleeves rolled up, both forearms wound with loops of pale gut string, a bandolier of string spools across his chest, long-nosed pliers and an awl hanging from his belt, and three bare racket frames strapped across his back. Green-grey dead skin, a length of string bitten between his teeth, sunken eyes. He grips a tennis ball in one huge fist. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
"subject": "The reference is THE STRINGER — a towering dead racket stringer facing the viewer, in a scuffed leather work apron over a sweat-stained club polo with the sleeves rolled up, both forearms wound with loops of pale gut string, a bandolier of string spools across his chest, long-nosed pliers and an awl hanging from his belt, and three bare racket frames strapped across his back. Green-grey dead skin, a length of string bitten between his teeth, sunken eyes. He grips a tennis ball in one huge fist. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
},
|
||||
"boss_string_throw": {
|
||||
"sprites": [
|
||||
@@ -956,7 +956,7 @@
|
||||
"anchor": 0,
|
||||
"check": "any",
|
||||
"state": true,
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
},
|
||||
"boss_dir_walk": {
|
||||
"sprites": [
|
||||
@@ -969,7 +969,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE TOURNAMENT DIRECTOR \u2014 a towering dead official facing the viewer, in a double-breasted navy blazer with a gold club crest on the breast pocket, a striped club tie, cream trousers, and an accreditation lanyard round his neck. A black two-way radio is raised in one hand and a clipboard of order-of-play sheets is clamped under that arm. Green-grey dead skin, half-moon spectacles, jaw hanging open mid-announcement. He grips a tennis ball in his other huge fist. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE TOURNAMENT DIRECTOR — a towering dead official facing the viewer, in a double-breasted navy blazer with a gold club crest on the breast pocket, a striped club tie, cream trousers, and an accreditation lanyard round his neck. A black two-way radio is raised in one hand and a clipboard of order-of-play sheets is clamped under that arm. Green-grey dead skin, half-moon spectacles, jaw hanging open mid-announcement. He grips a tennis ball in his other huge fist. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_dir_wounds": {
|
||||
"sprites": [
|
||||
@@ -983,7 +983,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"state": true,
|
||||
"subject": "The reference is THE TOURNAMENT DIRECTOR \u2014 a towering dead official facing the viewer, in a double-breasted navy blazer with a gold club crest on the breast pocket, a striped club tie, cream trousers, and an accreditation lanyard round his neck. A black two-way radio is raised in one hand and a clipboard of order-of-play sheets is clamped under that arm. Green-grey dead skin, half-moon spectacles, jaw hanging open mid-announcement. He grips a tennis ball in his other huge fist. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
"subject": "The reference is THE TOURNAMENT DIRECTOR — a towering dead official facing the viewer, in a double-breasted navy blazer with a gold club crest on the breast pocket, a striped club tie, cream trousers, and an accreditation lanyard round his neck. A black two-way radio is raised in one hand and a clipboard of order-of-play sheets is clamped under that arm. Green-grey dead skin, half-moon spectacles, jaw hanging open mid-announcement. He grips a tennis ball in his other huge fist. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
},
|
||||
"boss_dir_throw": {
|
||||
"sprites": [
|
||||
@@ -1001,7 +1001,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"state": true,
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
},
|
||||
"boss_berry_walk": {
|
||||
"sprites": [
|
||||
@@ -1014,7 +1014,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE STRAWBERRY SELLER \u2014 a towering dead tournament vendor facing the viewer, in a white apron soaked through with deep red and a folded paper cap, a wooden vendor's tray slung from a neck strap across his belly loaded with punnets of DEEP RED strawberries and white jugs of cream, sleeves shoved up over blood-smeared forearms, a serving ladle hanging from his belt. Green-grey dead skin, cream down his chin, hollow eyes. He grips a tennis ball in one huge fist. Use only deep blood red, white, cream and brown \u2014 absolutely no pink, no magenta, no violet and no purple anywhere in the drawing. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE STRAWBERRY SELLER — a towering dead tournament vendor facing the viewer, in a white apron soaked through with deep red and a folded paper cap, a wooden vendor's tray slung from a neck strap across his belly loaded with punnets of DEEP RED strawberries and white jugs of cream, sleeves shoved up over blood-smeared forearms, a serving ladle hanging from his belt. Green-grey dead skin, cream down his chin, hollow eyes. He grips a tennis ball in one huge fist. Use only deep blood red, white, cream and brown — absolutely no pink, no magenta, no violet and no purple anywhere in the drawing. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_berry_wounds": {
|
||||
"sprites": [
|
||||
@@ -1028,7 +1028,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"state": true,
|
||||
"subject": "The reference is THE STRAWBERRY SELLER \u2014 a towering dead tournament vendor facing the viewer, in a white apron soaked through with deep red and a folded paper cap, a wooden vendor's tray slung from a neck strap across his belly loaded with punnets of DEEP RED strawberries and white jugs of cream, sleeves shoved up over blood-smeared forearms, a serving ladle hanging from his belt. Green-grey dead skin, cream down his chin, hollow eyes. He grips a tennis ball in one huge fist. Use only deep blood red, white, cream and brown \u2014 absolutely no pink, no magenta, no violet and no purple anywhere in the drawing. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
"subject": "The reference is THE STRAWBERRY SELLER — a towering dead tournament vendor facing the viewer, in a white apron soaked through with deep red and a folded paper cap, a wooden vendor's tray slung from a neck strap across his belly loaded with punnets of DEEP RED strawberries and white jugs of cream, sleeves shoved up over blood-smeared forearms, a serving ladle hanging from his belt. Green-grey dead skin, cream down his chin, hollow eyes. He grips a tennis ball in one huge fist. Use only deep blood red, white, cream and brown — absolutely no pink, no magenta, no violet and no purple anywhere in the drawing. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
},
|
||||
"boss_berry_throw": {
|
||||
"sprites": [
|
||||
@@ -1046,7 +1046,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"state": true,
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
},
|
||||
"boss_champ_walk": {
|
||||
"sprites": [
|
||||
@@ -1059,7 +1059,7 @@
|
||||
"anchor": 0,
|
||||
"check": "same",
|
||||
"newart": true,
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE CHAMPION \u2014 the towering dead fourteen-time champion facing the viewer, in a torn all-white tennis kit gone grey and yellow with age, gold trim at the collar, a laurel of white strapping tape wound round his head like a crown, an old sweatband on each wrist. A huge silver trophy is gripped in one fist and held slightly out from his body. Green-grey dead skin drawn tight over a heavy champion's jaw, sunken eyes, teeth bared. He grips a tennis ball in his other huge fist. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
"subject": "The reference is a huge chapter-boss zombie drawn FACING THE VIEWER. Draw TWO frames of a DIFFERENT boss in that same front-facing style and at that same enormous size: THE CHAMPION — the towering dead fourteen-time champion facing the viewer, in a torn all-white tennis kit gone grey and yellow with age, gold trim at the collar, a laurel of white strapping tape wound round his head like a crown, an old sweatband on each wrist. A huge silver trophy is gripped in one fist and held slightly out from his body. Green-grey dead skin drawn tight over a heavy champion's jaw, sunken eyes, teeth bared. He grips a tennis ball in his other huge fist. In both frames his chest and face point straight at the viewer. The two frames are two stages of one heavy stride straight toward the viewer, one knee lifted in each. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_champ_wounds": {
|
||||
"sprites": [
|
||||
@@ -1073,7 +1073,7 @@
|
||||
"anchor": 0,
|
||||
"check": "loose",
|
||||
"state": true,
|
||||
"subject": "The reference is THE CHAMPION \u2014 the towering dead fourteen-time champion facing the viewer, in a torn all-white tennis kit gone grey and yellow with age, gold trim at the collar, a laurel of white strapping tape wound round his head like a crown, an old sweatband on each wrist. A huge silver trophy is gripped in one fist and held slightly out from his body. Green-grey dead skin drawn tight over a heavy champion's jaw, sunken eyes, teeth bared. He grips a tennis ball in his other huge fist. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump \u2014 the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips \u2014 one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height \u2014 one arm is still whole and still holding what it held. He must stay the same enormous size in all three \u2014 do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
"subject": "The reference is THE CHAMPION — the towering dead fourteen-time champion facing the viewer, in a torn all-white tennis kit gone grey and yellow with age, gold trim at the collar, a laurel of white strapping tape wound round his head like a crown, an old sweatband on each wrist. A huge silver trophy is gripped in one fist and held slightly out from his body. Green-grey dead skin drawn tight over a heavy champion's jaw, sunken eyes, teeth bared. He grips a tennis ball in his other huge fist. Draw THREE frames of that SAME boss, the same enormous size and the same costume, standing and facing the viewer, as three worsening stages of damage: (1) the arm on the left-hand side of the image is torn off at the shoulder leaving a ragged bloody stump — the OTHER arm is untouched and still holding what it held; (2) his chest and belly are torn wide open with the ribs showing through and the clothing hanging in bloody strips — one arm is still whole and still holding what it held; (3) his chest is torn open with ribs showing AND he has no head at all, the neck ending in a ragged red stump at shoulder height — one arm is still whole and still holding what it held. He must stay the same enormous size in all three — do not slim him down as the damage grows. Output exactly three figures in one row."
|
||||
},
|
||||
"boss_champ_throw": {
|
||||
"sprites": [
|
||||
@@ -1091,7 +1091,7 @@
|
||||
"anchor": 0,
|
||||
"check": "any",
|
||||
"state": true,
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds \u2014 but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
"subject": "The reference shows the SAME boss in four states: undamaged, then three worsening stages of damage. Draw all FOUR of those exact states again, in the same order, same size, same costume, same wounds — but each one caught MID-THROW: the whole body wound up and twisted, the surviving arm drawn back high over the shoulder about to hurl a tennis ball straight at the viewer, weight on the back foot. The wounds must stay clearly visible in every frame. Output exactly four figures in one row."
|
||||
},
|
||||
"boss_berry_stride": {
|
||||
"sprites": [
|
||||
@@ -1104,7 +1104,7 @@
|
||||
"anchor": 0,
|
||||
"check": "any",
|
||||
"state": true,
|
||||
"subject": "The reference is THE STRAWBERRY SELLER \u2014 a towering dead tournament vendor facing the viewer, in a white apron soaked through with deep red and a folded paper cap, a wooden vendor's tray slung from a neck strap across his belly loaded with punnets of DEEP RED strawberries and white jugs of cream, sleeves shoved up over blood-smeared forearms, a serving ladle hanging from his belt. Green-grey dead skin, hollow eyes. He grips a tennis ball in one huge fist. No pink, no magenta, no violet, no purple. Draw TWO frames of that SAME boss walking straight toward the viewer. THE LEGS ARE THE ENTIRE POINT OF THIS SHEET AND THE TWO FRAMES MUST BE OPPOSITE HALVES OF ONE STRIDE. FRAME ONE: his LEFT leg is striding forward with the foot flat on the ground well ahead of him and his RIGHT leg is trailing far behind, that back heel lifted off the ground \u2014 the feet are wide apart with clear empty space between the two shoes. FRAME TWO: exactly the other way round \u2014 his RIGHT leg strides forward with the foot flat on the ground well ahead of him and the LEFT leg trails far behind with the heel lifted, again with the feet wide apart. In frame two the arms swing the opposite way to frame one as well. Do NOT draw the same leg forward in both frames and do NOT draw him standing on one leg with a knee raised \u2014 these are two moments of a heavy walk, so in each frame one foot is planted ahead and the other is behind. Same size, same costume, same face, chest and face squarely toward the viewer in both. Output exactly two figures in one row."
|
||||
"subject": "The reference is THE STRAWBERRY SELLER — a towering dead tournament vendor facing the viewer, in a white apron soaked through with deep red and a folded paper cap, a wooden vendor's tray slung from a neck strap across his belly loaded with punnets of DEEP RED strawberries and white jugs of cream, sleeves shoved up over blood-smeared forearms, a serving ladle hanging from his belt. Green-grey dead skin, hollow eyes. He grips a tennis ball in one huge fist. No pink, no magenta, no violet, no purple. Draw TWO frames of that SAME boss walking straight toward the viewer. THE LEGS ARE THE ENTIRE POINT OF THIS SHEET AND THE TWO FRAMES MUST BE OPPOSITE HALVES OF ONE STRIDE. FRAME ONE: his LEFT leg is striding forward with the foot flat on the ground well ahead of him and his RIGHT leg is trailing far behind, that back heel lifted off the ground — the feet are wide apart with clear empty space between the two shoes. FRAME TWO: exactly the other way round — his RIGHT leg strides forward with the foot flat on the ground well ahead of him and the LEFT leg trails far behind with the heel lifted, again with the feet wide apart. In frame two the arms swing the opposite way to frame one as well. Do NOT draw the same leg forward in both frames and do NOT draw him standing on one leg with a knee raised — these are two moments of a heavy walk, so in each frame one foot is planted ahead and the other is behind. Same size, same costume, same face, chest and face squarely toward the viewer in both. Output exactly two figures in one row."
|
||||
},
|
||||
"boss_champ_stride": {
|
||||
"sprites": [
|
||||
@@ -1117,6 +1117,110 @@
|
||||
"anchor": 0,
|
||||
"check": "any",
|
||||
"state": true,
|
||||
"subject": "The FIRST figure in the reference is THE CHAMPION \u2014 the towering dead fourteen-time champion facing the viewer, in a torn all-white tennis kit gone grey and yellow with age, gold trim at the collar, a laurel of white strapping tape round his head, a sweatband on each wrist, a huge silver trophy gripped in one fist and a tennis ball in the other. Green-grey dead skin, heavy jaw, sunken eyes. The SECOND and THIRD figures are a DIFFERENT boss and they are in the reference for ONE reason: their LEGS. Draw TWO frames of THE CHAMPION \u2014 the first figure's face, body, kit, trophy and ball, nobody else's \u2014 walking straight toward the viewer, and copy the LEG AND FOOT POSITIONS of the second and third figures exactly: in each frame one leg strides far forward with the foot flat on the ground and the other trails far behind with the heel lifted, the two shoes WIDE APART with a big empty gap between them, and the forward leg swaps from one frame to the other. Do not put both feet together and do not stand him on one leg. Do not give him the second figure's clothes, tools or face. BOTH FRAMES MUST FACE THE VIEWER HEAD ON: his chest, both shoulders and his whole face square to the camera, both arms visible on either side of his body. Never a side view, never a three-quarter view, never walking across the picture. He is an ENORMOUS heavy-set figure \u2014 do not slim him down. Output exactly two figures in one row."
|
||||
"subject": "The FIRST figure in the reference is THE CHAMPION — the towering dead fourteen-time champion facing the viewer, in a torn all-white tennis kit gone grey and yellow with age, gold trim at the collar, a laurel of white strapping tape round his head, a sweatband on each wrist, a huge silver trophy gripped in one fist and a tennis ball in the other. Green-grey dead skin, heavy jaw, sunken eyes. The SECOND and THIRD figures are a DIFFERENT boss and they are in the reference for ONE reason: their LEGS. Draw TWO frames of THE CHAMPION — the first figure's face, body, kit, trophy and ball, nobody else's — walking straight toward the viewer, and copy the LEG AND FOOT POSITIONS of the second and third figures exactly: in each frame one leg strides far forward with the foot flat on the ground and the other trails far behind with the heel lifted, the two shoes WIDE APART with a big empty gap between them, and the forward leg swaps from one frame to the other. Do not put both feet together and do not stand him on one leg. Do not give him the second figure's clothes, tools or face. BOTH FRAMES MUST FACE THE VIEWER HEAD ON: his chest, both shoulders and his whole face square to the camera, both arms visible on either side of his body. Never a side view, never a three-quarter view, never walking across the picture. He is an ENORMOUS heavy-set figure — do not slim him down. Output exactly two figures in one row."
|
||||
},
|
||||
"racket_play": {
|
||||
"sprites": [
|
||||
"z_r1",
|
||||
"z_r2",
|
||||
"z_r3",
|
||||
"z_r4"
|
||||
],
|
||||
"ref_only": [
|
||||
"z_c1",
|
||||
"o_idle1",
|
||||
"o_run1",
|
||||
"o_swing1"
|
||||
],
|
||||
"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. "
|
||||
},
|
||||
"racket_w1": {
|
||||
"sprites": [
|
||||
"z_rw1",
|
||||
"z_rw1b",
|
||||
"z_rw1s"
|
||||
],
|
||||
"ref_only": [
|
||||
"z_cw1",
|
||||
"o_idle1",
|
||||
"o_run1",
|
||||
"o_swing1"
|
||||
],
|
||||
"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. "
|
||||
},
|
||||
"racket_w2": {
|
||||
"sprites": [
|
||||
"z_rw2",
|
||||
"z_rw2b",
|
||||
"z_rw2s"
|
||||
],
|
||||
"ref_only": [
|
||||
"z_cw2",
|
||||
"o_idle1",
|
||||
"o_run1",
|
||||
"o_swing1"
|
||||
],
|
||||
"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. "
|
||||
},
|
||||
"racket_f_play": {
|
||||
"sprites": [
|
||||
"z_r1_f",
|
||||
"z_r2_f",
|
||||
"z_r3_f",
|
||||
"z_r4_f"
|
||||
],
|
||||
"ref_only": [
|
||||
"z_c1_f",
|
||||
"o_idle1_f",
|
||||
"o_run1_f",
|
||||
"o_swing1_f"
|
||||
],
|
||||
"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. "
|
||||
},
|
||||
"racket_f_w1": {
|
||||
"sprites": [
|
||||
"z_rw1_f",
|
||||
"z_rw1b_f",
|
||||
"z_rw1s_f"
|
||||
],
|
||||
"ref_only": [
|
||||
"z_cw1_f",
|
||||
"o_idle1_f",
|
||||
"o_run1_f",
|
||||
"o_swing1_f"
|
||||
],
|
||||
"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. "
|
||||
},
|
||||
"racket_f_w2": {
|
||||
"sprites": [
|
||||
"z_rw2_f",
|
||||
"z_rw2b_f",
|
||||
"z_rw2s_f"
|
||||
],
|
||||
"ref_only": [
|
||||
"z_cw2_f",
|
||||
"o_idle1_f",
|
||||
"o_run1_f",
|
||||
"o_swing1_f"
|
||||
],
|
||||
"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. "
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -219,16 +219,20 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
|
||||
letter-spacing: 1px; }
|
||||
/* a row, not a stacked tile: three 3:2 tiles stacked fill a phone twice over, and the art still
|
||||
reads at this size. -webkit-tap-highlight-color kills iOS's blue flash over the pixel art. */
|
||||
#courtList button.court { display: flex; align-items: center; gap: 11px; width: 100%;
|
||||
/* MODE tiles reuse the court row wholesale — same box, same selected state. Only the picture
|
||||
differs: a court tile is a photo of a court and crops fine, a mode tile is a SPRITE and must be
|
||||
shown whole, so it gets `contain` and a dark plate to stand on. */
|
||||
#modeList img { object-fit: contain !important; background: rgba(0,0,0,0.35); }
|
||||
#courtList button.court, #modeList button.court { display: flex; align-items: center; gap: 11px; width: 100%;
|
||||
margin: 0 0 8px; padding: 7px; background: var(--panel);
|
||||
border: 2px solid var(--line); color: inherit; font: inherit; text-align: left;
|
||||
cursor: pointer; -webkit-tap-highlight-color: transparent; }
|
||||
#courtList button.court.on { border-color: var(--acid); background: rgba(188,212,85,0.09); }
|
||||
#courtList img { width: 92px; height: 66px; display: block; image-rendering: pixelated; flex: none;
|
||||
#courtList button.court.on, #modeList button.court.on { border-color: var(--acid); background: rgba(188,212,85,0.09); }
|
||||
#courtList img, #modeList img { width: 92px; height: 66px; display: block; image-rendering: pixelated; flex: none;
|
||||
object-fit: cover; }
|
||||
#courtList .cb { flex: 1; min-width: 0; }
|
||||
#courtList b { display: block; font: 400 12px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; }
|
||||
#courtList i { display: block; margin: 3px 0 6px; font: 400 9px Silkscreen, monospace; color: var(--dim); font-style: normal; }
|
||||
#courtList .cb, #modeList .cb { flex: 1; min-width: 0; }
|
||||
#courtList b, #modeList b { display: block; font: 400 12px Silkscreen, monospace; color: var(--cream); letter-spacing: 0.5px; }
|
||||
#courtList i, #modeList i { display: block; margin: 3px 0 6px; font: 400 9px Silkscreen, monospace; color: var(--dim); font-style: normal; }
|
||||
/* The two meters read straight off the court's own bounce numbers (see main.js), so they cannot
|
||||
drift away from what the ball actually does on it. */
|
||||
.meter { display: flex; align-items: center; gap: 6px; margin-top: 4px;
|
||||
@@ -352,9 +356,11 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
|
||||
adding either is a table row, never markup -->
|
||||
<div id="setup">
|
||||
<div class="hdr"><button class="chev" id="sBack">‹</button><h2>MATCH SETUP</h2></div>
|
||||
<h3>01 · PLAYER</h3>
|
||||
<h3>01 · MODE</h3>
|
||||
<div id="modeList"></div>
|
||||
<h3>02 · PLAYER</h3>
|
||||
<div id="tours"></div>
|
||||
<h3>02 · COURT</h3>
|
||||
<h3>03 · COURT</h3>
|
||||
<div id="courtList"></div>
|
||||
<div class="foot">
|
||||
<p id="sSum"></p>
|
||||
@@ -416,6 +422,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one') {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script type="module" src="src/main.js?v=178"></script>
|
||||
<script type="module" src="src/main.js?v=179"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -31,6 +31,12 @@ export const TUNE = {
|
||||
// faces an opponent that visibly starts falling apart rather than a wall.
|
||||
aiQualityMin: 0.45, aiQualityMax: 0.72, aiFlub: 0.18,
|
||||
aiFlubLoss: 0.08,
|
||||
// ...and in CLASSIC TENNIS the same CPU has to last a whole match rather than one game, so the
|
||||
// rubber band is turned off there (aiFlubLoss would have him in pieces by the second set) and the
|
||||
// cap is raised: a mode whose whole promise is "real tennis" cannot be won by attrition.
|
||||
classicSets: 2, // sets to win the match — best of three
|
||||
classicQualityMax: 0.86,
|
||||
classicFlub: 0.10,
|
||||
aiReaction: 0.45, // s before the CPU reads your shot — well-aimed corners are winners
|
||||
autoAssist: matchMedia('(pointer: coarse)').matches ? 1.15 : 0, // auto-run speed factor (mobile)
|
||||
// ---- THE SIDESTEP. Free walking stays 'rally'-only (see the movement block in gameplay), which
|
||||
@@ -485,6 +491,9 @@ export const APPLAUSE_T = 4.2;
|
||||
// It is deliberately long. Oliver: "the movies surround and bite them, blood spills, and then the
|
||||
// person basically drowns in the zombies" — that cannot happen in half a second.
|
||||
export const EATEN_BURST = 2.3, EATEN_SUMMARY = 3.6, EATEN_RESTART = 4.6;
|
||||
// ...and the same two beats for the ending with no corpse in it (a classic match played out). It is
|
||||
// shorter because there is no animation to sit through — only the crowd finishing, and the summary.
|
||||
export const DONE_RESTART = 2.0;
|
||||
export const EATEN_FEED_R = 1.15; // m — how tight the feeding ring packs around the body
|
||||
|
||||
// UI accent colours, one place so the whole HUD can be re-tuned at once. Deliberately
|
||||
@@ -539,6 +548,19 @@ export const COURTS = [
|
||||
// dx/apex are optional and override BOUNCE_IDLE's pair: she reaches further out and higher than he
|
||||
// does, so the pre-serve ball has to meet a different palm. Same rule as BOUNCE_IDLE — measured off
|
||||
// the drawn hand by eye, not calculated.
|
||||
// THE THREE MODES, picked before a run and nowhere else. Pure DATA, like TOURS and COURTS: adding
|
||||
// one is a row here plus its dispatch line in main.start(), never markup.
|
||||
// classic — real tennis, best of TUNE.classicSets sets, nothing ever turns
|
||||
// zombie — the exhibition match (beats.startMatch): one game per opponent, blood only
|
||||
// gore — the original: the opening match TURNS and you survive what walks on
|
||||
// `tile` is an existing sprite rather than new art on purpose — each one is the thing you will be
|
||||
// looking at for the whole mode, which is a better advert than a drawn icon of it.
|
||||
export const MODES = [
|
||||
{ id: 'classic', name: 'CLASSIC TENNIS', sub: 'REAL TENNIS · BEST OF THREE SETS', tile: 'o_swing1' },
|
||||
{ id: 'zombie', name: 'ZOMBIE TENNIS', sub: 'ONE GAME PER OPPONENT · BLOOD ONLY', tile: 'z_r1' },
|
||||
{ id: 'gore', name: 'SPLATTER GORE', sub: 'THE MATCH TURNS · SURVIVE IT', tile: 'z_boss1' },
|
||||
];
|
||||
|
||||
export const TOURS = [
|
||||
{ id: 'men', name: "MEN'S SINGLES", tile: 'tour_m', sfx: null },
|
||||
{ id: 'women', name: "WOMEN'S SINGLES", tile: 'tour_w', sfx: '_f', dx: 0.46, apex: 0.78 },
|
||||
@@ -666,7 +688,7 @@ export const ENEMIES = {
|
||||
// per run, and he is NOT the racket zombie below — that one keeps coming back. Missing this row
|
||||
// is what put a second "SHAMBLER" on the screen: an unmapped key falls back to the shambler art.
|
||||
c: { name: 'THE OPPONENT', spr: 'z_c1', sub: 'HE TURNED MID-MATCH' },
|
||||
r: { name: 'THE CLUB PRO', spr: 'z_c1', sub: 'STILL HAS A BACKHAND' },
|
||||
r: { name: 'THE CLUB PRO', spr: 'z_r1', sub: 'STILL HAS A BACKHAND' },
|
||||
m: { name: 'THE BALL MACHINE', spr: 'z_mach1', sub: 'FIRES BACK · FURNITURE' },
|
||||
};
|
||||
for (let i = 0; i < BOSS_ART.length; i++) // the chapter bosses, named where they already are
|
||||
|
||||
@@ -6,6 +6,7 @@ import { audio, pock, swish, whoosh, applause, voice, sfx, aww, zombieMusic, zom
|
||||
import { axisX, axisZ, takeFlickAim, touchPX, resetInput } from './input.js';
|
||||
import { W } from './render.js'; // runtime-only cycle (render imports gameplay), same pattern as input/zombies
|
||||
import { updateDrill } from './drill.js';
|
||||
import { endRun, beginRun, MODE_CLASSIC } from './stats.js';
|
||||
import { updateZombies, updateParts, spawnZombie, spawnRacketZombie, spawnMachine, spawnChapterBoss, zombies, gore, explode, meleeSwipe, extras, parts, pellets, shots, playerGore, eatenBleed, resetZombies , firePellet , spawnBarrel , fireBeam , pops, popText } from './zombies.js';
|
||||
import { proceedAfterClear, startDuel, startHorde, warnHorde, resolveInterlude, watchdog } from './beats.js'; // runtime-only cycle: beats calls back into cheer/aside/endBurst/deliverTin/showModal/logSwing
|
||||
|
||||
@@ -485,10 +486,13 @@ function pointTo(side, reason) {
|
||||
if (side === 'O') aww(0.8); // you dropped the point — the crowd sighs
|
||||
if (reason) voice(reason);
|
||||
if (gameOver) {
|
||||
if (G.mode === 'tennis' && side === 'P' && !G.everTransitioned) return startTransition();
|
||||
// ...unless this is CLASSIC TENNIS, where nothing turns and the first game you win is just the
|
||||
// first game you win. That check is the whole of the mode's isolation from the gore path.
|
||||
if (G.mode === 'tennis' && side === 'P' && !G.everTransitioned && !G.classic) return startTransition();
|
||||
voice(side === 'P' ? 'game_player' : 'game_opponent', 0.7);
|
||||
cheer(2.8, 0.6);
|
||||
score.server = other(score.server);
|
||||
if (G.classic) { G.runGames++; if (classicGame(side)) return; } // ...then a set, then the match
|
||||
} else {
|
||||
voice(scoreKey(), 0.7);
|
||||
if (side === 'P') cheer(1.2, 0.3);
|
||||
@@ -496,6 +500,44 @@ function pointTo(side, reason) {
|
||||
G.serveNum = 1;
|
||||
}
|
||||
|
||||
// CLASSIC TENNIS: a game has just been banked by advancePoint — is it also a set, and is the set
|
||||
// also the match? Returns true when it ended the match, so pointTo stops handing the point flow on.
|
||||
// Six games AND a two-game lead, the real rule; no tiebreak, so 6-6 simply plays on to 8-6. That is
|
||||
// the one simplification here and it is deliberate — a tiebreak is a different scoring mode bolted
|
||||
// onto a mode that is not yet proven, and 7-5 sets are not what anybody is complaining about.
|
||||
// ponytail: add the tiebreak when a real match actually stalls at 6-6.
|
||||
// Exported for the suite: the whole of a mode's scoring rule is worth pinning down, and the only
|
||||
// other way in is winning twelve games through real rallies.
|
||||
export function classicGame(side) {
|
||||
const i = side === 'P' ? 0 : 1, j = 1 - i;
|
||||
if (score.games[i] < 6 || score.games[i] - score.games[j] < 2) return false;
|
||||
G.sets[i]++; score.games = [0, 0];
|
||||
const mine = i === 0;
|
||||
if (G.sets[i] >= TUNE.classicSets) { endClassic(mine); return true; }
|
||||
G.card = { title: 'SET ' + (G.sets[0] + G.sets[1]), sub1: mine ? 'THE SET IS YOURS' : 'SET TO THEM',
|
||||
color: mine ? UI.pick : UI.hot, t: TUNE.setCardT };
|
||||
G.overT = Math.max(G.overT, TUNE.setCardT);
|
||||
return false;
|
||||
}
|
||||
|
||||
// The match is over and NOBODY DIED — the one end-of-run state that is not a corpse. It reuses the
|
||||
// death screen's whole shape (a held summary, then a gated tap that restarts) because that is the
|
||||
// only thing about the two endings that is the same; the words, the colour and the still-standing
|
||||
// player are all its own. update() freezes on G.done, exactly as it does on G.mode === 'eaten'.
|
||||
export function endClassic(won) {
|
||||
if (G.done) return;
|
||||
G.done = { won, t: 0 };
|
||||
ball.active = false; G.flash = null; G.modal = null; G.card = null;
|
||||
if (won) { cheer(4, 1); applause(1, 0.2); voice('unbelievable', 0.4); }
|
||||
else { aww(1); voice('game_opponent', 0.3); }
|
||||
// g = GAMES PLAYED, s = SETS YOU WON — this mode's two headline numbers in the record's two slots.
|
||||
// `dead` carries the RESULT: a match you lost is the run ending badly, a match you won is not,
|
||||
// so the stats screen's DEATHS column reads as matches lost and (runs − deaths) as matches won,
|
||||
// with no extra field to keep in step.
|
||||
const b = endRun(G.runGames, G.sets[0], G.splatT, !won, MODE_CLASSIC);
|
||||
G.best = b; G.newBest = b.newBest;
|
||||
}
|
||||
|
||||
// splatter-mode scoring: points land mid-flight without interrupting play.
|
||||
// quiet (during a horde) rate-limits the umpire so he doesn't call every rapid-fire point.
|
||||
// The scoreboard IS the progression: games drive spawn pressure, 6 games = a set = a horde,
|
||||
@@ -752,6 +794,7 @@ const xLimit = () => Math.max(xVisible(), COURT.W / 2);
|
||||
// back themselves, so nothing here has to know the shape of any of it.
|
||||
export function restartRun() {
|
||||
resetZombies(); resetInput(); resetState(); setupPoint();
|
||||
beginRun(); // ...and the stats bag, which is the only state that does not live on G
|
||||
}
|
||||
|
||||
export function forceZombies() {
|
||||
@@ -1230,6 +1273,16 @@ function mopRound(b, dt) {
|
||||
// ---------------------------------------------------------------- update ----
|
||||
export function update(dt) {
|
||||
if (G.hitstop > 0) { G.hitstop -= dt; return; }
|
||||
// THE OTHER ENDING: a classic match played out. The world holds still — the man is standing, the
|
||||
// crowd is still clapping it down — and the only thing running is the clock the summary and its
|
||||
// restart tap are gated on. Same shape as the block below, without a corpse in it.
|
||||
if (G.done) {
|
||||
G.idleT += dt; G.done.t += dt;
|
||||
if (G.done.t >= EATEN_SUMMARY && !G.done.handed) { G.done.handed = true; menuDuck(false); }
|
||||
crowd.cheer = Math.max(0, crowd.cheer - dt);
|
||||
if (G.card && (G.card.t -= dt) <= 0) G.card = null;
|
||||
return;
|
||||
}
|
||||
if (G.mode === 'eaten') { // the match is over in the truest sense
|
||||
G.idleT += dt;
|
||||
const was = G.eatenT; G.eatenT += dt;
|
||||
@@ -1470,11 +1523,15 @@ export function update(dt) {
|
||||
&& ball.y < CONTACT.maxY && ball.y > CONTACT.minY && ball.vz < 0;
|
||||
if (near) {
|
||||
// rubber band: every game HE has taken makes him flub more — the opening match must not
|
||||
// be a wall a new player grinds against for rounds (see aiFlubLoss in config)
|
||||
if (Math.random() < TUNE.aiFlub + score.games[1] * TUNE.aiFlubLoss) G.aiSwingCool = 0.5; // whiff: hesitates and misses
|
||||
// be a wall a new player grinds against for rounds (see aiFlubLoss in config).
|
||||
// CLASSIC TENNIS turns the band OFF and flubs less: the band exists to get a new player
|
||||
// PAST the opener, and a mode whose whole promise is a real match cannot be won by an
|
||||
// opponent that falls apart the moment he goes ahead.
|
||||
const flub = G.classic ? TUNE.classicFlub : TUNE.aiFlub + score.games[1] * TUNE.aiFlubLoss;
|
||||
if (Math.random() < flub) G.aiSwingCool = 0.5; // whiff: hesitates and misses
|
||||
else {
|
||||
O.swingT = TUNE.swingWindup + TUNE.swingWindow / 2;
|
||||
trySwing(O, true); O.swingT = -1;
|
||||
trySwing(O, true, G.classic ? TUNE.classicQualityMax : TUNE.aiQualityMax); O.swingT = -1;
|
||||
G.aiSwingCool = ball.lastHit === 'O' ? 0.4 : 0.12;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Module map: config (tuning/constants) · state (mutable game state) · gameplay (logic/update)
|
||||
// render (camera/drawing) · input (keys/touch) · audio (sfx/umpire) · panel (T tuning UI)
|
||||
|
||||
import { TUNE, COURTS, TOURS, EATEN_RESTART, WEAPONS, bossArt } from './config.js';
|
||||
import { TUNE, COURTS, TOURS, MODES, EATEN_RESTART, DONE_RESTART, WEAPONS, bossArt } from './config.js';
|
||||
import { P, O, ball, score, G, setupPoint, selectCourt, selectTour } from './state.js';
|
||||
import { update, restartRun, keyPressed, solveShot, inServeBox, inCourt, forceZombies, splatPoint, deliverTin, selectWeapon, grantWeapon, showModal, dismissModal, flickTarget, dragServe, toggleTestMode } from './gameplay.js';
|
||||
import { startDuel, resolveInterlude, startBossFight, endBossFight, startDrill, endDrill, startMatch, endMatch } from './beats.js';
|
||||
@@ -72,6 +72,26 @@ let picked = remembered('court') || COURTS[0].id;
|
||||
let pickedTour = remembered('tour') || TOURS[0].id;
|
||||
const go = stage => { intro.dataset.stage = stage; menuMusic(); }; // every stage change is a gesture, so it is also a safe place to (re)start the theme
|
||||
|
||||
// --- MODE tiles, built from config.MODES. The setup screen now picks WHAT, WHO and WHERE, and this
|
||||
// is the first of the three because it is the one that changes the other two's meaning. Same
|
||||
// "tap selects, SERVE UP starts" rule as everything else on the screen; the row markup is the court
|
||||
// row's, reused wholesale (see the shared selectors in index.html).
|
||||
let pickedMode = remembered('mode') || MODES[0].id;
|
||||
const modeList = document.getElementById('modeList');
|
||||
for (const m of MODES) {
|
||||
const b = document.createElement('button');
|
||||
b.className = 'court' + (m.id === pickedMode ? ' on' : '');
|
||||
b.innerHTML = `<img src="assets/${m.tile}.png?v=${SPRV}" alt=""><span class="cb">`
|
||||
+ `<b>${m.name}</b><i>${m.sub}</i></span>`;
|
||||
b.addEventListener('click', () => {
|
||||
pickedMode = m.id;
|
||||
try { localStorage.setItem('mode', m.id); } catch {} // come back to what you were playing
|
||||
for (const el of modeList.children) el.classList.toggle('on', el === b);
|
||||
summary();
|
||||
});
|
||||
modeList.appendChild(b);
|
||||
}
|
||||
|
||||
// --- tour tiles, built from the table. Same "tap selects, SERVE UP starts" rule as the court rows —
|
||||
// the setup screen picks WHO and WHERE, and nothing on it commits you.
|
||||
const tourList = document.getElementById('tours');
|
||||
@@ -120,10 +140,16 @@ for (const c of COURTS) {
|
||||
function summary() {
|
||||
const t = TOURS.find(x => x.id === pickedTour) || TOURS[0];
|
||||
const c = COURTS.find(x => x.id === picked) || COURTS[0];
|
||||
const best = stats.total().best;
|
||||
const m = MODES.find(x => x.id === pickedMode) || MODES[0];
|
||||
// the mark to beat is the PICKED MODE's own, because the three of them do not measure the same
|
||||
// thing — see the record-shape note in stats.endRun
|
||||
const mode = m.id === 'zombie' ? stats.MODE_MATCH : m.id === 'classic' ? stats.MODE_CLASSIC : stats.MODE_GORE;
|
||||
const best = stats.read('all', undefined, mode).longest;
|
||||
const unit = m.id === 'zombie' ? (best === 1 ? ' FELLED' : ' FELLED')
|
||||
: best === 1 ? ' GAME' : ' GAMES';
|
||||
document.getElementById('sSum').innerHTML =
|
||||
`<span>${t.name.replace(' SINGLES', '')} · ${c.name}</span>`
|
||||
+ `<span>${best ? best + (best === 1 ? ' GAME' : ' GAMES') + ' TO BEAT' : 'FIRST RUN'}</span>`;
|
||||
`<span>${m.name} · ${t.name.replace(' SINGLES', '')} · ${c.name}</span>`
|
||||
+ `<span>${best ? best + unit + ' TO BEAT' : 'FIRST RUN'}</span>`;
|
||||
}
|
||||
|
||||
// The splash carries ONE number, on the STATS button. A boxed BEST RUN / WORLD RANK bar across the
|
||||
@@ -141,6 +167,12 @@ function start() {
|
||||
selectCourt(picked);
|
||||
menuDuck(true); // the theme belongs to the menus — hand the court over to the ambience
|
||||
intro.hidden = true; ambient(); voice('quiet_please'); // low atmosphere bed starts with the first gesture
|
||||
// ...and the mode the setup screen picked. THREE LINES, because that is genuinely all the modes
|
||||
// differ by at this point: gore is the game as it always was, classic is the same tennis with the
|
||||
// turn switched off, and zombie tennis is the match taking the court. Everything else about a mode
|
||||
// lives in the code that reads G.classic / G.match, never here.
|
||||
G.classic = pickedMode === 'classic';
|
||||
if (pickedMode === 'zombie') { intoSplatter(); startMatch(); }
|
||||
}
|
||||
let stPeriod = 'all';
|
||||
const openStats = () => { stats.drawStats(stPeriod, SPRV); go('stats'); };
|
||||
@@ -330,7 +362,9 @@ addEventListener('pagehide', () => {
|
||||
// the theme restarted from silence. restartRun puts every bag back from a pristine copy, and the
|
||||
// bed that has been playing under the death summary simply carries on into the title screen.
|
||||
const maybeRestart = () => {
|
||||
if (G.modal || G.mode !== 'eaten' || G.eatenT <= EATEN_RESTART) return;
|
||||
// ...and the classic ending taps out the same way, on its own shorter clock (G.done, no corpse)
|
||||
const ready = G.done ? G.done.t > DONE_RESTART : G.mode === 'eaten' && G.eatenT > EATEN_RESTART;
|
||||
if (G.modal || !ready) return;
|
||||
restartRun();
|
||||
refreshSplash(); // the run just ended: the splash count has moved
|
||||
intro.hidden = false;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Camera, viewport, sprites and all drawing. Owns the crowd dots (visual-only state).
|
||||
|
||||
import { cv, ctx } from './dom.js';
|
||||
import { TUNE, UI, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW, TOSS } from './config.js';
|
||||
import { TUNE, UI, EATEN_BURST, EATEN_SUMMARY, EATEN_RESTART, DONE_RESTART, COURT, P_BOUNDS, PLAYER_H, BOY_H, UMP_H, UMP_X, MACH_H, BOSS_ART, ZWOUND, woundStage, BOUNCE_IDLE, SPRITE_H, zombieH , WEAPONS, RACK_ROW, TOSS } from './config.js';
|
||||
import { P, O, ball, score, crowd, G, court, tour } from './state.js';
|
||||
import { predictLanding, previewServe, slotId, slotStock, serveApexY } from './gameplay.js';
|
||||
import { drillQueue, drillLegal, drillMult } from './drill.js';
|
||||
@@ -195,7 +195,7 @@ export function proj(x, y, z) {
|
||||
// Asset cache-buster — bump with main.js?v=N (see the img.src note below). EXPORTED because the
|
||||
// menu screens hang <img> tags on the same files, and two copies of this number is one copy too
|
||||
// many: the one that does not get bumped is the one that serves a cached 404.
|
||||
export const SPRV = 91;
|
||||
export const SPRV = 92;
|
||||
// The boot bar in main.js watches this. Nothing here CHANGES when things load — every sprite was
|
||||
// already requested at import — it just makes the wait visible and holds the menu back until the
|
||||
// last sheet has landed. See the onerror note below for the other half of "sometimes missing".
|
||||
@@ -238,6 +238,11 @@ for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','
|
||||
'z_s1','z_s2','z_s3','z_s4','z_sdown', // the chair spectator: 4-frame shuffle + the staggered pose
|
||||
'z_c3','z_c4', // ...and the turned CPU walks on four frames too
|
||||
'z_cw1','z_cw2','z_aw','z_bw', // wounded skins for multi-hit enemies (racket boss, brute, and now the classic shamblers)
|
||||
// THE MATCH OPPONENT, drawn to play tennis rather than to shamble: ready stance,
|
||||
// shuffle pair, forehand — and the same three poses again at each wound stage
|
||||
// (…s is the swing). Its own family, so the turned CPU above keeps its shamble.
|
||||
'z_r1','z_r2','z_r3','z_r4',
|
||||
'z_rw1','z_rw1b','z_rw1s','z_rw2','z_rw2b','z_rw2s',
|
||||
'w_ball','w_bomb','w_triple','w_fire','w_gun', // weapon-rack icons
|
||||
'w_beacon','w_laser','w_rocket','w_flamer', // ...and the four that come out of a barrel
|
||||
'z_barrel1','z_barrel2', // the weapon barrel, two frames so it ROLLS
|
||||
@@ -256,6 +261,8 @@ for (const n of ['p_idle1','p_idle2','p_bounce','p_bounce2','p_toss','p_smash','
|
||||
'o_idle1_f','o_idle2_f','o_bounce_f','o_bounce2_f','o_toss_f','o_smash_f',
|
||||
'o_run1_f','o_run2_f','o_swing1_f','o_swing2_f',
|
||||
'z_c1_f','z_c2_f','z_c3_f','z_c4_f','z_cw1_f','z_cw2_f','z_cw1b_f','z_cw2b_f',
|
||||
'z_r1_f','z_r2_f','z_r3_f','z_r4_f',
|
||||
'z_rw1_f','z_rw1b_f','z_rw1s_f','z_rw2_f','z_rw2b_f','z_rw2s_f',
|
||||
'scoreboard']) {
|
||||
const img = new Image();
|
||||
// ?v=SPRV, for the same reason index.html versions main.js. It is also what buys the year-long
|
||||
@@ -561,14 +568,25 @@ function drawZombie(zb) {
|
||||
if (zb.variant === 'o') return drawBarrel(zb);
|
||||
if (zb.variant === 'm') return drawMachine(zb);
|
||||
const rk = zb.variant === 'r';
|
||||
const v = rk ? 'c' : zb.variant; // the racket zombie reuses the turned-CPU sprite (already holds a racket)
|
||||
// THE MATCH OPPONENT HAS ITS OWN SPRITES NOW. It used to borrow the turned CPU's ('c') — a body
|
||||
// drawn to SHAMBLE at the camera with its racket hanging at its side, which is what was playing
|
||||
// tennis points against you. The 'r' family is drawn off the LIVING opponent's poses instead (a
|
||||
// ready stance, a shuffle pair and a real forehand, at every wound stage). 'c' keeps its shamble
|
||||
// untouched, because in the gore mode shambling is exactly what the turned CPU should be doing.
|
||||
const v = rk ? (SPR.z_r1 ? 'r' : 'c') : zb.variant; // 'c' until the new sheets have landed
|
||||
const rNew = rk && v === 'r';
|
||||
let N = ZFRAMES[v] || 2;
|
||||
if (!SPR['z_' + v + N]) N = 2; // frames still loading (or sheet rejected): 2-frame fallback
|
||||
// same CYCLE frequency as before — more frames subdivide the stride, they don't speed it up
|
||||
// The racket zombie holds a position and only moves when the ball makes him, so a time-driven
|
||||
// cycle had him flicking between two frames on the spot. His stride steps off ground covered like
|
||||
// the brute's — standing still is standing still — and his swing keeps its own frame.
|
||||
let frame = rk && zb.pose === 'swing' ? 2
|
||||
// The 'r' family's own cycle: 1 = the ready stance, held whenever racketAI is not running him;
|
||||
// 2/3 = the shuffle; 4 = the forehand. `pose` is racketAI's own signal, so the picture and the
|
||||
// behaviour cannot drift.
|
||||
let frame = rNew ? (zb.pose === 'swing' ? 4
|
||||
: zb.pose === 'run' ? stepFrame((zb.dist || 0) / TUNE.racketStride, 2) + 2 : 1)
|
||||
: rk && zb.pose === 'swing' ? 2
|
||||
: rk ? stepFrame((zb.dist || 0) / TUNE.racketStride, N) + 1
|
||||
: ZSTRIDE[v] ? stepFrame(zb.z / (ZSTRIDE[v] * 2 / N), N) + 1 // heaviest bodies: step off DISTANCE
|
||||
// WALKED, like their wound lurch below,
|
||||
@@ -608,10 +626,22 @@ function drawZombie(zb) {
|
||||
// boss looking untouched until the killing blow. Keep these in step with bleed()'s anchors.
|
||||
else if (rk) {
|
||||
const f = zb.hp / (zb.hpMax || TUNE.racketHp);
|
||||
if (f <= 0.34 && SPR.z_cw2) { name = 'z_cw2'; h = 1.52; } // headless: a head shorter, so the shoulders land where a whole zombie's do
|
||||
else if (f <= 0.67 && SPR.z_cw1) name = 'z_cw1';
|
||||
const b = name + 'b'; // ...and he limps through his wounds too, instead of gliding
|
||||
if (name !== 'z_' + v + frame && SPR[b] && stepFrame(zb.walkT * 5.2, 2)) name = b;
|
||||
const st = f <= 0.34 ? 2 : f <= 0.67 ? 1 : 0; // 0 unhurt, 1 arm off, 2 headless
|
||||
if (st === 2) h = 1.52; // headless: a head shorter, so the shoulders land where a whole zombie's do
|
||||
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
|
||||
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'
|
||||
: 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
|
||||
if (st === 2 && SPR.z_cw2) name = 'z_cw2';
|
||||
else if (st === 1 && SPR.z_cw1) name = 'z_cw1';
|
||||
const b = name + 'b'; // ...and he limps through his wounds too, instead of gliding
|
||||
if (name !== 'z_' + v + frame && SPR[b] && stepFrame(zb.walkT * 5.2, 2)) name = b;
|
||||
}
|
||||
}
|
||||
// The chapter boss comes apart through the SAME fraction-of-hpMax rule as the racket zombie, over
|
||||
// three stages, so a 34 hp chapter-4 boss visibly degrades all the way down: arm off, then ribs
|
||||
@@ -2052,11 +2082,13 @@ export function render() {
|
||||
ctx.textAlign = 'left'; ctx.font = F(8, svr); ctx.fillStyle = svr ? bd.cream : bd.dim;
|
||||
ctx.fillText(names[i], 18, cy);
|
||||
ctx.textAlign = 'center';
|
||||
if (splat) { ctx.font = F(8, 0); ctx.fillStyle = bd.dim; ctx.fillText(String(G.sets[i]), 74, cy); } // sets
|
||||
// ...and CLASSIC TENNIS shows them too: it is the one mode where a set is the thing you are
|
||||
// actually playing for, and hiding the column left a match-scoring mode reading 0-0 all match.
|
||||
if (splat || G.classic) { ctx.font = F(8, 0); ctx.fillStyle = bd.dim; ctx.fillText(String(G.sets[i]), 74, cy); } // sets
|
||||
ctx.font = F(8); ctx.fillStyle = bd.cream; ctx.fillText(String(score.games[i]), 90, cy); // games
|
||||
ctx.font = F(8); ctx.fillStyle = svr ? bd.gold : bd.cream; ctx.fillText(ptTxt(i), 126, cy); // points, in the art's slot
|
||||
}
|
||||
if (splat) {
|
||||
if (splat || G.classic) {
|
||||
// This row used to be bare text on the court. That was fine over one dark green lawn and is
|
||||
// unreadable over a sunlit clay crowd or a floodlit blue one, so it gets its own panel — the
|
||||
// same trick the scoreboard art above it already relies on.
|
||||
@@ -2071,12 +2103,15 @@ export function render() {
|
||||
// ...and in the MATCH the run is not measured in games at all (blood-only scoring): the ladder
|
||||
// rung you are on and the bodies behind you are what the player is playing for, so this slot
|
||||
// prints those instead. Same slot, same size — the mode changes the words, not the furniture.
|
||||
// ...and in CLASSIC it says how far through the MATCH you are, which is the one thing the
|
||||
// board itself cannot: which set this is, and how many it takes to win.
|
||||
ctx.fillText(G.match ? `OPPONENT ${G.match.opp} · ${G.match.opp - 1} FELLED`
|
||||
: G.classic ? `SET ${G.sets[0] + G.sets[1] + 1} · FIRST TO ${TUNE.classicSets}`
|
||||
: `GAME ${G.runGames + 1} · ${G.sets[0]} SET${G.sets[0] === 1 ? '' : 'S'}`, bW - 3, bH + 8);
|
||||
}
|
||||
// ...and NOT during a match: nothing on that court is killed for points, so the pips were both a
|
||||
// lie and a collision — 'NEXT ○○' ran straight into the OPPONENT line sharing the panel.
|
||||
if (splat && !G.match && TUNE.killPips && TUNE.killsPerPoint > 1) { // kills-to-next-point pips, on the panel above
|
||||
if (splat && !G.match && !G.classic && TUNE.killPips && TUNE.killsPerPoint > 1) { // kills-to-next-point pips, on the panel above
|
||||
ctx.textAlign = 'left'; ctx.font = F(7, 0); ctx.fillStyle = bd.dim; ctx.fillText('NEXT', 4, bH + 8);
|
||||
for (let k = 0; k < TUNE.killsPerPoint; k++) {
|
||||
ctx.beginPath(); ctx.arc(34 + k * 8, bH + 8, 2.4, 0, 7);
|
||||
@@ -2090,34 +2125,48 @@ export function render() {
|
||||
if (G.mode === 'splatter' && !G.interlude && !G.drill) drawRack(); // courtside weapon rack (hidden during the tennis-rules duel AND the drill, which is played with plain balls)
|
||||
drawDrillHud(); // the triage readout — no-op unless a drill is running
|
||||
drawApproachRing(); drawApexBand(); // the match's timing, drawn — no-ops unless a match is running
|
||||
// phase C: the summary fades UP over the death animation instead of cutting on top of it
|
||||
if (G.mode === 'eaten' && G.eatenT > EATEN_SUMMARY) {
|
||||
const fade = Math.min(1, (G.eatenT - EATEN_SUMMARY) / 0.6);
|
||||
ctx.save(); ctx.globalAlpha = fade;
|
||||
ctx.fillStyle = 'rgba(10,4,6,0.72)'; ctx.fillRect(0, 0, W, H);
|
||||
// The announcement face, at 26 rather than the card's 30: this is the longest string in the game
|
||||
// and at 30 it ran edge to edge on a 270px-wide portrait canvas.
|
||||
// The match bled to death rather than being eaten, and it counts a different thing — see the
|
||||
// matchBest block in killPlayer. Same three lines, its own words: the measure is bodies felled.
|
||||
// THE END OF A RUN, whichever way it ended. Three modes end three different ways and they share
|
||||
// one screen — a wash, a headline, the run's own two numbers, the mark to beat and the gated tap
|
||||
// — because only the WORDS differ, and three copies of this drift apart the first time one moves.
|
||||
// eaten + gore GAME, SET, MASSACRE. n games, n sets
|
||||
// eaten + match BLED OUT. n opponents felled, n games
|
||||
// done + classic MATCH. / BEATEN. the set score
|
||||
// phase C for the death: the summary fades UP over the animation instead of cutting on top of it.
|
||||
{
|
||||
const m = G.match && G.match.felled !== undefined ? G.match : null;
|
||||
ctx.font = B(26);
|
||||
shadowText(m ? 'BLED OUT.' : 'GAME, SET, MASSACRE.', W / 2, H / 2 - 44, UI.bad);
|
||||
ctx.font = F(9);
|
||||
shadowText(m ? 'FELLED ' + m.felled + ' OPPONENT' + (m.felled === 1 ? '' : 'S')
|
||||
+ ' · ' + m.games + ' GAMES'
|
||||
: 'SURVIVED ' + G.runGames + ' GAMES · ' + G.sets[0] + ' SETS', W / 2, H / 2 - 14, UI.cream);
|
||||
if (G.newBest) { // a fresh record crows; otherwise show the mark to beat
|
||||
const pulse = 0.55 + 0.45 * Math.abs(Math.sin(G.eatenT * 4));
|
||||
ctx.font = B(20);
|
||||
shadowText('★ NEW BEST ★', W / 2, H / 2 + 2, hexA(UI.warm, pulse));
|
||||
} else if (m ? m.best > 0 : (G.best && G.best.games > 0)) {
|
||||
ctx.font = F(8);
|
||||
shadowText(m ? 'BEST ' + m.best + ' FELLED'
|
||||
: 'BEST ' + G.best.games + ' GAMES · ' + G.best.sets + ' SETS', W / 2, H / 2 + 4, UI.dim);
|
||||
const dead = G.mode === 'eaten' && G.eatenT > EATEN_SUMMARY, done = G.done && G.done.t > 0.5;
|
||||
if (dead || done) {
|
||||
const clk = dead ? G.eatenT - EATEN_SUMMARY : G.done.t - 0.5;
|
||||
const fade = Math.min(1, clk / 0.6);
|
||||
const won = !dead && G.done.won;
|
||||
ctx.save(); ctx.globalAlpha = fade;
|
||||
ctx.fillStyle = won ? 'rgba(6,10,8,0.72)' : 'rgba(10,4,6,0.72)'; ctx.fillRect(0, 0, W, H);
|
||||
// The announcement face, at 26 rather than the card's 30: this is the longest string in the
|
||||
// game and at 30 it ran edge to edge on a 270px-wide portrait canvas.
|
||||
const title = dead ? (m ? 'BLED OUT.' : 'GAME, SET, MASSACRE.') : won ? 'GAME, SET, MATCH.' : 'BEATEN.';
|
||||
const line = dead
|
||||
? (m ? 'FELLED ' + m.felled + ' OPPONENT' + (m.felled === 1 ? '' : 'S') + ' · ' + m.games + ' GAMES'
|
||||
: 'SURVIVED ' + G.runGames + ' GAMES · ' + G.sets[0] + ' SETS')
|
||||
: G.sets[0] + '–' + G.sets[1] + ' IN SETS · ' + G.runGames + ' GAMES';
|
||||
ctx.font = B(26); shadowText(title, W / 2, H / 2 - 44, won ? UI.pick : UI.bad);
|
||||
ctx.font = F(9); shadowText(line, W / 2, H / 2 - 14, UI.cream);
|
||||
if (G.newBest) { // a fresh record crows; otherwise show the mark to beat
|
||||
const pulse = 0.55 + 0.45 * Math.abs(Math.sin(clk * 4));
|
||||
ctx.font = B(20);
|
||||
shadowText('★ NEW BEST ★', W / 2, H / 2 + 2, hexA(UI.warm, pulse));
|
||||
} else if (G.best && G.best.games > 0) {
|
||||
ctx.font = F(8);
|
||||
shadowText(m ? 'BEST ' + G.best.games + ' FELLED'
|
||||
: G.classic ? 'LONGEST MATCH ' + G.best.games + ' GAMES'
|
||||
: 'BEST ' + G.best.games + ' GAMES · ' + G.best.sets + ' SETS', W / 2, H / 2 + 4, UI.dim);
|
||||
}
|
||||
// gated well past the animation so a panic tap can't skip it (main.js gates the restart the same)
|
||||
if (dead ? G.eatenT > EATEN_RESTART : G.done.t > DONE_RESTART) {
|
||||
ctx.font = F(8);
|
||||
shadowText(IS_TOUCH ? 'TAP TO PLAY AGAIN' : 'PRESS ANY KEY TO PLAY AGAIN', W / 2, H / 2 + 32, UI.warm);
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
// gated well past the animation so a panic tap can't skip it (main.js gates the restart the same)
|
||||
if (G.eatenT > EATEN_RESTART) { ctx.font = F(8); shadowText(IS_TOUCH ? 'TAP TO PLAY AGAIN' : 'PRESS ANY KEY TO PLAY AGAIN', W / 2, H / 2 + 32, UI.warm); }
|
||||
ctx.restore();
|
||||
}
|
||||
// Timed freezes swallow every input until they run out, which reads as the game having hung
|
||||
// ("sometimes the controls just feel frozen"). Show the clock instead of hiding it. A modal is
|
||||
|
||||
@@ -108,6 +108,13 @@ export const G = {
|
||||
match: null, // ZOMBIE TENNIS (beats.startMatch): {opp, ending}. One GAME per opponent,
|
||||
// real scoring — every point you win wounds the racket zombie, every point it
|
||||
// wins draws your blood. Runs ON TOP of a permanent interlude.
|
||||
// CLASSIC TENNIS: the mode where nothing turns. `G.mode` stays 'tennis' for the whole run, the
|
||||
// transition is blocked, and the game is scored as a real match — 6 games with a two-game lead is
|
||||
// a set, TUNE.classicSets sets is the match. It is the FOUNDATION mode, not a warm-up: if the
|
||||
// core tennis is good, everything built on it is good.
|
||||
classic: false,
|
||||
done: null, // {won, t} — the run ENDED without a corpse (a classic match played out).
|
||||
// The one end-of-run state that is not 'eaten': same summary, same gated tap.
|
||||
drill: null, // the TRIAGE drill (src/drill.js): {t, spawnT, score, streak, kills, faults,
|
||||
// lost, best, msg}. Owns the court like every other mode — see beats.startDrill.
|
||||
// One rule: always kill the body that would reach you first. `t` is time
|
||||
|
||||
@@ -26,8 +26,12 @@ let run = bag();
|
||||
// count lives on G and survives the flush, so a second endRun would sail past a "nothing happened"
|
||||
// guard and bank a duplicate with zero kills. `pagehide` really does fire more than once — the
|
||||
// bfcache dismisses and restores the same page — which is exactly how this was caught.
|
||||
// Cleared by the next kill, so a fresh run re-arms itself with no reset call to forget.
|
||||
// Cleared by the next kill — which was the whole of the reset until CLASSIC TENNIS arrived, a mode
|
||||
// with NO KILLS IN IT AT ALL. There, nothing ever cleared the flag, so the second and every later
|
||||
// match of a session was silently swallowed by the guard below. beginRun() is the honest reset and
|
||||
// gameplay.restartRun (the one "a new run starts here" moment there is) calls it.
|
||||
let banked = false;
|
||||
export function beginRun() { run = bag(); banked = false; }
|
||||
|
||||
// ---------------------------------------------------------------- storage ----
|
||||
// Private-mode Safari throws on both read and write. Stats are a nicety; a menu that will not open
|
||||
@@ -88,7 +92,7 @@ export function multiKill() { run.mk++; }
|
||||
// opponents felled and has exactly one kill per opponent, by definition, always credited to 'bomb'
|
||||
// (matchGameWon's explode). Un-tagged records predate the split and ARE gore runs, which is why the
|
||||
// default is 'g' everywhere and no migration is needed.
|
||||
export const MODE_GORE = 'g', MODE_MATCH = 'z';
|
||||
export const MODE_GORE = 'g', MODE_MATCH = 'z', MODE_CLASSIC = 'c';
|
||||
const modeOf = r => r.m || MODE_GORE;
|
||||
|
||||
export function endRun(games, sets, secs, dead = true, mode = MODE_GORE) {
|
||||
|
||||
@@ -82,7 +82,7 @@ globalThis.getComputedStyle = () => ({ paddingTop: '0' });
|
||||
|
||||
// ---- game modules (real code) ----------------------------------------------
|
||||
const { G, P, O, score, ball, setupPoint } = await import('./src/state.js');
|
||||
const { update, forceZombies, splatPoint, restartRun, flickTarget, keyPressed } = await import('./src/gameplay.js');
|
||||
const { update, forceZombies, splatPoint, restartRun, flickTarget, keyPressed, classicGame } = await import('./src/gameplay.js');
|
||||
const { startDuel, resolveInterlude, startBossFight, endBossFight, startDrill: _startDrill, endDrill, startMatch: _startMatch, endMatch } = await import('./src/beats.js');
|
||||
// the drill's first-sight modal freezes the world (that is what modals do) — dismiss it the way a
|
||||
// player would, so the tests step a live court
|
||||
@@ -776,6 +776,44 @@ test('the match measures OPPONENTS FELLED, banked as its own kind of run', () =>
|
||||
G.mode = 'splatter'; endMatch();
|
||||
});
|
||||
|
||||
// ---- classic tennis: the mode where nothing turns ---------------------------------------------
|
||||
|
||||
test('classic tennis: a game is not a set, and six with a two-game lead is', () => {
|
||||
G.mode = 'tennis'; G.classic = true; G.everTransitioned = false;
|
||||
score.games = [5, 4];
|
||||
assert.equal(classicGame('P'), false, '5-4 is not a set — advancePoint has not banked the sixth yet');
|
||||
score.games = [6, 5];
|
||||
assert.equal(classicGame('P'), false, 'nor is 6-5: the two-game lead is the rule');
|
||||
assert.deepEqual(G.sets, [0, 0]);
|
||||
score.games = [7, 5];
|
||||
assert.equal(classicGame('P'), false, '7-5 IS a set, but not the match');
|
||||
assert.deepEqual(G.sets, [1, 0], 'the set is banked');
|
||||
assert.deepEqual(score.games, [0, 0], 'and the games reset under it');
|
||||
assert.equal(G.done, null, 'one set is not a match');
|
||||
});
|
||||
|
||||
test('classic tennis: the second set ends the run, with no corpse', () => {
|
||||
G.mode = 'tennis'; G.classic = true;
|
||||
G.sets = [1, 0]; score.games = [6, 0]; G.runGames = 14;
|
||||
assert.equal(classicGame('P'), true, 'the match is over');
|
||||
assert.ok(G.done && G.done.won, 'and you won it');
|
||||
assert.notEqual(G.mode, 'eaten', 'nobody died — this is the other ending');
|
||||
const runs = JSON.parse(localStorage.getItem('splatterRuns'));
|
||||
const r = runs[runs.length - 1];
|
||||
assert.equal(r.m, 'c', 'banked as a classic run');
|
||||
assert.equal(r.dead, 0, 'a match WON is not a death — that is how wins are counted');
|
||||
assert.equal(r.s, 2, 'sets won ride in the second headline slot');
|
||||
});
|
||||
|
||||
test('classic tennis: losing the match ends it the same way, and counts as a loss', () => {
|
||||
G.mode = 'tennis'; G.classic = true;
|
||||
G.sets = [0, 1]; score.games = [0, 6]; G.runGames = 12;
|
||||
assert.equal(classicGame('O'), true);
|
||||
assert.ok(G.done && !G.done.won, 'beaten');
|
||||
const runs = JSON.parse(localStorage.getItem('splatterRuns'));
|
||||
assert.equal(runs[runs.length - 1].dead, 1, 'a match lost IS the run ending badly');
|
||||
});
|
||||
|
||||
// stats.js ships its own fixture-based check — the period filter, the mode split and the name
|
||||
// normalisation that has to agree with server.py. It was exported and never called by anything.
|
||||
test("stats.js's own check", () => { assert.equal(statsCheck(), 'ok'); });
|
||||
|
||||