Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
417 commits
Select commit Hold shift + click to select a range
46087c1
fix(hands): heads lean apart instead of passing through each other
user1303836 Oct 7, 2026
b719ab7
fix(hands): a newcomer who mashes the buttons can beat the rookie
user1303836 Oct 7, 2026
b753540
fix(hands): camera framing for the replay, the count and the rest on …
user1303836 Oct 7, 2026
592ca8e
fix(hands): the count shown after a standing eight stops where the re…
user1303836 Oct 7, 2026
9b2c667
fix(hands): blood that soaks in and flies as drops
user1303836 Oct 7, 2026
fc6e8d2
Merge feature/hands-clientfix (part 2): the visual QA's 3D scene fixes
user1303836 Oct 7, 2026
0da7263
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
88ea83f
Merge feature/hands-corefix (part 2): standing eight and neutral corn…
user1303836 Oct 7, 2026
ca872df
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
73eb05a
feat(hands): "Box!" when the referee sends them back to it
user1303836 Oct 7, 2026
b618936
feat(hands): even out the fighting styles
user1303836 Oct 7, 2026
604f2a7
test(hands): an end-to-end pick of styles, and every scenario settles…
user1303836 Oct 7, 2026
7fe871f
fix(hands): name plates on a phone no longer run into each other
user1303836 Oct 7, 2026
751bd53
Merge feature/hands-styles: five fighting styles, a pick before the b…
user1303836 Oct 7, 2026
3db8394
test(hands): e2e scenarios that still drop a connection and reach a TKO
user1303836 Oct 7, 2026
f7acf79
fix(hands): toes stay flat on the canvas when the heel lifts
user1303836 Oct 7, 2026
216bb38
fix(hands): knockdowns fall the way the punch sends them, live and in…
user1303836 Oct 7, 2026
0232ec7
fix(hands): hooks end their sweep on the contact point
user1303836 Oct 7, 2026
1681e9d
fix(hands): body hooks bend the fighter toward the ribs and body uppe…
user1303836 Oct 7, 2026
a549ccc
fix(hands): close range jabs and straights stop at the face instead o…
user1303836 Oct 7, 2026
60a8c31
fix(hands): a punch allocates nothing per frame
user1303836 Oct 7, 2026
36cdb2c
fix(hands): the pose solver stops building vectors every frame
user1303836 Oct 7, 2026
f8d102b
fix(hands): punches the server refuses come back as soon as it says so
user1303836 Oct 7, 2026
0a55d5b
fix(hands): a fighter dropped for not reading still pauses the bout a…
user1303836 Oct 7, 2026
60cd1f0
fix(hands): reconnecting over a stalled socket no longer blocks every…
user1303836 Oct 7, 2026
a914ea1
fix(hands): a punch held back by the input budget no longer fires aft…
user1303836 Oct 7, 2026
a97a1dc
test(hands): the rematch-while-closing test no longer races the bout …
user1303836 Oct 7, 2026
79f231b
fix(hands): the newer of two presses inside one server tick is the pu…
user1303836 Oct 7, 2026
f4ee0c1
test(hands): the first-frame timeout test no longer hangs on windows
user1303836 Oct 7, 2026
32a70f5
fix(hands): a window left open across a protocol bump is told to reload
user1303836 Oct 7, 2026
a60a19c
fix(hands): the local two-player server starts on windows
user1303836 Oct 7, 2026
652adab
fix(hands): an engine failure ends the bout as a no contest instead o…
user1303836 Oct 7, 2026
5c4230f
fix(hands): a punch pressed during another starts when the engine wou…
user1303836 Oct 7, 2026
d7f6ffc
fix(hands): back-to-back bouts between the same two fighters move rat…
user1303836 Oct 7, 2026
5397e9d
fix(hands): slips and weaves that work show the glove go where the he…
user1303836 Oct 7, 2026
64aa97c
fix(hands): a pause returns both fighters' held walk and guard to neu…
user1303836 Oct 7, 2026
2e05cb7
fix(hands): knees bend the right way and feet, knees and gloves meet …
user1303836 Oct 7, 2026
5ffce95
fix(hands): a press is matched to the input frame that actually carri…
user1303836 Oct 7, 2026
89126c5
fix(hands): seated fighters' feet rest on the canvas
user1303836 Oct 7, 2026
04f918d
fix(hands): the doctor no longer decides the bouts a better boxer wins
user1303836 Oct 7, 2026
1cc4bed
test(hands): measure the computer as the room picks it, against a cou…
user1303836 Oct 7, 2026
8a21c65
feat(hands): a champion a good player can beat, and a contender beate…
user1303836 Oct 7, 2026
5ea8bfe
Merge feature/hands-tune: difficulty that matches the level names, an…
user1303836 Oct 7, 2026
f77cd44
fix(hands): a chain of combinations no longer holds a stunned fighter
user1303836 Oct 7, 2026
3ea073c
fix(hands): the body weave and slip test boxes with a settled facing
user1303836 Oct 7, 2026
fff3bd3
fix(hands): clinched fighters stop instead of keeping the speed they …
user1303836 Oct 7, 2026
d45696f
fix(hands): the manifest refuses a facing scale or stool spot the eng…
user1303836 Oct 7, 2026
6bc8693
fix(hands): a walk or guard held at the bell no longer carries into t…
user1303836 Oct 7, 2026
38a6dad
fix(hands): discord rpc and connection failures explain themselves
user1303836 Oct 7, 2026
d48c856
fix(hands): rematch, retry and failures keep the discord activity open
user1303836 Oct 7, 2026
942a45b
fix(hands): a protocol bump asks open windows to reload
user1303836 Oct 7, 2026
f513ee6
fix(hands): interpolation delay recovers within seconds of a latency …
user1303836 Oct 7, 2026
69308ab
fix(hands): presses right after a periodic flush leave at once
user1303836 Oct 7, 2026
d99735f
fix(hands): the bell sends one neutral frame so held input stops
user1303836 Oct 7, 2026
cb980ed
fix(hands): touch input reaches the server without document focus
user1303836 Oct 7, 2026
37524af
fix(hands): keys and touches held through the bell count at once
user1303836 Oct 7, 2026
97de308
fix(hands): phone players can slip, weave, pull and clinch
user1303836 Oct 7, 2026
7f1ef42
fix(hands): audio unlocks on the first touch
user1303836 Oct 7, 2026
876b265
fix(hands): the network remembers which input frame carried each press
user1303836 Oct 7, 2026
4313555
fix(hands): a rematch signs in without authenticating the sdk again
user1303836 Oct 7, 2026
8f9806f
fix(hands): the resolution scaler settles one step down instead of pu…
user1303836 Oct 7, 2026
911f108
fix(hands): the low quality tier no longer recompiles every shader
user1303836 Oct 7, 2026
f1cbd23
fix(hands): the first bloody hit no longer compiles a shader mid-fight
user1303836 Oct 7, 2026
f6c4e9e
fix(hands): rematches free the blob shadows, gib buffers and bloom fi…
user1303836 Oct 7, 2026
781c362
fix(hands): the 3D view follows a zoom or a move to another monitor
user1303836 Oct 7, 2026
1f9a066
fix(hands): the severed glove's wrist cap sits on the glove
user1303836 Oct 7, 2026
844d23a
fix(hands): a dislocated jaw no longer tears open the throat
user1303836 Oct 7, 2026
0a2bd3e
fix(hands): a stoppage without a replay waits for the finishing punch
user1303836 Oct 7, 2026
fdf077f
fix(hands): the knockdown punch keeps its full dent in the face
user1303836 Oct 7, 2026
c611da8
fix(hands): compact scoreboard mini-bars fit small phones
user1303836 Oct 7, 2026
a54349f
fix(hands): blood, teeth and severed parts fly along the punch
user1303836 Oct 7, 2026
c940c23
fix(hands): blood droplets cost nothing when none are in flight
user1303836 Oct 7, 2026
3c204fa
fix(hands): the corner stool stays until the fighter has risen off it
user1303836 Oct 7, 2026
9d5c651
fix(hands): the taunt beckon moves every frame
user1303836 Oct 7, 2026
1d6cd95
fix(hands): fighters walk in to touch gloves before the opening bell
user1303836 Oct 7, 2026
ea285ec
fix(hands): the referee steps in and pushes on both fighters to break…
user1303836 Oct 7, 2026
d1fdce2
fix(hands): the referee's counting arm chops down on each number
user1303836 Oct 7, 2026
f926bdf
fix(hands): officials use plain materials and cast no shadows
user1303836 Oct 7, 2026
ca2118b
fix(hands): a fighter first seen mid-walk to the glove touch steps, n…
user1303836 Oct 7, 2026
8776d74
fix(hands): every punch eases out of the guard instead of jumping on …
user1303836 Oct 7, 2026
86fdb70
fix(hands): snapshots are deflated and coalesced so slow viewers stay…
user1303836 Oct 7, 2026
d164964
test(hands): a spectator on a 40 KB/s link keeps up with the fight
user1303836 Oct 7, 2026
a3d4071
fix(hands): knockdowns near the ropes keep the body inside the ring
user1303836 Oct 7, 2026
b98a52c
fix(hands): the get-up follows the meter and finishes inside the serv…
user1303836 Oct 7, 2026
8cb31d8
fix(hands): the player's fighter sets off on the press and stops on t…
user1303836 Oct 7, 2026
daa9d4c
fix(hands): the player's guard and slips show on the key press
user1303836 Oct 7, 2026
6cb8525
test(hands): the stalled-reconnect test waits for a lasting stall again
user1303836 Oct 7, 2026
a749c6c
fix(hands): a knockdown during the get-up falls from where he was
user1303836 Oct 7, 2026
6dc5098
fix(hands): the feet are planted under a rising fighter instead of sn…
user1303836 Oct 7, 2026
91671d9
test(hands): a transition sweep guards continuity, the canvas and kne…
user1303836 Oct 7, 2026
186c286
Merge fix293-srv into the #293 review-fix integration
user1303836 Oct 7, 2026
173892a
Merge fix293-pred into the #293 review-fix integration
user1303836 Oct 7, 2026
7e70b17
Merge fix293-anim into the #293 review-fix integration
user1303836 Oct 7, 2026
01d5a4c
fix(hands): the renderer learns which input frame carried each press
user1303836 Oct 7, 2026
c137b4d
test(hands): the transition sweep covers hooks, uppercuts and a per-t…
user1303836 Oct 7, 2026
e9bfa3e
test(hands): the knockdown dent test uses a hit the engine can deal
user1303836 Oct 7, 2026
7987a51
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
6333068
Merge feature/hands-realism: #293's review fixes into the polish branch
user1303836 Oct 7, 2026
e51875c
fix(hands): the ring announcer never reads names with an online voice
user1303836 Oct 7, 2026
2bb354e
test(hands): simulated bouts skip the checksum nothing reads
user1303836 Oct 7, 2026
cb6368f
fix(hands): the ring announcer falls silent while the Activity is hidden
user1303836 Oct 7, 2026
7aa7f8b
test(hands): the balance script plays people over a connection, and s…
user1303836 Oct 7, 2026
c287cc1
fix(hands): the computer only follows up with the full price of the n…
user1303836 Oct 7, 2026
6ab6bcf
fix(hands): crowd arms seat with the bodies when reduced motion comes…
user1303836 Oct 7, 2026
417ea6b
fix(hands): input frames after the result count against the flood limit
user1303836 Oct 7, 2026
69e0ebf
fix(hands): a computer with a broken-down body keeps fighting on the …
user1303836 Oct 7, 2026
5806f3a
fix(hands): each input frame is decoded once again
user1303836 Oct 7, 2026
c4dee62
fix(hands): the ring announcer says both names before the opening bell
user1303836 Oct 7, 2026
f8cd90f
fix(hands): the over-the-shoulder camera stays behind the player on a…
user1303836 Oct 7, 2026
b3f02e3
docs(hands): the README's controls match the game's
user1303836 Oct 7, 2026
1ca0c3b
fix(hands): a win by doctor stoppage counts as a knockout in the record
user1303836 Oct 7, 2026
a3f22ea
fix(hands): the stands behind the fighters are full in every shot but…
user1303836 Oct 7, 2026
64482c7
fix(hands): the swarmer's card shows the full reach he now has
user1303836 Oct 7, 2026
6aa8da5
fix(hands): one rope strap per tie, from the bottom rope to the top, …
user1303836 Oct 7, 2026
492181a
fix(hands): hurt vision and the muffle start with the punch that rock…
user1303836 Oct 7, 2026
f307cd2
fix(hands): the engine checksum covers each fighter's style
user1303836 Oct 7, 2026
924a61b
fix(hands): the style pick on a phone held sideways shows five cards …
user1303836 Oct 7, 2026
e6fa95b
fix(hands): rated bouts record and log both fighters' styles
user1303836 Oct 7, 2026
e9ec74c
fix(hands): faded near ropes no longer cut the blob shadows and glove…
user1303836 Oct 7, 2026
710228f
fix(hands): the computer parries only as often as its perfect-block c…
user1303836 Oct 7, 2026
cbc8945
fix(hands): a stun ends the slip or weave it catches, so the fighter …
user1303836 Oct 7, 2026
8625478
fix(hands): the page loads Discord images from the avatar path only
user1303836 Oct 7, 2026
f3a48aa
fix(hands): rope shadows follow the ropes as they give
user1303836 Oct 7, 2026
1505fb8
fix(hands): the referee counts a risen fighter to eight and always li…
user1303836 Oct 7, 2026
31adcd1
fix(hands): the style pick's keys follow the keyboard focus and leave…
user1303836 Oct 7, 2026
3659607
fix(hands): the styles are revealed together at the bell, not as each…
user1303836 Oct 7, 2026
e8a1354
fix(hands): a style picked as the pick closes is never shown as settl…
user1303836 Oct 7, 2026
63fd607
fix(hands): the computer reacts to each punch in its own time, and th…
user1303836 Oct 7, 2026
56cc6f8
fix(hands): a swarmer pushed onto a corner pad no longer ends the bou…
user1303836 Oct 7, 2026
59013d7
fix(hands): the knockout replay falls where the fighter stood and kee…
user1303836 Oct 7, 2026
718245d
fix(hands): a get-up meter that fills on the count of ten is a knockout
user1303836 Oct 7, 2026
e4459d8
fix(hands): the commentary stops asking whether a fighter who is up c…
user1303836 Oct 7, 2026
c722359
fix(hands): a drop or return during the pick reaches the other corner…
user1303836 Oct 7, 2026
15c2a0b
fix(hands): the finish close-up picks its side once the body has land…
user1303836 Oct 7, 2026
9cbb4e1
feat(hands): the style pick works from a controller
user1303836 Oct 7, 2026
2637182
fix(hands): a knocked-out head lies on its neck and on the canvas, wh…
user1303836 Oct 7, 2026
bd19866
test(hands): a knockout turns the body into the fall from its first f…
user1303836 Oct 7, 2026
8c0850e
fix(hands): a friend who arrives during the computer's pick takes its…
user1303836 Oct 7, 2026
9ac9df0
fix(hands): a blocked punch sounds and rumbles as a block and earns n…
user1303836 Oct 7, 2026
3e49ec0
test(hands): the masher test uses the client's real one-press queue
user1303836 Oct 7, 2026
ea041cf
fix(hands): after a knockout the broadcast shows the winner and the r…
user1303836 Oct 7, 2026
c2525aa
test(hands): the knockout replay's fall check and its test type-check
user1303836 Oct 7, 2026
278b2d0
fix(hands): the name plate drops whole parts, keeps its counts and st…
user1303836 Oct 7, 2026
7c1f78a
fix(hands): a body shot that drops him doubles him over onto his knees
user1303836 Oct 7, 2026
f50f81e
fix(hands): the rest's wide shot on an upright phone holds still and …
user1303836 Oct 7, 2026
0d1242d
fix(hands): the rookie pecks at a newcomer's guard every round and wa…
user1303836 Oct 7, 2026
ebdec93
fix(hands): blood stains on the canvas are lighter in the middle than…
user1303836 Oct 7, 2026
5dd7b6a
fix(hands): a seat that opens before the bell goes to the waiting spe…
user1303836 Oct 7, 2026
d28a81e
fix(hands): a fighter on the ropes leans back on them, and the ropes …
user1303836 Oct 7, 2026
388f79e
fix(hands): knocked-out feet roll only as far as an ankle does, and n…
user1303836 Oct 7, 2026
3a96447
fix(hands): heads rest on opposite shoulders in a clinch whatever the…
user1303836 Oct 7, 2026
b70416d
test(hands): the reconnect scenario drops the link the way a lost net…
user1303836 Oct 7, 2026
67ccf41
fix(hands): a fighter gets a few clear ticks after a stun before a ro…
user1303836 Oct 7, 2026
b2a4bbe
fix(hands): canvas blood builds up over a bout instead of flooding ro…
user1303836 Oct 7, 2026
e338c88
fix(hands): fighters drawn apart are eased there, stay inside the rop…
user1303836 Oct 7, 2026
2c79505
fix(hands): the fouled fighter comes out of the recovery clear-headed
user1303836 Oct 7, 2026
6c382af
fix(hands): a knocked-out head lands on the canvas instead of flippin…
user1303836 Oct 7, 2026
f776085
fix(hands): a result arriving twice is shown once, and the stoppage's…
user1303836 Oct 7, 2026
8380823
fix(hands): flesh, teeth, brain and skull stay on the canvas for the …
user1303836 Oct 7, 2026
78e76d7
fix(hands): the rematch room holds the fighters' seats, and spectator…
user1303836 Oct 7, 2026
d10e0bc
fix(hands): a block that wears the guard below what can stop a punch …
user1303836 Oct 7, 2026
b6514a7
fix(hands): hair dye and beards keep their colour on dark-skinned fig…
user1303836 Oct 7, 2026
e81e0a9
fix(hands): reduced blood is reduced for teeth and the gum shield, an…
user1303836 Oct 7, 2026
9a980d0
fix(hands): the referee counts over the body where the fall took it, …
user1303836 Oct 7, 2026
7eb516a
fix(hands): the knockout replay falls and ends exactly as the count s…
user1303836 Oct 7, 2026
dd3c2b5
fix(hands): the standing eight names the fighter who beat the count, …
user1303836 Oct 7, 2026
3aabc7e
fix(hands): the knockdown caption keeps below the count on phones
user1303836 Oct 7, 2026
63ca022
Merge main after #293's squash merge
user1303836 Oct 7, 2026
93a90f4
Merge fix294-pick: style pick, announcer, introductions, README and e…
user1303836 Oct 7, 2026
0abeaca
fix(hands): after a gap in drawing a knocked-down fighter falls at hi…
user1303836 Oct 7, 2026
43fd2ab
fix(hands): a fighter who drops without a close pauses the bout in 7.…
user1303836 Oct 7, 2026
675d57b
test(hands): the styles e2e scenario expects the reveal at the bell
user1303836 Oct 7, 2026
e0a70e6
fix(hands): captions and the HUD fit the merged touch pads, and the p…
user1303836 Oct 7, 2026
fe994b2
fix(hands): beaten eyes swell into grotesque mounds, and cheek and fo…
user1303836 Oct 7, 2026
a8a05ba
Merge fix294-camera: camera, finish sequence, replay, referee and hur…
user1303836 Oct 7, 2026
1f9fbb7
fix(hands): the touch hint keeps left of the pads on small phones and…
user1303836 Oct 7, 2026
39d1ec3
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
67674df
fix(hands): the slow-connection warning keeps clear of the touch pads…
user1303836 Oct 7, 2026
21b0b7b
fix(hands): the stands make room for the decision and arm-raise shots…
user1303836 Oct 7, 2026
e4a348f
fix(hands): a rematch against the computer waits for a friend before …
user1303836 Oct 7, 2026
1f657fc
fix(hands): the skin shaders discard nothing and heads draw one-sided…
user1303836 Oct 7, 2026
e9f8a96
fix(hands): a head brought back on the canvas rolls round on it inste…
user1303836 Oct 7, 2026
cebd3d9
Merge fix294-hud: HUD, captions, touch layout, commentary and contact…
user1303836 Oct 7, 2026
89ecce1
fix(hands): live hits bleed from where the fighter is drawn
user1303836 Oct 7, 2026
f2375e5
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
ece4a5a
feat(hands): finishers follow the punch, and a body shot caves the ri…
user1303836 Oct 7, 2026
de19c7a
fix(hands): blood leaves from the drawn fighter without needing the r…
user1303836 Oct 7, 2026
b03dce2
fix(hands): a perfect block needs a real raise, so a flickered guard …
user1303836 Oct 7, 2026
83595c0
fix(hands): the result card's punch totals are the engine's count for…
user1303836 Oct 7, 2026
f9b0c18
fix(hands): a severed head and glove keep the scan's smooth shading a…
user1303836 Oct 7, 2026
d7c858b
fix(hands): rooms and computer bouts are capped so the event loop sta…
user1303836 Oct 7, 2026
d07ba46
fix(hands): the neck's cross-section turns with the head on the stump…
user1303836 Oct 7, 2026
cab8e67
fix(hands): a severed head keeps its injuries and the skin's sheen
user1303836 Oct 7, 2026
92dcf67
test(hands): the shader warm-up covers every finisher and the gum shield
user1303836 Oct 7, 2026
4a22f6d
fix(hands): players behind Discord's proxy no longer share one sign-i…
user1303836 Oct 7, 2026
e5cae59
test(hands): the jaw mask test reads the injury shader's moved point
user1303836 Oct 7, 2026
d5f85d3
fix(hands): blood drips from the face as drawn, and pools under every…
user1303836 Oct 7, 2026
1ef5cbc
test(hands): the network test's malformed waiting frame offers three …
user1303836 Oct 7, 2026
f4e7fb2
fix(hands): a finisher's stump pumps blood with the heartbeat for sec…
user1303836 Oct 7, 2026
e13e61f
fix(hands): ring control settles a close round of boxing but never wi…
user1303836 Oct 7, 2026
4f5d179
fix(hands): a style's power is one number, for the damage and the poi…
user1303836 Oct 7, 2026
a75b8f6
fix(hands): the countdown and rest panel keeps clear of the touch pads
user1303836 Oct 7, 2026
e5d19fa
Merge fix294-effects: canvas blood pacing, lasting gore, severed-head…
user1303836 Oct 7, 2026
6edb852
test(hands): the ballistic effects test lets the severed neck bleed o…
user1303836 Oct 7, 2026
7caa40d
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
3fb391c
fix(hands): the swarmer is a step quicker on his feet, not a stride
user1303836 Oct 7, 2026
8b3eeb2
fix(hands): the computer's boxer moves like one
user1303836 Oct 7, 2026
5d1d786
fix(hands): the protocol goes to version 4, so a window from before i…
user1303836 Oct 7, 2026
95285b5
fix(hands): a parried fighter is rooted for the stagger, so holding b…
user1303836 Oct 7, 2026
c8b527b
refactor(hands): keep the fountain's tuning private to the effects
user1303836 Oct 7, 2026
0ba457c
fix(hands): the player's fighter stumbles out of a stun that cut his …
user1303836 Oct 7, 2026
37341ab
fix(hands): a phone held upright gets a short touch hint
user1303836 Oct 7, 2026
a1f0e1e
Merge fix294-hud: panels and hint clear of the touch pads on phones
user1303836 Oct 7, 2026
50dc29e
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
39254a3
Merge fix294-scene: full stands, clinch heads, ropes, finisher choice…
user1303836 Oct 7, 2026
21750bd
test(hands): renderer stubs carry the camera's and the scene's new fi…
user1303836 Oct 7, 2026
34e3ca9
fix(hands): the physics carries a knocked-down fighter into the get-u…
user1303836 Oct 7, 2026
c478481
fix(hands): a style's conditioning saving is its advertised share, no…
user1303836 Oct 7, 2026
ad477f7
Merge fix294-rooms: protocol 4, rooms, rematch seats, silent drops, p…
user1303836 Oct 7, 2026
3a54564
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
ff63708
Merge fix294-engine: stun, parry, guard, foul, count and conditioning…
user1303836 Oct 7, 2026
6fbad42
fix(hands): a downed player's get-up prompt stands clear of the get-u…
user1303836 Oct 7, 2026
44e3720
fix(hands): a pair pressed into a corner settles, and the bell breaks…
user1303836 Oct 7, 2026
b00e474
fix(hands): the champion is harder to beat than the contender again
user1303836 Oct 7, 2026
50c2c3d
fix(hands): the reconnection panel keeps clear of the touch pads
user1303836 Oct 7, 2026
25a8e5a
test(hands): the blocked-knockdown push stub has the movement prediction
user1303836 Oct 7, 2026
c5b1d54
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
710d75f
Merge fix294-engine: guard breaks, perfect-block re-arm, parry roots,…
user1303836 Oct 7, 2026
8f21386
fix(hands): skin and kit a fallen body reaches under the canvas are d…
user1303836 Oct 7, 2026
6486100
feat(hands): a spent guard shows on the guard bar and in the fighter'…
user1303836 Oct 7, 2026
26d4880
Merge fix294-hud: get-up and reconnect panels clear of the pads, spen…
user1303836 Oct 7, 2026
012dc8b
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
40a9b8d
fix(hands): say that he steps back to his place as he rises, not once up
user1303836 Oct 7, 2026
8dd792c
fix(hands): the computer tries a parry only with a guard it has let d…
user1303836 Oct 7, 2026
6b2b95a
fix(hands): the style cards show the boxer's and swarmer's power and …
user1303836 Oct 7, 2026
e1f3be5
Merge fix294-ragdoll: knockout physics, the replayed fall and the get…
user1303836 Oct 7, 2026
e8bb387
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
de88cb8
fix(hands): circling takes an angle on a man who stands, and the faci…
user1303836 Oct 7, 2026
7e08263
fix(hands): the commentary calls cuts on the doctor's own scale, and …
user1303836 Oct 7, 2026
6447c23
test(hands): the golden replay boxes through the new rules instead of…
user1303836 Oct 7, 2026
895299a
Merge fix294-engine2: a turn-rate limit on facing, corners and the be…
user1303836 Oct 7, 2026
dbebc54
Merge fix294-engine2: a real turn-rate limit, facing through combinat…
user1303836 Oct 7, 2026
8f0b923
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
20b33dc
test(hands): the held-seat test waits for the watcher's new welcome a…
user1303836 Oct 7, 2026
9b4c360
fix(hands): the computer only throws a punch that reaches along the w…
user1303836 Oct 7, 2026
d1663a6
fix(hands): no style runs away with its matchups
user1303836 Oct 7, 2026
776f115
fix(hands): the contender is harder to outbox, and the rookie reaches…
user1303836 Oct 7, 2026
eaf70ad
Merge fix294-balance: a latency-aware balance harness, the computer's…
user1303836 Oct 7, 2026
996e77f
build(hands): rebuild the Activity bundle
user1303836 Oct 7, 2026
1a20fbf
test(hands): the stalled-reconnect test caps the server's send buffer…
user1303836 Oct 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,12 @@ Keyboard controls use physical key positions (`KeyboardEvent.code`):
| Slip left / slip right | `Z` / `X` |
| Weave / pull | `C` / `V` |
| Clinch / switch stance | `B` / `N` |
| Low blow / headbutt | `1` / `2` |
| Taunt | `M` |
| Low blow / headbutt (deliberate fouls) | `Shift+1` / `Shift+2` |
| Private get-up rhythm | `Left Arrow` / `Right Arrow` |
| Corner instruction, between rounds | `1` close the cut · `2` bring down the swelling · `3` catch your breath |
| Style, in the pick before the bout | Arrow keys choose, `Enter` settles; `1`–`5` settle on that card at once |
| Camera | `K` cycles broadcast, close and over the shoulder |

