Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ The right stick also performs one punch after a center→peak→center gesture.

### Presentation and settings

The committed client renders a real-time 3D broadcast presentation with WebGL (pinned three.js): a procedurally modeled arena, canvas-textured ring, articulated boxer rigs with IK-driven punch animation, a referee, dynamic lighting and shadows, and GPU particle effects—plus generated Web Audio. There are no runtime images, fonts, music, model files, or other external assets; every mesh, texture, and sound is generated in code. **Blood defaults to `full`**; Settings can select `full`, `reduced`, or `off` without changing authoritative trauma or HUD information. Settings also provide master audio volume, haptics on/off, and reduced motion. Audio unlocks only after user interaction and suspends while hidden; haptics are feature-detected and limited to bounded authoritative impact events. Reduced motion removes particles/shake while preserving match state and private get-up information.
The committed client renders a real-time 3D broadcast presentation with WebGL (pinned three.js): a procedurally modeled arena, canvas-textured ring, a referee, dynamic lighting and shadows, and GPU particle effects—plus generated Web Audio. The fighters are the CC0 KayKit Barbarian rig (Kay Lousberg, kaylousberg.com; license in web/hands/assets-src/) driven by authored clips retarget-baked from the project's own boxing motion (idle, movement, guards, all punches both hands, reactions, knockdown, get-up), phase-locked to the authoritative simulation via combat-manifest.json. All arena meshes, textures, and sounds remain generated in code. **Blood defaults to `full`**; Settings can select `full`, `reduced`, or `off` without changing authoritative trauma or HUD information. Settings also provide master audio volume, haptics on/off, and reduced motion. Audio unlocks only after user interaction and suspends while hidden; haptics are feature-detected and limited to bounded authoritative impact events. Reduced motion removes particles/shake while preserving match state and private get-up information.

Before a public release, review Discord's current violent-content rules, age rating/restriction controls, store/application disclosures, and regional requirements. Do not add external/borrowed assets, commercial boxing-game UI, audio, animation traces, real-fighter or celebrity likenesses, sanctioning-body/brand marks, logos, or recognizable trade dress. All fighter art, interface, motion, terminology, and sound must remain original.

Expand Down
50 changes: 50 additions & 0 deletions docs/hands-lab-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -286,3 +286,53 @@ All five steps landed. Final state:
- Bundle is 1.67 MB (GLB embedded as base64, still the exact three-file
manifest; both static scanners learned to skip URL extraction only for
>4 KB generated literals — credential scanning still applies).

---

# Addendum: imported rigged model (2026-08-06)

**Asset**: KayKit Adventurers `Barbarian.glb` (CC0, Kay Lousberg), vendored with
license in `web/hands/assets-src/`. Inspection: 41-bone armature (dots stripped
by GLTFLoader: `upperarml`, `wristl`, `footl`…), 76 authored clips (in-place,
game-ready), T-pose rest, ~1.35 m tall, faces +Z, 6 skinned parts, 1 palette
texture (1024²), 4,045 triangles, prop meshes (axes/shield/mug/hat/cape)
stripped at generation.

**Generation**: `scripts/generate-fighter-glb.ts` retarget-bakes the project's
tuned procedural boxing motion onto the Barbarian armature — world-delta
retarget for torso/head, child-aim retarget for limbs (convention-free), hips
translation scaled by rest hip ratio. 18 clips at authoritative tick rate.
Canonical adapter (`BONE_ADAPTER`) maps canonical bones → model bones with a
hard diagnostic on missing bones. Glove meshes are runtime-attached to the
wrist bones (corner colors); the skin palette texture is embedded base64 and
assigned per fighter clone.

**Model lab**: `/hands/model-lab` (dev) / `?model-lab=1` (vite) — clip player
(play/pause/seek/loop/crossfade), SkeletonHelper, full bone hierarchy print,
clip name/duration/track table, triangle/material/texture inventory,
scale/rotation/position controls, and warnings (unnamed clips/bones, missing
textures, runtime warnings). Same lighting rig as the game.

**Runtime**: `SkinnedBoxer` = SkeletonUtils.clone + per-fighter AnimationMixer +
independently cloned materials only where appearance differs (gear gloves,
skin clearcoat), shared geometry/texture. `BoxingGraph` drives locomotion
blending, committed action playback phase-locked to manifest ticks, reactions,
knockdown/getup, foot locking, and constrained additive IK — corrections
applied strictly after `mixer.update()`. Procedural animator preserved behind
`?procedural=1` and as automatic fallback on GLB load failure.

**Verified**: independent skeletons/animation/materials per fighter (unit
tested), cast+receive shadows, authoritative roots preserved, zero console
errors across captures, SwiftShader software floor avg 59 ms/frame (GPU-bound
real hardware runs far faster; scene ~10k tris).

**Missing clips for existing combat actions** (all currently fall back to
idle/locomotion): taunt dance, clinch hold, foul-recovery crouch, weave/slip/
pull defensive poses, body-target punch variants (aim IK covers height), power
variants (timeScale covers tempo).

**Known remaining visual defects**: ACES tone mapping plus arena lighting wash
the palette toward pastel; trauma overlays are scaled for the larger head but
their positions are approximate; the knockdown head-fall velocity makes the
0.10 m joint metric read ~0.22 m one tick after contact (filmstrip shows flush
contact).
5 changes: 5 additions & 0 deletions src/intelstream/hands/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ def __init__(
routes.extend(
[
web.get("/hands/lab", self._lab_redirect),
web.get("/hands/model-lab", self._model_lab_redirect),
web.get("/hands/replays/{name}", self._lab_replay),
]
)
Expand Down Expand Up @@ -798,6 +799,10 @@ async def _index(self, _request: web.Request) -> web.Response:
async def _lab_redirect(_request: web.Request) -> web.Response:
raise web.HTTPFound("/?lab=1")

@staticmethod
async def _model_lab_redirect(_request: web.Request) -> web.Response:
raise web.HTTPFound("/?model-lab=1")

async def _lab_replay(self, request: web.Request) -> web.Response:
if not self.dev_mode:
raise web.HTTPNotFound()
Expand Down
2 changes: 1 addition & 1 deletion src/intelstream/hands/static/assets/hands.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 60 additions & 35 deletions src/intelstream/hands/static/assets/hands.js

Large diffs are not rendered by default.

33 changes: 33 additions & 0 deletions web/hands/assets-src/Barbarian.LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

KayKit : Adventurers Character Pack (1.0)

Created/distributed by Kay Lousberg (www.kaylousberg.com)
Creation date: 13/03/2023 09:00

------------------------------

License: (Creative Commons Zero, CC0)
http://creativecommons.org/publicdomain/zero/1.0/

This content is free to use in personal, educational and commercial projects.

Support me by using a brand resource provided in this pack or by crediting Kay Lousberg, www.kaylousberg.com (this is not mandatory)

------------------------------

This asset pack is here thanks to all the wonderful people who support KayKit on Patreon and those who buy our EXTRA or SOURCE packs on itch.io.

And a big, special thank you to my Super Supporters:

- Brian McBarron
- Silva



------------------------------


Patreon: http://patreon.com/kaylousberg

Follow on Twitter for updates:
http://twitter.com/KayLousberg
Binary file added web/hands/assets-src/Barbarian.glb
Binary file not shown.
Binary file added web/hands/assets-src/barbarian_texture.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 0 additions & 69 deletions web/hands/glb-debug.html

This file was deleted.

3 changes: 2 additions & 1 deletion web/hands/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"test": "vitest",
"test:run": "vitest run",
"build": "tsc --noEmit && vite build && npm run scan:build",
"scan:build": "node scripts/scan-build.mjs"
"scan:build": "node scripts/scan-build.mjs",
"generate:fighter": "esbuild scripts/generate-fighter-glb.ts --bundle --platform=node --format=esm --outfile=node_modules/.cache/generate-fighter-glb.mjs && node node_modules/.cache/generate-fighter-glb.mjs"
},
"dependencies": {
"@discord/embedded-app-sdk": "2.5.0",
Expand Down
Loading
Loading