Standard-controller controls are:

Expand All @@ -490,6 +494,8 @@ Standard-controller controls are:
| Clinch / switch stance | Left-stick press / right-stick press |
| Low blow / headbutt | View/Back / Menu/Start |
| Private get-up rhythm | While down, press D-pad left / right; it registers immediately rather than waiting for release |
| Corner instruction, between rounds | Left (`X`/Square) close the cut · top (`Y`/Triangle) bring down the swelling · right (`B`/Circle) catch your breath |
| Style, in the pick before the bout | D-pad or left stick choose; bottom (`A`/Cross) settles |

The right stick also performs one punch after a center→peak→center gesture. Left/right direction selects the hand. Using the absolute angle from horizontal: **0–22.5° hook**, **22.5–45° jab**, **45–70° straight**, and **70–90° uppercut**. The gesture fires once only after returning to center; trigger modifiers are captured at gesture start. Face/D-pad punches are the accessibility alternative when stick gestures are impractical.

Expand Down Expand Up @@ -561,7 +567,7 @@ For a long-running deployment, run the command under your process manager of cho
2. On the application's **OAuth2** page, add `https://127.0.0.1` under **Redirects** and save it. Discord requires a Redirect URI for Activity authorization even though the Embedded App SDK handles returning to the Activity; this placeholder is the value specified by Discord's Activity guide.
3. Configure Activity OAuth for exactly `identify` and `guilds.members.read`. Install the guild app with both `bot` and `applications.commands` scopes, and keep **Server Members Intent** enabled. Message Content Intent remains needed by other IntelStream features.
4. Verify `DISCORD_GUILD_ID`, the authenticated application/client ID, and `DISCORD_CLIENT_SECRET`. Store the client secret and bot token only in the server environment. Never put either secret—or OAuth codes, access tokens, or game tickets—in a URL, Vite variable, browser/local storage, analytics, or logs.
5. Run the Python listener on `127.0.0.1:HANDS_PORT`. Put a public TLS reverse proxy on the mapped origin and proxy `/`, `/api/hands/*`, and WebSocket upgrades to that listener. Preserve HTTPS/WSS, Host, and upgrade headers; do not expose the plaintext loopback port publicly. Hands applies global and per-client request/concurrency ceilings using the direct peer address. If the proxy supplies `X-Forwarded-For`, set `HANDS_TRUSTED_PROXY_CIDRS` to only the exact proxy network(s) that connect to Hands (for example `127.0.0.1/32,::1/128` for a loopback proxy), configure the proxy to overwrite or append the real client address, and prevent clients from bypassing that proxy. Forwarded headers from any unlisted peer are ignored; never configure an all-addresses CIDR.
5. Run the Python listener on `127.0.0.1:HANDS_PORT`. Put a public TLS reverse proxy on the mapped origin and proxy `/`, `/api/hands/*`, and WebSocket upgrades to that listener. Preserve HTTPS/WSS, Host, and upgrade headers; do not expose the plaintext loopback port publicly. Hands applies global and per-client request/concurrency ceilings keyed on the peer address; because Discord's Activity proxy hides players' addresses, the sign-in ceilings are also scoped to the Activity instance, so one voice channel cannot crowd out another. If the proxy supplies `X-Forwarded-For`, set `HANDS_TRUSTED_PROXY_CIDRS` to only the exact proxy network(s) that connect to Hands (for example `127.0.0.1/32,::1/128` for a loopback proxy), configure the proxy to overwrite or append the real client address, and prevent clients from bypassing that proxy. Forwarded headers from any unlisted peer are ignored; never configure an all-addresses CIDR.
6. Start `uv run intelstream` and confirm startup configures one guild-only global `hands` Entry Point with Discord handler `DISCORD_LAUNCH_ACTIVITY`. Confirm the public `/healthz`, open Discord's App Launcher, search for BunkerIntel, and launch it. Have a second distinct guild member select **Play now** on Discord's channel message, then have a third member join and confirm they see **SPECTATING · READ ONLY** with no gameplay input. Confirm only the first two seats affect the match and ELO. A single process owns in-memory OAuth state, rooms, spectators, and reconnect tickets; do not horizontally scale Hands without shared authoritative state/routing.
7. Complete the violent-content/age-rating/disclosure and originality reviews described above before public distribution.

Expand Down Expand Up @@ -625,7 +631,7 @@ HANDS_DEV_BACKEND=http://127.0.0.1:8091 npm --prefix web/hands run dev -- --port

Open `http://localhost:5174/?e2e=1&instance_id=<any id>&player=<name>` in two browser windows (different names) to fight. The `e2e` switch only exists in Vite development builds; the development server authenticates anyone who can reach its port, so never expose it.

`scripts/hands_e2e_scenarios.js` automates this with Playwright: `ko` (power punches until a knockdown, private get-up rhythm, stoppage), `reconnect` (one client drops offline mid-round and resumes), `rest` (two rounds with the corner rest), `spectator` (a third client joins read-only), `touch` (one player on an emulated phone), `mash` (hundreds of key presses per second) `latency` (a TCP proxy delays every frame 110 ms each way, and the clients report their measured input acknowledgement latency, which the fighter HUD also shows) `soak` (a full three-round bout sampling heap size, latency and render scale every twenty seconds) `background` (one player's page is frozen through the DevTools lifecycle state for eight seconds, as a backgrounded phone app would be, then resumed) `rematch` (both players use the Rematch button after the result and fight a second bout in the same instance) `rematchloop` (four bouts back to back while sampling heap size and GPU object counts for leaks) `clinch` (both players close in and one ties up; the harness reads the fighters' separation from the client state through the engine's draw-in, the hold and the referee break) and `response` (key press to first rendered frame for the player's own punch and step, when the opponent sees them, and whether the predicted punch ever jumps back, behind a delay proxy set with `E2E_DELAY_MS`, 60 ms each way by default). It spawns the development server itself and prints the clients' status text plus any client or server errors. The default software renderer keeps runs reproducible on machines without a GPU; set `E2E_GPU=1` to render on the machine's GPU for real frame pacing, input latency and screenshots.
`scripts/hands_e2e_scenarios.js` automates this with Playwright: `ko` (power punches until a knockdown, private get-up rhythm, stoppage), `reconnect` (one client's link goes silent mid-round through a TCP proxy, with no close in either direction as a lost network has none; it times how long the room takes to pause the other player, then restores the link and checks both resume), `rest` (two rounds with the corner rest), `spectator` (a third client joins read-only), `touch` (one player on an emulated phone), `mash` (hundreds of key presses per second) `latency` (a TCP proxy delays every frame 110 ms each way, and the clients report their measured input acknowledgement latency, which the fighter HUD also shows) `soak` (a full three-round bout sampling heap size, latency and render scale every twenty seconds) `background` (one player's page is frozen through the DevTools lifecycle state for eight seconds, as a backgrounded phone app would be, then resumed) `rematch` (both players use the Rematch button after the result and fight a second bout in the same instance) `rematchloop` (four bouts back to back while sampling heap size and GPU object counts for leaks) `clinch` (both players close in and one ties up; the harness reads the fighters' separation from the client state through the engine's draw-in, the hold and the referee break) and `response` (key press to first rendered frame for the player's own punch and step, when the opponent sees them, and whether the predicted punch ever jumps back, behind a delay proxy set with `E2E_DELAY_MS`, 60 ms each way by default). It spawns the development server itself and prints the clients' status text plus any client or server errors. The default software renderer keeps runs reproducible on machines without a GPU; set `E2E_GPU=1` to render on the machine's GPU for real frame pacing, input latency and screenshots.

`HANDS_DEV_BACKEND` is a Node/Vite development-process setting, not a browser `VITE_*` value and not a production origin. Real OAuth still needs a valid Activity instance; the fixture is only recorded presentation data. Keep `HANDS_DEV_MODE=false` in production.

Expand Down
5 changes: 4 additions & 1 deletion scripts/check_hands_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
re.IGNORECASE,
)
# These are the complete external URL literals carried by reviewed client code.
# They are pinned SDK metadata or model attribution, not Hands runtime targets.
# Apart from Discord's avatar host they are pinned SDK metadata or model attribution,
# not Hands runtime targets.
REVIEWED_EXTERNAL_URL_LITERALS = {
"https://github.com/uuidjs/uuid#getrandomvalues-not-supported",
"https://discord.com",
Expand All @@ -40,6 +41,8 @@
"https://staging.discord.co",
"http://localhost:3333",
"https://pax.discord.com",
# Discord's image host, for the players' own avatars (image requests only).
"https://cdn.discordapp.com/avatars/",
# Texel Boxer source and CC BY 4.0 license attribution shown in-app.
"https://sketchfab.com/3d-models/boxer-84767168720948b38728ff78ee6f6090",
"https://creativecommons.org/licenses/by/4.0/",
Expand Down
Loading
Loading