docs+fix: sidequest close-out — T-1095 head tint, design doc, wardrobe docs, changelog (T-1088/T-1089)

T-1095 fixed: template heads now receive the body's skin tone (same
treatment as seg_head) — _load_head passes tone.lit with a full-white
fallback mask through _attach_to_bone; without a mask sidecar the tint was
silently ignored, so untinted templates read grey against mid/dark tones.
Verified by lookbook render (head_001 on child, tone 6 — face matches arms).

Docs: the T-1088 locomotion design document committed to docs/design/ (the
sandbox code's 'design §' references now resolve in-repo); character-asset-
organization gains §11 Wardrobe Pipeline and sheds three stale claims (the
never-built indexed-greyscale mask plan, single-mask-per-asset for clothing,
the resolved multi-region open question); CHANGELOG carries the sidequest
entry; D-250 amended with the shipped cutaway-modes verdict (mode 2 default,
user-decided live).

Tickets: T-1088, T-1089, T-1095 closed; T-1096 filed (S9 live feel-tuning,
needs the user). The Fable-5 cascade exception is closed — the cascade
resumes at Phase 4 (T-750).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 14:15:56 +02:00
co-authored by Claude Fable 5
parent e709462a7b
commit 3d6dcc9d05
8 changed files with 684 additions and 14 deletions
+81
View File
@@ -976,3 +976,84 @@ Basic-set EXPANSION (user, 2026-07-06 bedtime directive: ''full set of the basic
Fill-in-the-blanks addendum (user bedtime directive 2 + lead judgment): wave 2 grows to 12 — adds sweater_modern (crew pullover), cargo_pants (utility/cyberpunk staple), parka_thrds (cold-weather was absent entirely; ships as the FIRST CANON-BRANDED garment — thrds is Braemar''s cold-weather fiber brand per wiki; hip-length to avoid the parked skirt-rigging tier), slides (swim footwear, near-free). PLUS outfit presets: data file of named complete looks (casual/business/sport/beach/worker/sleep as tint-palette presets over garments) authored by the lead at integration — makes the catalogue usable for NPC dressing and the shop as OUTFITS, not just items. Post-wave-2 catalogue: 21 modern pieces (tops 8 / bottoms 6 / feet 4 / full-body 2 / swim 3). Hats/accessories remain the deliberate daylight deferral (T-721).', NULL, '2026-07-06 21:20:30', '2026-07-06 21:20:30.325', '2026-07-06 21:20:30.325', NULL, '844a61fd59dbff78bb63a90f4399d5c9', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCPBF41RWK9PW9M22Q7961C', 'status', 'backlog', 'review', NULL, '2026-07-07 09:23:38', '2026-07-07 09:23:38.268', '2026-07-07 09:23:38.268', NULL, 'dbfc4dd044d0fd988d9b5ff5e2514d7e', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCPBF41RWK9PW9M22Q7961C', 'description', 'Fable-5-window sidequest workstream 2 (user directive 2026-07-06, extends T-1088 scope family): build the clothing ENGINE and a basic set now, park variety for later. Target bar: RimWorld''s original apparel breadth — varied enough to not feel limiting. Goal experience: being able to pick and SHOP for clothes — colorize + slap logos on casualwear. Basic set: t-shirt (logo-capable), hoodie (logo-capable), button-down shirt, shorts, jeans, formal pants, jacket, colorable uniform, black suit (moved up so officials are includable). Skipped by explicit call: capes, dresses/skirts (parked — difficulty tier). Engine deliverables: (1) multi-region tint masks — requires Quaternius Source tier files (USD5 Patreon month, one-time download, CC0 retained — user purchase action); (2) logo decal region on garment chest UV — flat 2D artwork per D-244, diegetic hook into economy generated brands (wiki/economics/corporations/generated_brands.toml) for brand-logo shirts; (3) manifest + CharacterVisualDescriptor category coverage (slots/tints already generic); (4) batch-fit each authored garment to all 11 body types via the validated Sprint-28 Blender Surface Deform pipeline (tooling/blender_*.py). Authoring routes per garment TBD by feasibility pass: derive from owned Fantasy pack meshes (62 parts, e.g. tunic->tshirt sleeve cut, pants->shorts hem cut) vs hand-author low-poly on the 65-bone rig (Garment Tool). Related: T-1088 locomotion sandbox doubles as the garment-under-animation QA rig (cycle outfits through Walk/Sprint/Crouch_Fwd).
Correction (2026-07-06): Source tier is PARTIALLY owned already — docs/assets/downloads/ (gitignored vendor archives, present in both checkouts) holds Universal Base Characters[Source] (630MB: full .blend files for all 6 base bodies incl. FullBody + OnlyHead variants, hairstyle .blends origin-at-0 + rigged-to-head-bone, texture masters, Godot engine project) plus UBC[Standard], UAL 1+2[Standard], Modular Character Outfits Fantasy[Standard]. NOT owned: Fantasy Outfits[Source] — the garment recolor masks + named vertex groups. Consequence: authoring NEW garments is fully unblocked (author against source body .blends, create our own tint masks/vertex groups — no purchase needed); only pack-DERIVED garments'' clean masks would want one more USD5 Patreon month, decision deferred until the feasibility route table says how much derivation we actually use.
Art direction (user, 2026-07-06): garments read CYBERPUNK/MODERN — near-future everyday civilian + corporate wear — NOT fantasy/medieval. The owned Fantasy pack is at most a topology donor (low-poly base shapes like pants/shirts are genre-neutral; genre lives in silhouette details, textures, trims, and accessories) — no medieval trim/textures may survive into shipped garments. Weight the authoring routes accordingly: texture identity matters as much as mesh. Canon hook: the wiki already ships a garment brand — thrds (wiki/star-systems/GJ-475/index.md, Braemar fiber cooperative, corridor fashion markets) — so branded clothing connects to Phase-1 lore, not only generated_brands.toml. This emphasis also feeds the Quaternius-pivot evaluation: commercial alternatives skew sci-fi/urban while Quaternius clothing is fantasy-only.
Nuance (user, 2026-07-06): the cyberpunk/modern direction is the DEFAULT, not a prohibition — fashion in the Reach is cyclical, so fantasy/medieval-flavored garments may appear here and there as deliberate fashion statements (subculture pieces, luxury/revival trims, statement outerwear). Supersedes the previous note''s hard ''no medieval trim may survive'' line. Practical consequence: a small number of Fantasy-pack pieces may ship near-as-is where they read as intentional fashion; the basic set itself stays modern.
Art direction CONSOLIDATED (user, 2026-07-06 — supersedes the two notes above): the Reach has no single clothing style — ALL styles coexist, with modern/cyberpunk probably the most prevalent. Style is a prevalence DISTRIBUTION, not a genre rule, and may eventually vary by culture/settlement (fits the simulation DNA; fashion-as-cultural-data is a later phase concern, not this ticket). Consequences now: (1) the engine is style-agnostic by construction (slots/tints/logos carry no genre); (2) the basic set targets the prevalent center — modern casual + corporate — because it dresses the most NPCs and the shopping experience; (3) garments get a lightweight style tag in the manifest (e.g. style: modern|formal|fantasy|utility) as the cheap seam so per-culture distributions can be authored later without retrofitting; (4) Fantasy-pack pieces are legitimate catalogue members under their own tag, prevalence-weighted low.
Scope pin (user, 2026-07-06, final word on style): for simplicity, THIS ticket ships ONE style only — cyberpunk/modern. The pluralistic distribution model above remains the long-term truth (keep the manifest style tag as the seam), but the v1 basic set is single-style; other styles are catalogue growth, not scope.
Route challenge (user, 2026-07-06): not sold on staying Quaternius-primary — ''Quaternius is limited and will move the wall at too slow a pace; I''d rather pick something that has what we need now.'' Fresh store verification (2026-07-06): Sidekick packs are one-time USD199.99, perpetual, engine-agnostic license (Godot legal, unsupported); NO raw FBX — extraction from unitypackage (community-proven: unitypackage_godot, third-party Sidekick Creator Godot plugin incl. body blend shapes); ''Sold out'' labels are a broken-theme artifact per Shopify JSON (needs one browser cart check); SyntyPass rejected (assets stop being developable after cancel). Relevant packs: Starter (FREE, 57+91 parts), Modern Civilians (165 parts = v1 basic set territory), Sci-Fi Civilians (103 parts, cyberpunk accents), Modern Police (uniforms/officials). DECISION NOW GATED ON THE FREE SPIKE: user downloads free Starter Pack -> Bridge-C spike (extract garment -> Robust Weight Transfer onto our rig -> 11-body batch -> animation QA in T-1088 sandbox). Pass -> buy Modern Civilians, Synty = primary garment supply (+UAL1/UAL2 Source ~USD30 for clips — no Synty substitute exists for Godot animations; Fantasy Outfits Source drops to low priority under the single-style pin). Fail -> hand-author route stands. Stay-vs-pivot governance record HELD until spike evidence lands.
Scope guard (user concern, 2026-07-06): Synty intake must NOT displace the create-stuff-yourself pipeline — the user''s goal includes in-house garment creation capability, not just swapping vendor catalogs. Resolution: three-route portfolio sharing one engine — (a) Synty intake = variety bootstrap only; (b) derivation scripting (cuts/merges/retexture, agent-automatable) = create-yourself lite, turns any donor topology into original designs; (c) TRUE AUTHORING on owned UBC Source body .blends = the pipeline proper. GUARANTEE: the colorable uniform and black suit (no donor exists in any pack) are built via route (c) as the authoring pipeline''s end-to-end proof — non-negotiable deliverable of this ticket, so the pipeline exists even if Synty covers everything else. Spike status: extraction done inline by lead (158 FBX, sci-fi civilian theme confirmed); DECISIVE finding — Sidekick rig is UE-Mannequin-named, 52/65 bone-name overlap with our rig, sample garment binds to 12 vgroups of which 11 match ours exactly (only head->Head case rename) => transplant likely rename-and-rebind, far cheaper than the weight-transfer the pivot eval assumed; body blend shapes travel in the FBX. Transplant phase parked pending API recovery / token-window reset.
ROUTE DECISION (user, 2026-07-06, final): Synty intake REJECTED despite the spike''s technical PASS — (1) USD199.99/pack is too expensive; (2) Sidekick modularity is baked body-segment swap (clothes fused to body chunks), incompatible with our layered clothing-over-body system (11 bodies, skin tones, slot swapping); (3) user dislikes the Synty style. The spike still paid: transplant/batch scripts are source-agnostic and become the G1-family production pipeline; T-1090 (5 bodies broken bare) discovered; the Synty question is closed with evidence, not parked. OPERATIVE ROUTE: (b) derive from owned Fantasy parts + (c) hand-author — with a new preferred authoring technique: OFFSET-SHELL FROM OUR OWN BODY MESHES (extract body segment surface, offset outward into garment shell, cut neckline/hem/sleeves; weights inherited by construction, style fully ours, USD0). Suit + uniform remain the full hand-author proof. Purchases still open (separate concerns): UAL1/UAL2 Source ~USD30 for animation clips; Fantasy Outfits Source USD20 low-priority convenience.
Chromakey garment-QA harness DELIVERED (2026-07-06, commits eaca6c8c4/74fa16260/b09a50efb): two-pass depth-proximity clip detection — pass A keys covered body segments magenta, pass B re-renders garment-only with a depth-only 3cm epsilon bias toward camera; analyzer splits key pixels into exposed_skin (informational — sleeveless arms, collars) vs clip_through (gating — skin within 3cm in front of cloth). Run: tooling/garment-qa/run-garment-qa <config>. Verified on the peasant set (avg_m/f x Walk/Sprint/Crouch_Fwd x 3 frames x 4 yaws): 0/18 front-view false positives; genuine findings = sleeveless armhole seam (avg_f, sides), deep-crouch waist gap (worst 150px, back), collar nape. First real fit observations already on record for the peasant set. Sensitivity: clip_epsilon_m + --min-pixels, to calibrate against the first modern garments. This is the acceptance gate for every garment the wardrobe pipeline produces; pair with the T-1088 sandbox for in-world walk QA.
ENGINE DELIVERED (2026-07-06, commits e22ea0fa4 + 278e8b7c2; earlier eaca6c8c4/74fa16260/b09a50efb chromakey, b54b8189d bodies): G1 skinned batch-fit (blender_batch_fit_skinned.py), offset-shell authoring (blender_author_offset_shell.py — route c create-yourself, weights by construction, procedural RGBA masks, UV2 chest channel), toon_garment.gdshader (channel-blended 4-region tint + logo after-tint/before-toon), compositor plumb (multi_region coverage flag -> garment shader; descriptor clothing_logos: per-character brand choice), thrds logo stub, manifest style tag + logo_capable. PROOF: tshirt_modern on 6 healthy bodies, 18-assertion suite green, 216-capture chromakey QA. ROUTE GUIDANCE from QA evidence (Q-060): single-reference SD-fit of offset-shells degrades with girth divergence (muscular_m worst 859px clip at 24mm standoff; reference body clean) — offset-shell garments should be authored PER BODY (needs per-body masks + runtime <body>_mask.png loading, small change); SD-fit remains right for derived/hand-authored garments sharing one mask (suit, uniform, Fantasy cuts). REMAINING for this ticket: refit tshirt to the 5 repaired forks (T-1090 done — add to --only and rerun), per-body shell mode, then the basic set: hoodie, button-down, shorts, jeans, formal pants, jacket + the suit/uniform hand-author proof; creation-screen try-on UI for tints/logos.
Basic-set EXPANSION (user, 2026-07-06 bedtime directive: ''full set of the basics across the board''): wave 2 after the in-flight wave 1 — FOOTWEAR: sneakers_modern (trainers, everyday default), shoes_formal (suit pairing), boots_modern (ankle height); SPORT: tank_top (sleeveless, logo-capable), joggers_modern (cuffed, track-stripe tint region), track_jacket (with joggers = the training suit, logo-capable); SWIM: swim_trunks (bright), swimsuit_onepiece (color-block regions). Foot garments follow the peasant_shoes both-feet convention; sole geometry as an offset-shell param extension. Total modern catalogue after wave 2: 17 garments across tops/bottoms/feet/full-body x casual/formal/sport/swim. DEFERRED deliberately: hats/accessories — accessory slot path is unexercised and T-721 flags a filter bug; needs daylight, not a 3am debug. Overnight sequence: wave 1 -> wave 2 -> full garment x 11-body fitting matrix (the ''T-1090 fittings'' check, fork bodies especially) -> commits -> gated pushes -> morning report.
Fill-in-the-blanks addendum (user bedtime directive 2 + lead judgment): wave 2 grows to 12 — adds sweater_modern (crew pullover), cargo_pants (utility/cyberpunk staple), parka_thrds (cold-weather was absent entirely; ships as the FIRST CANON-BRANDED garment — thrds is Braemar''s cold-weather fiber brand per wiki; hip-length to avoid the parked skirt-rigging tier), slides (swim footwear, near-free). PLUS outfit presets: data file of named complete looks (casual/business/sport/beach/worker/sleep as tint-palette presets over garments) authored by the lead at integration — makes the catalogue usable for NPC dressing and the shop as OUTFITS, not just items. Post-wave-2 catalogue: 21 modern pieces (tops 8 / bottoms 6 / feet 4 / full-body 2 / swim 3). Hats/accessories remain the deliberate daylight deferral (T-721).', 'Fable-5-window sidequest workstream 2 (user directive 2026-07-06, extends T-1088 scope family): build the clothing ENGINE and a basic set now, park variety for later. Target bar: RimWorld''s original apparel breadth — varied enough to not feel limiting. Goal experience: being able to pick and SHOP for clothes — colorize + slap logos on casualwear. Basic set: t-shirt (logo-capable), hoodie (logo-capable), button-down shirt, shorts, jeans, formal pants, jacket, colorable uniform, black suit (moved up so officials are includable). Skipped by explicit call: capes, dresses/skirts (parked — difficulty tier). Engine deliverables: (1) multi-region tint masks — requires Quaternius Source tier files (USD5 Patreon month, one-time download, CC0 retained — user purchase action); (2) logo decal region on garment chest UV — flat 2D artwork per D-244, diegetic hook into economy generated brands (wiki/economics/corporations/generated_brands.toml) for brand-logo shirts; (3) manifest + CharacterVisualDescriptor category coverage (slots/tints already generic); (4) batch-fit each authored garment to all 11 body types via the validated Sprint-28 Blender Surface Deform pipeline (tooling/blender_*.py). Authoring routes per garment TBD by feasibility pass: derive from owned Fantasy pack meshes (62 parts, e.g. tunic->tshirt sleeve cut, pants->shorts hem cut) vs hand-author low-poly on the 65-bone rig (Garment Tool). Related: T-1088 locomotion sandbox doubles as the garment-under-animation QA rig (cycle outfits through Walk/Sprint/Crouch_Fwd).
Correction (2026-07-06): Source tier is PARTIALLY owned already — docs/assets/downloads/ (gitignored vendor archives, present in both checkouts) holds Universal Base Characters[Source] (630MB: full .blend files for all 6 base bodies incl. FullBody + OnlyHead variants, hairstyle .blends origin-at-0 + rigged-to-head-bone, texture masters, Godot engine project) plus UBC[Standard], UAL 1+2[Standard], Modular Character Outfits Fantasy[Standard]. NOT owned: Fantasy Outfits[Source] — the garment recolor masks + named vertex groups. Consequence: authoring NEW garments is fully unblocked (author against source body .blends, create our own tint masks/vertex groups — no purchase needed); only pack-DERIVED garments'' clean masks would want one more USD5 Patreon month, decision deferred until the feasibility route table says how much derivation we actually use.
Art direction (user, 2026-07-06): garments read CYBERPUNK/MODERN — near-future everyday civilian + corporate wear — NOT fantasy/medieval. The owned Fantasy pack is at most a topology donor (low-poly base shapes like pants/shirts are genre-neutral; genre lives in silhouette details, textures, trims, and accessories) — no medieval trim/textures may survive into shipped garments. Weight the authoring routes accordingly: texture identity matters as much as mesh. Canon hook: the wiki already ships a garment brand — thrds (wiki/star-systems/GJ-475/index.md, Braemar fiber cooperative, corridor fashion markets) — so branded clothing connects to Phase-1 lore, not only generated_brands.toml. This emphasis also feeds the Quaternius-pivot evaluation: commercial alternatives skew sci-fi/urban while Quaternius clothing is fantasy-only.
Nuance (user, 2026-07-06): the cyberpunk/modern direction is the DEFAULT, not a prohibition — fashion in the Reach is cyclical, so fantasy/medieval-flavored garments may appear here and there as deliberate fashion statements (subculture pieces, luxury/revival trims, statement outerwear). Supersedes the previous note''s hard ''no medieval trim may survive'' line. Practical consequence: a small number of Fantasy-pack pieces may ship near-as-is where they read as intentional fashion; the basic set itself stays modern.
Art direction CONSOLIDATED (user, 2026-07-06 — supersedes the two notes above): the Reach has no single clothing style — ALL styles coexist, with modern/cyberpunk probably the most prevalent. Style is a prevalence DISTRIBUTION, not a genre rule, and may eventually vary by culture/settlement (fits the simulation DNA; fashion-as-cultural-data is a later phase concern, not this ticket). Consequences now: (1) the engine is style-agnostic by construction (slots/tints/logos carry no genre); (2) the basic set targets the prevalent center — modern casual + corporate — because it dresses the most NPCs and the shopping experience; (3) garments get a lightweight style tag in the manifest (e.g. style: modern|formal|fantasy|utility) as the cheap seam so per-culture distributions can be authored later without retrofitting; (4) Fantasy-pack pieces are legitimate catalogue members under their own tag, prevalence-weighted low.
Scope pin (user, 2026-07-06, final word on style): for simplicity, THIS ticket ships ONE style only — cyberpunk/modern. The pluralistic distribution model above remains the long-term truth (keep the manifest style tag as the seam), but the v1 basic set is single-style; other styles are catalogue growth, not scope.
Route challenge (user, 2026-07-06): not sold on staying Quaternius-primary — ''Quaternius is limited and will move the wall at too slow a pace; I''d rather pick something that has what we need now.'' Fresh store verification (2026-07-06): Sidekick packs are one-time USD199.99, perpetual, engine-agnostic license (Godot legal, unsupported); NO raw FBX — extraction from unitypackage (community-proven: unitypackage_godot, third-party Sidekick Creator Godot plugin incl. body blend shapes); ''Sold out'' labels are a broken-theme artifact per Shopify JSON (needs one browser cart check); SyntyPass rejected (assets stop being developable after cancel). Relevant packs: Starter (FREE, 57+91 parts), Modern Civilians (165 parts = v1 basic set territory), Sci-Fi Civilians (103 parts, cyberpunk accents), Modern Police (uniforms/officials). DECISION NOW GATED ON THE FREE SPIKE: user downloads free Starter Pack -> Bridge-C spike (extract garment -> Robust Weight Transfer onto our rig -> 11-body batch -> animation QA in T-1088 sandbox). Pass -> buy Modern Civilians, Synty = primary garment supply (+UAL1/UAL2 Source ~USD30 for clips — no Synty substitute exists for Godot animations; Fantasy Outfits Source drops to low priority under the single-style pin). Fail -> hand-author route stands. Stay-vs-pivot governance record HELD until spike evidence lands.
Scope guard (user concern, 2026-07-06): Synty intake must NOT displace the create-stuff-yourself pipeline — the user''s goal includes in-house garment creation capability, not just swapping vendor catalogs. Resolution: three-route portfolio sharing one engine — (a) Synty intake = variety bootstrap only; (b) derivation scripting (cuts/merges/retexture, agent-automatable) = create-yourself lite, turns any donor topology into original designs; (c) TRUE AUTHORING on owned UBC Source body .blends = the pipeline proper. GUARANTEE: the colorable uniform and black suit (no donor exists in any pack) are built via route (c) as the authoring pipeline''s end-to-end proof — non-negotiable deliverable of this ticket, so the pipeline exists even if Synty covers everything else. Spike status: extraction done inline by lead (158 FBX, sci-fi civilian theme confirmed); DECISIVE finding — Sidekick rig is UE-Mannequin-named, 52/65 bone-name overlap with our rig, sample garment binds to 12 vgroups of which 11 match ours exactly (only head->Head case rename) => transplant likely rename-and-rebind, far cheaper than the weight-transfer the pivot eval assumed; body blend shapes travel in the FBX. Transplant phase parked pending API recovery / token-window reset.
ROUTE DECISION (user, 2026-07-06, final): Synty intake REJECTED despite the spike''s technical PASS — (1) USD199.99/pack is too expensive; (2) Sidekick modularity is baked body-segment swap (clothes fused to body chunks), incompatible with our layered clothing-over-body system (11 bodies, skin tones, slot swapping); (3) user dislikes the Synty style. The spike still paid: transplant/batch scripts are source-agnostic and become the G1-family production pipeline; T-1090 (5 bodies broken bare) discovered; the Synty question is closed with evidence, not parked. OPERATIVE ROUTE: (b) derive from owned Fantasy parts + (c) hand-author — with a new preferred authoring technique: OFFSET-SHELL FROM OUR OWN BODY MESHES (extract body segment surface, offset outward into garment shell, cut neckline/hem/sleeves; weights inherited by construction, style fully ours, USD0). Suit + uniform remain the full hand-author proof. Purchases still open (separate concerns): UAL1/UAL2 Source ~USD30 for animation clips; Fantasy Outfits Source USD20 low-priority convenience.
Chromakey garment-QA harness DELIVERED (2026-07-06, commits eaca6c8c4/74fa16260/b09a50efb): two-pass depth-proximity clip detection — pass A keys covered body segments magenta, pass B re-renders garment-only with a depth-only 3cm epsilon bias toward camera; analyzer splits key pixels into exposed_skin (informational — sleeveless arms, collars) vs clip_through (gating — skin within 3cm in front of cloth). Run: tooling/garment-qa/run-garment-qa <config>. Verified on the peasant set (avg_m/f x Walk/Sprint/Crouch_Fwd x 3 frames x 4 yaws): 0/18 front-view false positives; genuine findings = sleeveless armhole seam (avg_f, sides), deep-crouch waist gap (worst 150px, back), collar nape. First real fit observations already on record for the peasant set. Sensitivity: clip_epsilon_m + --min-pixels, to calibrate against the first modern garments. This is the acceptance gate for every garment the wardrobe pipeline produces; pair with the T-1088 sandbox for in-world walk QA.
ENGINE DELIVERED (2026-07-06, commits e22ea0fa4 + 278e8b7c2; earlier eaca6c8c4/74fa16260/b09a50efb chromakey, b54b8189d bodies): G1 skinned batch-fit (blender_batch_fit_skinned.py), offset-shell authoring (blender_author_offset_shell.py — route c create-yourself, weights by construction, procedural RGBA masks, UV2 chest channel), toon_garment.gdshader (channel-blended 4-region tint + logo after-tint/before-toon), compositor plumb (multi_region coverage flag -> garment shader; descriptor clothing_logos: per-character brand choice), thrds logo stub, manifest style tag + logo_capable. PROOF: tshirt_modern on 6 healthy bodies, 18-assertion suite green, 216-capture chromakey QA. ROUTE GUIDANCE from QA evidence (Q-060): single-reference SD-fit of offset-shells degrades with girth divergence (muscular_m worst 859px clip at 24mm standoff; reference body clean) — offset-shell garments should be authored PER BODY (needs per-body masks + runtime <body>_mask.png loading, small change); SD-fit remains right for derived/hand-authored garments sharing one mask (suit, uniform, Fantasy cuts). REMAINING for this ticket: refit tshirt to the 5 repaired forks (T-1090 done — add to --only and rerun), per-body shell mode, then the basic set: hoodie, button-down, shorts, jeans, formal pants, jacket + the suit/uniform hand-author proof; creation-screen try-on UI for tints/logos.
Basic-set EXPANSION (user, 2026-07-06 bedtime directive: ''full set of the basics across the board''): wave 2 after the in-flight wave 1 — FOOTWEAR: sneakers_modern (trainers, everyday default), shoes_formal (suit pairing), boots_modern (ankle height); SPORT: tank_top (sleeveless, logo-capable), joggers_modern (cuffed, track-stripe tint region), track_jacket (with joggers = the training suit, logo-capable); SWIM: swim_trunks (bright), swimsuit_onepiece (color-block regions). Foot garments follow the peasant_shoes both-feet convention; sole geometry as an offset-shell param extension. Total modern catalogue after wave 2: 17 garments across tops/bottoms/feet/full-body x casual/formal/sport/swim. DEFERRED deliberately: hats/accessories — accessory slot path is unexercised and T-721 flags a filter bug; needs daylight, not a 3am debug. Overnight sequence: wave 1 -> wave 2 -> full garment x 11-body fitting matrix (the ''T-1090 fittings'' check, fork bodies especially) -> commits -> gated pushes -> morning report.
Fill-in-the-blanks addendum (user bedtime directive 2 + lead judgment): wave 2 grows to 12 — adds sweater_modern (crew pullover), cargo_pants (utility/cyberpunk staple), parka_thrds (cold-weather was absent entirely; ships as the FIRST CANON-BRANDED garment — thrds is Braemar''s cold-weather fiber brand per wiki; hip-length to avoid the parked skirt-rigging tier), slides (swim footwear, near-free). PLUS outfit presets: data file of named complete looks (casual/business/sport/beach/worker/sleep as tint-palette presets over garments) authored by the lead at integration — makes the catalogue usable for NPC dressing and the shop as OUTFITS, not just items. Post-wave-2 catalogue: 21 modern pieces (tops 8 / bottoms 6 / feet 4 / full-body 2 / swim 3). Hats/accessories remain the deliberate daylight deferral (T-721).
ACCEPTED for first release (user review, 2026-07-07): full catalogue + lookbook approved; toe-box fix reviewed — ''I still see some toes, but this will do''. Residual toe hints on closed footwear accepted as first-release quality; further toe-box smoothing is polish backlog, not scope. Closing.', NULL, '2026-07-07 12:04:38', '2026-07-07 12:04:38.700', '2026-07-07 12:04:38.700', NULL, '8fd724c63e771a5cef9dd2120aa022ec', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCPBF41RWK9PW9M22Q7961C', 'status', 'review', 'done', NULL, '2026-07-07 12:04:49', '2026-07-07 12:04:49.833', '2026-07-07 12:04:49.833', NULL, '69ad0ce426a5cf65efe7df5dc06161ef', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKR283RTWYXD2M005K65S52M', 'status', 'backlog', 'done', NULL, '2026-07-07 12:08:15', '2026-07-07 12:08:15.679', '2026-07-07 12:08:15.679', NULL, 'abf3b8af8fd454d6a75ca095b6d57908', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCER95EK266H8RWPW8XT1F0', 'description', 'Fable-5-window sidequest (sanctioned cascade exception, 2026-07-05): the presentation layer that turns discrete server tile steps into a believable walking 3D character. Scope: 3D sandbox dev scene (SR_LIVE=1, greybox tiles derived from server snapshots, no hand-authored map), CharacterVisual instantiated in-world, locomotion rig (tile-step + facing-octant interpolation, stance-aware speeds), UAL animation state machine (idle/walk/sprint/careful/crouch), D-148 camera rig (30deg low-angle follow, 45deg rotation). Server-authoritative from day one — no client-local movement model. Builds on D-148/D-149/D-244/D-066 and the T-417 stance system. If the Fable 5 window closes mid-flight, work parks here.
Visual reference (user, 2026-07-06): Xenonauts 2 nails the target tiles/occlusion/character perspective — readable tile grid, low-angle tactical camera with angle options (matches D-148 30deg low-angle + 45deg rotation steps and the spikes/3dpipeline angle presets), and crucially its wall/roof occlusion treatment: camera-facing walls cut down/ghosted so interiors stay readable, floors peel per z-level. One deliberate difference: our camera locks to the player character (D-015/T-116) — no free map panning. Implication for the locomotion sandbox: greybox walls should prototype camera-facing cutaway occlusion early, since wall readability interacts with the locked low-angle camera.
Scoping call (user + lead agreement, 2026-07-06): wall cutaway is CLIENT-SIDE presentation, decoupled from fog-of-perception. Rationale: two occlusion systems with different subjects — perception/fog governs what the CHARACTER knows (server-enforced info boundary; client only receives observer-filtered geometry), cutaway governs what the PLAYER''S CAMERA sees (pure render mode on wall data the client already holds). They compose: cutaway cuts render height; fog overlay still gates what is visible behind. Walls remain first-class client data objects (future destruction/explosion interactions), cutaway is a render mode on them like tint/LOD. Nuance parked for Phase 5 proper: destroyed-while-unobserved walls should render in remembered state (fog-memory applied to geometry). If this holds through implementation, mint a D-record (perception domain) when the sidequest lands.
Animation supply resolved (2026-07-06): user purchased UAL1[Source+Pro] (120 clips, identical lists) + UAL2[Source] (134 clips), unzipped in docs/assets/downloads/. Gains: Turn90_L/R + Turn180_L/R (turn-in-place), Sprint_Enter/Exit + Crouch_Enter/Exit (stance transitions), full 8-direction Walk/Jog/Crouch sets incl. diagonals, Counter_Idle + talking/phone/sitting idles (life-sim verbs), plus _RM root-motion variants (unused — in-place is correct for server-authoritative interpolation). Still absent everywhere: walk start/stop + stairs — the only remaining custom clips. Integration is NOT a drop-in swap: upstream renamed clips (Walk_Loop -> Walk_Fwd_Loop etc.), so wire via the design''s recorded plan — explicit library names + lib/Clip addressing + gait-table update. NOTE for facing design: the 8-dir walk sets unlock Q-084''s parked walk-vs-aim split (direction-matched clips relative to facing) — revisit during the S9 tuning session.
Live-session feedback (user, 2026-07-06): (1) Corridor cutaway verdict — two minds: ''extremely trippy, could be the game''s own look'' vs ''player cannot see what is in the room unless close''. Resolution: cutaway MODES, toggled live in the sandbox (corridor / bottom-walls-low / both) — bottom-wall rule is data-driven (wall drops to stub when a KNOWN floor tile sits on its camera-far side; camera-facing directions derived from WorldRoot basis at runtime, not hand-derived). Default picked by feel during the session; the trippy corridor stays available as a signature-look option. (2) NEW: mouse-over move-here marker on the hovered tile + optimal path line — client-side A* over the never-evict KNOWN tile store (info-boundary-honest: the character plans only through known tiles; fog is unpathable), 8-dir with diagonal step cost 1 (time-optimal per the no-sqrt2 wire), terrain-cost provider seam (uniform today, Phase-4 terrain later), click executes by streaming ordinary Move* step commands through the existing throttle (zero protocol change, server validates every step), cancelled by WASD override / path invalidation / arrival. Settles more of Q-084 (click-to-move half).
RMB gesture vocabulary (user, live session 2026-07-06, added to the path-preview feature): single right-click = walk there (current stance); DOUBLE right-click = sprint there (ladder ToggleStanceUp burst to Sprint via the ordinary command queue, pre-sprint stance RESTORED on arrival; a double upgrades the already-started follow in place); LONG-PRESS right-click (~0.4s, commit on release) = ''take cover at location'', prototyped as go-there-then-Crouch-on-arrival (no restore — crouching was the point). Real cover mechanics (wall adjacency, directional protection) are future combat design; the gesture is the input-vocabulary prototype. WASD always cancels any follow without stance restore (player override is deliberate).
Follow-facing refinement (user, live session 2026-07-06): during an RMB path-follow the BODY commits to the leg/movement direction (mouse no longer swings body yaw); the mouse instead drives a LAYERED LOOK-AT — Head bone (~70deg limit) plus torso twist via a spine bone (~30deg) for looking far lateral/behind; beyond their sum the character physically cannot look further without turning (correct). Pure client presentation on the D-249 model; SetFacing continues to ride the wire during follows, so the SERVER vision cone still follows the mouse (diegetic: the character looks where the player points while walking a committed path). Implementation: Godot LookAtModifier3D pair under the CharacterVisual skeleton, influence-faded in/out on follow start/end; rig gains a commit_body_to_motion flag (yaw from leg velocity while set).', 'Fable-5-window sidequest (sanctioned cascade exception, 2026-07-05): the presentation layer that turns discrete server tile steps into a believable walking 3D character. Scope: 3D sandbox dev scene (SR_LIVE=1, greybox tiles derived from server snapshots, no hand-authored map), CharacterVisual instantiated in-world, locomotion rig (tile-step + facing-octant interpolation, stance-aware speeds), UAL animation state machine (idle/walk/sprint/careful/crouch), D-148 camera rig (30deg low-angle follow, 45deg rotation). Server-authoritative from day one — no client-local movement model. Builds on D-148/D-149/D-244/D-066 and the T-417 stance system. If the Fable 5 window closes mid-flight, work parks here.
Visual reference (user, 2026-07-06): Xenonauts 2 nails the target tiles/occlusion/character perspective — readable tile grid, low-angle tactical camera with angle options (matches D-148 30deg low-angle + 45deg rotation steps and the spikes/3dpipeline angle presets), and crucially its wall/roof occlusion treatment: camera-facing walls cut down/ghosted so interiors stay readable, floors peel per z-level. One deliberate difference: our camera locks to the player character (D-015/T-116) — no free map panning. Implication for the locomotion sandbox: greybox walls should prototype camera-facing cutaway occlusion early, since wall readability interacts with the locked low-angle camera.
Scoping call (user + lead agreement, 2026-07-06): wall cutaway is CLIENT-SIDE presentation, decoupled from fog-of-perception. Rationale: two occlusion systems with different subjects — perception/fog governs what the CHARACTER knows (server-enforced info boundary; client only receives observer-filtered geometry), cutaway governs what the PLAYER''S CAMERA sees (pure render mode on wall data the client already holds). They compose: cutaway cuts render height; fog overlay still gates what is visible behind. Walls remain first-class client data objects (future destruction/explosion interactions), cutaway is a render mode on them like tint/LOD. Nuance parked for Phase 5 proper: destroyed-while-unobserved walls should render in remembered state (fog-memory applied to geometry). If this holds through implementation, mint a D-record (perception domain) when the sidequest lands.
Animation supply resolved (2026-07-06): user purchased UAL1[Source+Pro] (120 clips, identical lists) + UAL2[Source] (134 clips), unzipped in docs/assets/downloads/. Gains: Turn90_L/R + Turn180_L/R (turn-in-place), Sprint_Enter/Exit + Crouch_Enter/Exit (stance transitions), full 8-direction Walk/Jog/Crouch sets incl. diagonals, Counter_Idle + talking/phone/sitting idles (life-sim verbs), plus _RM root-motion variants (unused — in-place is correct for server-authoritative interpolation). Still absent everywhere: walk start/stop + stairs — the only remaining custom clips. Integration is NOT a drop-in swap: upstream renamed clips (Walk_Loop -> Walk_Fwd_Loop etc.), so wire via the design''s recorded plan — explicit library names + lib/Clip addressing + gait-table update. NOTE for facing design: the 8-dir walk sets unlock Q-084''s parked walk-vs-aim split (direction-matched clips relative to facing) — revisit during the S9 tuning session.
Live-session feedback (user, 2026-07-06): (1) Corridor cutaway verdict — two minds: ''extremely trippy, could be the game''s own look'' vs ''player cannot see what is in the room unless close''. Resolution: cutaway MODES, toggled live in the sandbox (corridor / bottom-walls-low / both) — bottom-wall rule is data-driven (wall drops to stub when a KNOWN floor tile sits on its camera-far side; camera-facing directions derived from WorldRoot basis at runtime, not hand-derived). Default picked by feel during the session; the trippy corridor stays available as a signature-look option. (2) NEW: mouse-over move-here marker on the hovered tile + optimal path line — client-side A* over the never-evict KNOWN tile store (info-boundary-honest: the character plans only through known tiles; fog is unpathable), 8-dir with diagonal step cost 1 (time-optimal per the no-sqrt2 wire), terrain-cost provider seam (uniform today, Phase-4 terrain later), click executes by streaming ordinary Move* step commands through the existing throttle (zero protocol change, server validates every step), cancelled by WASD override / path invalidation / arrival. Settles more of Q-084 (click-to-move half).
RMB gesture vocabulary (user, live session 2026-07-06, added to the path-preview feature): single right-click = walk there (current stance); DOUBLE right-click = sprint there (ladder ToggleStanceUp burst to Sprint via the ordinary command queue, pre-sprint stance RESTORED on arrival; a double upgrades the already-started follow in place); LONG-PRESS right-click (~0.4s, commit on release) = ''take cover at location'', prototyped as go-there-then-Crouch-on-arrival (no restore — crouching was the point). Real cover mechanics (wall adjacency, directional protection) are future combat design; the gesture is the input-vocabulary prototype. WASD always cancels any follow without stance restore (player override is deliberate).
Follow-facing refinement (user, live session 2026-07-06): during an RMB path-follow the BODY commits to the leg/movement direction (mouse no longer swings body yaw); the mouse instead drives a LAYERED LOOK-AT — Head bone (~70deg limit) plus torso twist via a spine bone (~30deg) for looking far lateral/behind; beyond their sum the character physically cannot look further without turning (correct). Pure client presentation on the D-249 model; SetFacing continues to ride the wire during follows, so the SERVER vision cone still follows the mouse (diegetic: the character looks where the player points while walking a committed path). Implementation: Godot LookAtModifier3D pair under the CharacterVisual skeleton, influence-faded in/out on follow start/end; rig gains a commit_body_to_motion flag (yaw from leg velocity while set).
SIDEQUEST CLOSE-OUT (2026-07-07): all scope delivered and pushed — sandbox (scene, greybox store, rig, gait machine, camera, cutaway modes w/ user-verdict mode-2 default recorded as D-250 amendment), RMB navigation vocabulary, layered head/torso look-at, D-252 view/movement protocol split (server+client), purchased UAL tiers wired (turn-in-place, stance enter/exits), design doc committed to docs/design/t1088-locomotion-sandbox-design.md (the ''design §'' references in sandbox code resolve in-repo now). Design-delta close-out notes: no new Gauntlet room was needed (constraint 12 never triggered, server untouched except D-252); ~40 lines of main.gd boot boilerplate duplicated with Pattern: markers for the T-962 extraction; seek-during-blend + remove_immutable_tracks caveats did not manifest in practice; ual_extended wiring superseded by the purchased-tier ual1/ual2 libraries; 2D select_yaw_target moving-branch is dead code post-D-252 (cleanup rides Phase 5). Remaining feel work parked as T-1096 (S9 live tuning — needs the user). Closing.', NULL, '2026-07-07 12:10:20', '2026-07-07 12:10:20.956', '2026-07-07 12:10:20.956', NULL, '846e89916f601a4622a03b275f200bc6', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCER95EK266H8RWPW8XT1F0', 'status', 'backlog', 'done', NULL, '2026-07-07 12:10:20', '2026-07-07 12:10:20.986', '2026-07-07 12:10:20.986', NULL, '3016244358c491462e72331ef063ed35', 2) ON CONFLICT(hash) DO NOTHING;
+1
View File
@@ -9,3 +9,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKHFRCP5R0VBA9BKR97RRBJ0', 'T-1093', '2026-07-06 18:44:32.562', '2026-07-06 18:44:32.562', NULL, 'ce581695739eea8cd11433cb9f6c86d1', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKJ25KG3ADM4M5XRXCVR2GQG', 'T-1094', '2026-07-06 20:04:59.393', '2026-07-06 20:04:59.393', NULL, 'e856fa3f89f621007a058db26aff2a05', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKR283RTWYXD2M005K65S52M', 'T-1095', '2026-07-07 10:04:11.591', '2026-07-07 10:04:11.591', NULL, 'e0a6ad2c4dce20a444a5af47d49b36c7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKRZ29KH70NFAY0Z1GCVR4N0', 'T-1096', '2026-07-07 12:10:06.109', '2026-07-07 12:10:06.109', NULL, 'bdf196e11c21f894bf01c08b10371ab7', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash);
+86
View File
@@ -817,3 +817,89 @@ Basic-set EXPANSION (user, 2026-07-06 bedtime directive: ''full set of the basic
Fill-in-the-blanks addendum (user bedtime directive 2 + lead judgment): wave 2 grows to 12 — adds sweater_modern (crew pullover), cargo_pants (utility/cyberpunk staple), parka_thrds (cold-weather was absent entirely; ships as the FIRST CANON-BRANDED garment — thrds is Braemar''s cold-weather fiber brand per wiki; hip-length to avoid the parked skirt-rigging tier), slides (swim footwear, near-free). PLUS outfit presets: data file of named complete looks (casual/business/sport/beach/worker/sleep as tint-palette presets over garments) authored by the lead at integration — makes the catalogue usable for NPC dressing and the shop as OUTFITS, not just items. Post-wave-2 catalogue: 21 modern pieces (tops 8 / bottoms 6 / feet 4 / full-body 2 / swim 3). Hats/accessories remain the deliberate daylight deferral (T-721).', 'review', 'high', NULL, 'client', NULL, '2026-07-06 07:34:18.656', '2026-07-07 09:23:38.257', NULL, '15fb82c297b4afafa017d7247c7ba67e', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKR283RTWYXD2M005K65S52M', 'bug', '06FB0TNSRXX29H5X0EB0F0GBW4', 'head_001 template renders grey (untinted) on child/teen/muscular bodies', 'Found by the T-1089 lookbook pass (2026-07-07): overlay head templates (head_001) render grey faces on child/teen/muscular bodies — the template appears not to receive the body''s skin-tone tint, while each body''s own seg_head renders correctly. Workaround used in the lookbook: head_id empty -> body seg_head shows. If head templates are meant to be body-agnostic (D-161 head-as-BoneAttachment3D), the skin-tone shader application needs to cover template heads per body; investigate _apply skin tone path in character_visual.gd for the head template branch.', 'backlog', 'medium', NULL, 'client', NULL, '2026-07-07 10:04:11.590', '2026-07-07 10:04:11.590', NULL, 'fee4a7bdc5705284493e52c31dd588c1', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCPBF41RWK9PW9M22Q7961C', 'story', '06FB0TNSRXX29H5X0EB0F0GBW4', 'Clothing catalogue engine + basic set — recolorable, logo-capable everyday garments', 'Fable-5-window sidequest workstream 2 (user directive 2026-07-06, extends T-1088 scope family): build the clothing ENGINE and a basic set now, park variety for later. Target bar: RimWorld''s original apparel breadth — varied enough to not feel limiting. Goal experience: being able to pick and SHOP for clothes — colorize + slap logos on casualwear. Basic set: t-shirt (logo-capable), hoodie (logo-capable), button-down shirt, shorts, jeans, formal pants, jacket, colorable uniform, black suit (moved up so officials are includable). Skipped by explicit call: capes, dresses/skirts (parked — difficulty tier). Engine deliverables: (1) multi-region tint masks — requires Quaternius Source tier files (USD5 Patreon month, one-time download, CC0 retained — user purchase action); (2) logo decal region on garment chest UV — flat 2D artwork per D-244, diegetic hook into economy generated brands (wiki/economics/corporations/generated_brands.toml) for brand-logo shirts; (3) manifest + CharacterVisualDescriptor category coverage (slots/tints already generic); (4) batch-fit each authored garment to all 11 body types via the validated Sprint-28 Blender Surface Deform pipeline (tooling/blender_*.py). Authoring routes per garment TBD by feasibility pass: derive from owned Fantasy pack meshes (62 parts, e.g. tunic->tshirt sleeve cut, pants->shorts hem cut) vs hand-author low-poly on the 65-bone rig (Garment Tool). Related: T-1088 locomotion sandbox doubles as the garment-under-animation QA rig (cycle outfits through Walk/Sprint/Crouch_Fwd).
Correction (2026-07-06): Source tier is PARTIALLY owned already — docs/assets/downloads/ (gitignored vendor archives, present in both checkouts) holds Universal Base Characters[Source] (630MB: full .blend files for all 6 base bodies incl. FullBody + OnlyHead variants, hairstyle .blends origin-at-0 + rigged-to-head-bone, texture masters, Godot engine project) plus UBC[Standard], UAL 1+2[Standard], Modular Character Outfits Fantasy[Standard]. NOT owned: Fantasy Outfits[Source] — the garment recolor masks + named vertex groups. Consequence: authoring NEW garments is fully unblocked (author against source body .blends, create our own tint masks/vertex groups — no purchase needed); only pack-DERIVED garments'' clean masks would want one more USD5 Patreon month, decision deferred until the feasibility route table says how much derivation we actually use.
Art direction (user, 2026-07-06): garments read CYBERPUNK/MODERN — near-future everyday civilian + corporate wear — NOT fantasy/medieval. The owned Fantasy pack is at most a topology donor (low-poly base shapes like pants/shirts are genre-neutral; genre lives in silhouette details, textures, trims, and accessories) — no medieval trim/textures may survive into shipped garments. Weight the authoring routes accordingly: texture identity matters as much as mesh. Canon hook: the wiki already ships a garment brand — thrds (wiki/star-systems/GJ-475/index.md, Braemar fiber cooperative, corridor fashion markets) — so branded clothing connects to Phase-1 lore, not only generated_brands.toml. This emphasis also feeds the Quaternius-pivot evaluation: commercial alternatives skew sci-fi/urban while Quaternius clothing is fantasy-only.
Nuance (user, 2026-07-06): the cyberpunk/modern direction is the DEFAULT, not a prohibition — fashion in the Reach is cyclical, so fantasy/medieval-flavored garments may appear here and there as deliberate fashion statements (subculture pieces, luxury/revival trims, statement outerwear). Supersedes the previous note''s hard ''no medieval trim may survive'' line. Practical consequence: a small number of Fantasy-pack pieces may ship near-as-is where they read as intentional fashion; the basic set itself stays modern.
Art direction CONSOLIDATED (user, 2026-07-06 — supersedes the two notes above): the Reach has no single clothing style — ALL styles coexist, with modern/cyberpunk probably the most prevalent. Style is a prevalence DISTRIBUTION, not a genre rule, and may eventually vary by culture/settlement (fits the simulation DNA; fashion-as-cultural-data is a later phase concern, not this ticket). Consequences now: (1) the engine is style-agnostic by construction (slots/tints/logos carry no genre); (2) the basic set targets the prevalent center — modern casual + corporate — because it dresses the most NPCs and the shopping experience; (3) garments get a lightweight style tag in the manifest (e.g. style: modern|formal|fantasy|utility) as the cheap seam so per-culture distributions can be authored later without retrofitting; (4) Fantasy-pack pieces are legitimate catalogue members under their own tag, prevalence-weighted low.
Scope pin (user, 2026-07-06, final word on style): for simplicity, THIS ticket ships ONE style only — cyberpunk/modern. The pluralistic distribution model above remains the long-term truth (keep the manifest style tag as the seam), but the v1 basic set is single-style; other styles are catalogue growth, not scope.
Route challenge (user, 2026-07-06): not sold on staying Quaternius-primary — ''Quaternius is limited and will move the wall at too slow a pace; I''d rather pick something that has what we need now.'' Fresh store verification (2026-07-06): Sidekick packs are one-time USD199.99, perpetual, engine-agnostic license (Godot legal, unsupported); NO raw FBX — extraction from unitypackage (community-proven: unitypackage_godot, third-party Sidekick Creator Godot plugin incl. body blend shapes); ''Sold out'' labels are a broken-theme artifact per Shopify JSON (needs one browser cart check); SyntyPass rejected (assets stop being developable after cancel). Relevant packs: Starter (FREE, 57+91 parts), Modern Civilians (165 parts = v1 basic set territory), Sci-Fi Civilians (103 parts, cyberpunk accents), Modern Police (uniforms/officials). DECISION NOW GATED ON THE FREE SPIKE: user downloads free Starter Pack -> Bridge-C spike (extract garment -> Robust Weight Transfer onto our rig -> 11-body batch -> animation QA in T-1088 sandbox). Pass -> buy Modern Civilians, Synty = primary garment supply (+UAL1/UAL2 Source ~USD30 for clips — no Synty substitute exists for Godot animations; Fantasy Outfits Source drops to low priority under the single-style pin). Fail -> hand-author route stands. Stay-vs-pivot governance record HELD until spike evidence lands.
Scope guard (user concern, 2026-07-06): Synty intake must NOT displace the create-stuff-yourself pipeline — the user''s goal includes in-house garment creation capability, not just swapping vendor catalogs. Resolution: three-route portfolio sharing one engine — (a) Synty intake = variety bootstrap only; (b) derivation scripting (cuts/merges/retexture, agent-automatable) = create-yourself lite, turns any donor topology into original designs; (c) TRUE AUTHORING on owned UBC Source body .blends = the pipeline proper. GUARANTEE: the colorable uniform and black suit (no donor exists in any pack) are built via route (c) as the authoring pipeline''s end-to-end proof — non-negotiable deliverable of this ticket, so the pipeline exists even if Synty covers everything else. Spike status: extraction done inline by lead (158 FBX, sci-fi civilian theme confirmed); DECISIVE finding — Sidekick rig is UE-Mannequin-named, 52/65 bone-name overlap with our rig, sample garment binds to 12 vgroups of which 11 match ours exactly (only head->Head case rename) => transplant likely rename-and-rebind, far cheaper than the weight-transfer the pivot eval assumed; body blend shapes travel in the FBX. Transplant phase parked pending API recovery / token-window reset.
ROUTE DECISION (user, 2026-07-06, final): Synty intake REJECTED despite the spike''s technical PASS — (1) USD199.99/pack is too expensive; (2) Sidekick modularity is baked body-segment swap (clothes fused to body chunks), incompatible with our layered clothing-over-body system (11 bodies, skin tones, slot swapping); (3) user dislikes the Synty style. The spike still paid: transplant/batch scripts are source-agnostic and become the G1-family production pipeline; T-1090 (5 bodies broken bare) discovered; the Synty question is closed with evidence, not parked. OPERATIVE ROUTE: (b) derive from owned Fantasy parts + (c) hand-author — with a new preferred authoring technique: OFFSET-SHELL FROM OUR OWN BODY MESHES (extract body segment surface, offset outward into garment shell, cut neckline/hem/sleeves; weights inherited by construction, style fully ours, USD0). Suit + uniform remain the full hand-author proof. Purchases still open (separate concerns): UAL1/UAL2 Source ~USD30 for animation clips; Fantasy Outfits Source USD20 low-priority convenience.
Chromakey garment-QA harness DELIVERED (2026-07-06, commits eaca6c8c4/74fa16260/b09a50efb): two-pass depth-proximity clip detection — pass A keys covered body segments magenta, pass B re-renders garment-only with a depth-only 3cm epsilon bias toward camera; analyzer splits key pixels into exposed_skin (informational — sleeveless arms, collars) vs clip_through (gating — skin within 3cm in front of cloth). Run: tooling/garment-qa/run-garment-qa <config>. Verified on the peasant set (avg_m/f x Walk/Sprint/Crouch_Fwd x 3 frames x 4 yaws): 0/18 front-view false positives; genuine findings = sleeveless armhole seam (avg_f, sides), deep-crouch waist gap (worst 150px, back), collar nape. First real fit observations already on record for the peasant set. Sensitivity: clip_epsilon_m + --min-pixels, to calibrate against the first modern garments. This is the acceptance gate for every garment the wardrobe pipeline produces; pair with the T-1088 sandbox for in-world walk QA.
ENGINE DELIVERED (2026-07-06, commits e22ea0fa4 + 278e8b7c2; earlier eaca6c8c4/74fa16260/b09a50efb chromakey, b54b8189d bodies): G1 skinned batch-fit (blender_batch_fit_skinned.py), offset-shell authoring (blender_author_offset_shell.py — route c create-yourself, weights by construction, procedural RGBA masks, UV2 chest channel), toon_garment.gdshader (channel-blended 4-region tint + logo after-tint/before-toon), compositor plumb (multi_region coverage flag -> garment shader; descriptor clothing_logos: per-character brand choice), thrds logo stub, manifest style tag + logo_capable. PROOF: tshirt_modern on 6 healthy bodies, 18-assertion suite green, 216-capture chromakey QA. ROUTE GUIDANCE from QA evidence (Q-060): single-reference SD-fit of offset-shells degrades with girth divergence (muscular_m worst 859px clip at 24mm standoff; reference body clean) — offset-shell garments should be authored PER BODY (needs per-body masks + runtime <body>_mask.png loading, small change); SD-fit remains right for derived/hand-authored garments sharing one mask (suit, uniform, Fantasy cuts). REMAINING for this ticket: refit tshirt to the 5 repaired forks (T-1090 done — add to --only and rerun), per-body shell mode, then the basic set: hoodie, button-down, shorts, jeans, formal pants, jacket + the suit/uniform hand-author proof; creation-screen try-on UI for tints/logos.
Basic-set EXPANSION (user, 2026-07-06 bedtime directive: ''full set of the basics across the board''): wave 2 after the in-flight wave 1 — FOOTWEAR: sneakers_modern (trainers, everyday default), shoes_formal (suit pairing), boots_modern (ankle height); SPORT: tank_top (sleeveless, logo-capable), joggers_modern (cuffed, track-stripe tint region), track_jacket (with joggers = the training suit, logo-capable); SWIM: swim_trunks (bright), swimsuit_onepiece (color-block regions). Foot garments follow the peasant_shoes both-feet convention; sole geometry as an offset-shell param extension. Total modern catalogue after wave 2: 17 garments across tops/bottoms/feet/full-body x casual/formal/sport/swim. DEFERRED deliberately: hats/accessories — accessory slot path is unexercised and T-721 flags a filter bug; needs daylight, not a 3am debug. Overnight sequence: wave 1 -> wave 2 -> full garment x 11-body fitting matrix (the ''T-1090 fittings'' check, fork bodies especially) -> commits -> gated pushes -> morning report.
Fill-in-the-blanks addendum (user bedtime directive 2 + lead judgment): wave 2 grows to 12 — adds sweater_modern (crew pullover), cargo_pants (utility/cyberpunk staple), parka_thrds (cold-weather was absent entirely; ships as the FIRST CANON-BRANDED garment — thrds is Braemar''s cold-weather fiber brand per wiki; hip-length to avoid the parked skirt-rigging tier), slides (swim footwear, near-free). PLUS outfit presets: data file of named complete looks (casual/business/sport/beach/worker/sleep as tint-palette presets over garments) authored by the lead at integration — makes the catalogue usable for NPC dressing and the shop as OUTFITS, not just items. Post-wave-2 catalogue: 21 modern pieces (tops 8 / bottoms 6 / feet 4 / full-body 2 / swim 3). Hats/accessories remain the deliberate daylight deferral (T-721).
ACCEPTED for first release (user review, 2026-07-07): full catalogue + lookbook approved; toe-box fix reviewed — ''I still see some toes, but this will do''. Residual toe hints on closed footwear accepted as first-release quality; further toe-box smoothing is polish backlog, not scope. Closing.', 'review', 'high', NULL, 'client', NULL, '2026-07-06 07:34:18.656', '2026-07-07 12:04:38.699', NULL, 'fe689e46ed80988afbb62827b85c5a9f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCPBF41RWK9PW9M22Q7961C', 'story', '06FB0TNSRXX29H5X0EB0F0GBW4', 'Clothing catalogue engine + basic set — recolorable, logo-capable everyday garments', 'Fable-5-window sidequest workstream 2 (user directive 2026-07-06, extends T-1088 scope family): build the clothing ENGINE and a basic set now, park variety for later. Target bar: RimWorld''s original apparel breadth — varied enough to not feel limiting. Goal experience: being able to pick and SHOP for clothes — colorize + slap logos on casualwear. Basic set: t-shirt (logo-capable), hoodie (logo-capable), button-down shirt, shorts, jeans, formal pants, jacket, colorable uniform, black suit (moved up so officials are includable). Skipped by explicit call: capes, dresses/skirts (parked — difficulty tier). Engine deliverables: (1) multi-region tint masks — requires Quaternius Source tier files (USD5 Patreon month, one-time download, CC0 retained — user purchase action); (2) logo decal region on garment chest UV — flat 2D artwork per D-244, diegetic hook into economy generated brands (wiki/economics/corporations/generated_brands.toml) for brand-logo shirts; (3) manifest + CharacterVisualDescriptor category coverage (slots/tints already generic); (4) batch-fit each authored garment to all 11 body types via the validated Sprint-28 Blender Surface Deform pipeline (tooling/blender_*.py). Authoring routes per garment TBD by feasibility pass: derive from owned Fantasy pack meshes (62 parts, e.g. tunic->tshirt sleeve cut, pants->shorts hem cut) vs hand-author low-poly on the 65-bone rig (Garment Tool). Related: T-1088 locomotion sandbox doubles as the garment-under-animation QA rig (cycle outfits through Walk/Sprint/Crouch_Fwd).
Correction (2026-07-06): Source tier is PARTIALLY owned already — docs/assets/downloads/ (gitignored vendor archives, present in both checkouts) holds Universal Base Characters[Source] (630MB: full .blend files for all 6 base bodies incl. FullBody + OnlyHead variants, hairstyle .blends origin-at-0 + rigged-to-head-bone, texture masters, Godot engine project) plus UBC[Standard], UAL 1+2[Standard], Modular Character Outfits Fantasy[Standard]. NOT owned: Fantasy Outfits[Source] — the garment recolor masks + named vertex groups. Consequence: authoring NEW garments is fully unblocked (author against source body .blends, create our own tint masks/vertex groups — no purchase needed); only pack-DERIVED garments'' clean masks would want one more USD5 Patreon month, decision deferred until the feasibility route table says how much derivation we actually use.
Art direction (user, 2026-07-06): garments read CYBERPUNK/MODERN — near-future everyday civilian + corporate wear — NOT fantasy/medieval. The owned Fantasy pack is at most a topology donor (low-poly base shapes like pants/shirts are genre-neutral; genre lives in silhouette details, textures, trims, and accessories) — no medieval trim/textures may survive into shipped garments. Weight the authoring routes accordingly: texture identity matters as much as mesh. Canon hook: the wiki already ships a garment brand — thrds (wiki/star-systems/GJ-475/index.md, Braemar fiber cooperative, corridor fashion markets) — so branded clothing connects to Phase-1 lore, not only generated_brands.toml. This emphasis also feeds the Quaternius-pivot evaluation: commercial alternatives skew sci-fi/urban while Quaternius clothing is fantasy-only.
Nuance (user, 2026-07-06): the cyberpunk/modern direction is the DEFAULT, not a prohibition — fashion in the Reach is cyclical, so fantasy/medieval-flavored garments may appear here and there as deliberate fashion statements (subculture pieces, luxury/revival trims, statement outerwear). Supersedes the previous note''s hard ''no medieval trim may survive'' line. Practical consequence: a small number of Fantasy-pack pieces may ship near-as-is where they read as intentional fashion; the basic set itself stays modern.
Art direction CONSOLIDATED (user, 2026-07-06 — supersedes the two notes above): the Reach has no single clothing style — ALL styles coexist, with modern/cyberpunk probably the most prevalent. Style is a prevalence DISTRIBUTION, not a genre rule, and may eventually vary by culture/settlement (fits the simulation DNA; fashion-as-cultural-data is a later phase concern, not this ticket). Consequences now: (1) the engine is style-agnostic by construction (slots/tints/logos carry no genre); (2) the basic set targets the prevalent center — modern casual + corporate — because it dresses the most NPCs and the shopping experience; (3) garments get a lightweight style tag in the manifest (e.g. style: modern|formal|fantasy|utility) as the cheap seam so per-culture distributions can be authored later without retrofitting; (4) Fantasy-pack pieces are legitimate catalogue members under their own tag, prevalence-weighted low.
Scope pin (user, 2026-07-06, final word on style): for simplicity, THIS ticket ships ONE style only — cyberpunk/modern. The pluralistic distribution model above remains the long-term truth (keep the manifest style tag as the seam), but the v1 basic set is single-style; other styles are catalogue growth, not scope.
Route challenge (user, 2026-07-06): not sold on staying Quaternius-primary — ''Quaternius is limited and will move the wall at too slow a pace; I''d rather pick something that has what we need now.'' Fresh store verification (2026-07-06): Sidekick packs are one-time USD199.99, perpetual, engine-agnostic license (Godot legal, unsupported); NO raw FBX — extraction from unitypackage (community-proven: unitypackage_godot, third-party Sidekick Creator Godot plugin incl. body blend shapes); ''Sold out'' labels are a broken-theme artifact per Shopify JSON (needs one browser cart check); SyntyPass rejected (assets stop being developable after cancel). Relevant packs: Starter (FREE, 57+91 parts), Modern Civilians (165 parts = v1 basic set territory), Sci-Fi Civilians (103 parts, cyberpunk accents), Modern Police (uniforms/officials). DECISION NOW GATED ON THE FREE SPIKE: user downloads free Starter Pack -> Bridge-C spike (extract garment -> Robust Weight Transfer onto our rig -> 11-body batch -> animation QA in T-1088 sandbox). Pass -> buy Modern Civilians, Synty = primary garment supply (+UAL1/UAL2 Source ~USD30 for clips — no Synty substitute exists for Godot animations; Fantasy Outfits Source drops to low priority under the single-style pin). Fail -> hand-author route stands. Stay-vs-pivot governance record HELD until spike evidence lands.
Scope guard (user concern, 2026-07-06): Synty intake must NOT displace the create-stuff-yourself pipeline — the user''s goal includes in-house garment creation capability, not just swapping vendor catalogs. Resolution: three-route portfolio sharing one engine — (a) Synty intake = variety bootstrap only; (b) derivation scripting (cuts/merges/retexture, agent-automatable) = create-yourself lite, turns any donor topology into original designs; (c) TRUE AUTHORING on owned UBC Source body .blends = the pipeline proper. GUARANTEE: the colorable uniform and black suit (no donor exists in any pack) are built via route (c) as the authoring pipeline''s end-to-end proof — non-negotiable deliverable of this ticket, so the pipeline exists even if Synty covers everything else. Spike status: extraction done inline by lead (158 FBX, sci-fi civilian theme confirmed); DECISIVE finding — Sidekick rig is UE-Mannequin-named, 52/65 bone-name overlap with our rig, sample garment binds to 12 vgroups of which 11 match ours exactly (only head->Head case rename) => transplant likely rename-and-rebind, far cheaper than the weight-transfer the pivot eval assumed; body blend shapes travel in the FBX. Transplant phase parked pending API recovery / token-window reset.
ROUTE DECISION (user, 2026-07-06, final): Synty intake REJECTED despite the spike''s technical PASS — (1) USD199.99/pack is too expensive; (2) Sidekick modularity is baked body-segment swap (clothes fused to body chunks), incompatible with our layered clothing-over-body system (11 bodies, skin tones, slot swapping); (3) user dislikes the Synty style. The spike still paid: transplant/batch scripts are source-agnostic and become the G1-family production pipeline; T-1090 (5 bodies broken bare) discovered; the Synty question is closed with evidence, not parked. OPERATIVE ROUTE: (b) derive from owned Fantasy parts + (c) hand-author — with a new preferred authoring technique: OFFSET-SHELL FROM OUR OWN BODY MESHES (extract body segment surface, offset outward into garment shell, cut neckline/hem/sleeves; weights inherited by construction, style fully ours, USD0). Suit + uniform remain the full hand-author proof. Purchases still open (separate concerns): UAL1/UAL2 Source ~USD30 for animation clips; Fantasy Outfits Source USD20 low-priority convenience.
Chromakey garment-QA harness DELIVERED (2026-07-06, commits eaca6c8c4/74fa16260/b09a50efb): two-pass depth-proximity clip detection — pass A keys covered body segments magenta, pass B re-renders garment-only with a depth-only 3cm epsilon bias toward camera; analyzer splits key pixels into exposed_skin (informational — sleeveless arms, collars) vs clip_through (gating — skin within 3cm in front of cloth). Run: tooling/garment-qa/run-garment-qa <config>. Verified on the peasant set (avg_m/f x Walk/Sprint/Crouch_Fwd x 3 frames x 4 yaws): 0/18 front-view false positives; genuine findings = sleeveless armhole seam (avg_f, sides), deep-crouch waist gap (worst 150px, back), collar nape. First real fit observations already on record for the peasant set. Sensitivity: clip_epsilon_m + --min-pixels, to calibrate against the first modern garments. This is the acceptance gate for every garment the wardrobe pipeline produces; pair with the T-1088 sandbox for in-world walk QA.
ENGINE DELIVERED (2026-07-06, commits e22ea0fa4 + 278e8b7c2; earlier eaca6c8c4/74fa16260/b09a50efb chromakey, b54b8189d bodies): G1 skinned batch-fit (blender_batch_fit_skinned.py), offset-shell authoring (blender_author_offset_shell.py — route c create-yourself, weights by construction, procedural RGBA masks, UV2 chest channel), toon_garment.gdshader (channel-blended 4-region tint + logo after-tint/before-toon), compositor plumb (multi_region coverage flag -> garment shader; descriptor clothing_logos: per-character brand choice), thrds logo stub, manifest style tag + logo_capable. PROOF: tshirt_modern on 6 healthy bodies, 18-assertion suite green, 216-capture chromakey QA. ROUTE GUIDANCE from QA evidence (Q-060): single-reference SD-fit of offset-shells degrades with girth divergence (muscular_m worst 859px clip at 24mm standoff; reference body clean) — offset-shell garments should be authored PER BODY (needs per-body masks + runtime <body>_mask.png loading, small change); SD-fit remains right for derived/hand-authored garments sharing one mask (suit, uniform, Fantasy cuts). REMAINING for this ticket: refit tshirt to the 5 repaired forks (T-1090 done — add to --only and rerun), per-body shell mode, then the basic set: hoodie, button-down, shorts, jeans, formal pants, jacket + the suit/uniform hand-author proof; creation-screen try-on UI for tints/logos.
Basic-set EXPANSION (user, 2026-07-06 bedtime directive: ''full set of the basics across the board''): wave 2 after the in-flight wave 1 — FOOTWEAR: sneakers_modern (trainers, everyday default), shoes_formal (suit pairing), boots_modern (ankle height); SPORT: tank_top (sleeveless, logo-capable), joggers_modern (cuffed, track-stripe tint region), track_jacket (with joggers = the training suit, logo-capable); SWIM: swim_trunks (bright), swimsuit_onepiece (color-block regions). Foot garments follow the peasant_shoes both-feet convention; sole geometry as an offset-shell param extension. Total modern catalogue after wave 2: 17 garments across tops/bottoms/feet/full-body x casual/formal/sport/swim. DEFERRED deliberately: hats/accessories — accessory slot path is unexercised and T-721 flags a filter bug; needs daylight, not a 3am debug. Overnight sequence: wave 1 -> wave 2 -> full garment x 11-body fitting matrix (the ''T-1090 fittings'' check, fork bodies especially) -> commits -> gated pushes -> morning report.
Fill-in-the-blanks addendum (user bedtime directive 2 + lead judgment): wave 2 grows to 12 — adds sweater_modern (crew pullover), cargo_pants (utility/cyberpunk staple), parka_thrds (cold-weather was absent entirely; ships as the FIRST CANON-BRANDED garment — thrds is Braemar''s cold-weather fiber brand per wiki; hip-length to avoid the parked skirt-rigging tier), slides (swim footwear, near-free). PLUS outfit presets: data file of named complete looks (casual/business/sport/beach/worker/sleep as tint-palette presets over garments) authored by the lead at integration — makes the catalogue usable for NPC dressing and the shop as OUTFITS, not just items. Post-wave-2 catalogue: 21 modern pieces (tops 8 / bottoms 6 / feet 4 / full-body 2 / swim 3). Hats/accessories remain the deliberate daylight deferral (T-721).
ACCEPTED for first release (user review, 2026-07-07): full catalogue + lookbook approved; toe-box fix reviewed — ''I still see some toes, but this will do''. Residual toe hints on closed footwear accepted as first-release quality; further toe-box smoothing is polish backlog, not scope. Closing.', 'done', 'high', NULL, 'client', NULL, '2026-07-06 07:34:18.656', '2026-07-07 12:04:49.833', NULL, '348ec6c1104b8c20ae8ee3b2c63797b7', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKR283RTWYXD2M005K65S52M', 'bug', '06FB0TNSRXX29H5X0EB0F0GBW4', 'head_001 template renders grey (untinted) on child/teen/muscular bodies', 'Found by the T-1089 lookbook pass (2026-07-07): overlay head templates (head_001) render grey faces on child/teen/muscular bodies — the template appears not to receive the body''s skin-tone tint, while each body''s own seg_head renders correctly. Workaround used in the lookbook: head_id empty -> body seg_head shows. If head templates are meant to be body-agnostic (D-161 head-as-BoneAttachment3D), the skin-tone shader application needs to cover template heads per body; investigate _apply skin tone path in character_visual.gd for the head template branch.', 'done', 'medium', NULL, 'client', NULL, '2026-07-07 10:04:11.590', '2026-07-07 12:08:15.679', NULL, '8ed376d80da36bf8f1361c3d4dcf9bbf', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKRZ29KH70NFAY0Z1GCVR4N0', 'task', '06FB0TNSRXX29H5X0EB0F0GBW4', 'S9 live feel-tuning session — locomotion constants against the tuned eye', 'The one unfinished piece of T-1088, deliberately parked at sidequest close (2026-07-07) because it needs Jeroen at the keyboard: (1) verify turn-in-place handedness (headless could not — positive shortest-arc delta maps to _L; one-line TURN_CLIP swap if mirrored); (2) judge TURN_SPEED_SCALE=2.0 (UAL turn clips ~1.7-2.0s vs the ~0.3s yaw ease) and the turn-on-stop behavior; (3) general feel constants pass (NATIVE_MPS cadence sync, blends, camera follow/lookahead, cutaway corridor width) — every knob in client/scripts/sandbox/sandbox_constants.gd with the DebugHud showing live numbers. Launch: server --test-mode + SR_LIVE=1 locomotion_sandbox.tscn. Also revisit during the session: Q-084''s walk-vs-aim animation split (the purchased 8-dir walk/jog/crouch sets make direction-matched clips tractable).', 'backlog', 'medium', NULL, 'client', NULL, '2026-07-07 12:10:06.108', '2026-07-07 12:10:06.108', NULL, '85414a301d4c7313046c3be096542165', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCER95EK266H8RWPW8XT1F0', 'story', '06FB0TNSRXX29H5X0EB0F0GBW4', '3D character locomotion sidequest — composited character walks the Gauntlet on the live server', 'Fable-5-window sidequest (sanctioned cascade exception, 2026-07-05): the presentation layer that turns discrete server tile steps into a believable walking 3D character. Scope: 3D sandbox dev scene (SR_LIVE=1, greybox tiles derived from server snapshots, no hand-authored map), CharacterVisual instantiated in-world, locomotion rig (tile-step + facing-octant interpolation, stance-aware speeds), UAL animation state machine (idle/walk/sprint/careful/crouch), D-148 camera rig (30deg low-angle follow, 45deg rotation). Server-authoritative from day one — no client-local movement model. Builds on D-148/D-149/D-244/D-066 and the T-417 stance system. If the Fable 5 window closes mid-flight, work parks here.
Visual reference (user, 2026-07-06): Xenonauts 2 nails the target tiles/occlusion/character perspective — readable tile grid, low-angle tactical camera with angle options (matches D-148 30deg low-angle + 45deg rotation steps and the spikes/3dpipeline angle presets), and crucially its wall/roof occlusion treatment: camera-facing walls cut down/ghosted so interiors stay readable, floors peel per z-level. One deliberate difference: our camera locks to the player character (D-015/T-116) — no free map panning. Implication for the locomotion sandbox: greybox walls should prototype camera-facing cutaway occlusion early, since wall readability interacts with the locked low-angle camera.
Scoping call (user + lead agreement, 2026-07-06): wall cutaway is CLIENT-SIDE presentation, decoupled from fog-of-perception. Rationale: two occlusion systems with different subjects — perception/fog governs what the CHARACTER knows (server-enforced info boundary; client only receives observer-filtered geometry), cutaway governs what the PLAYER''S CAMERA sees (pure render mode on wall data the client already holds). They compose: cutaway cuts render height; fog overlay still gates what is visible behind. Walls remain first-class client data objects (future destruction/explosion interactions), cutaway is a render mode on them like tint/LOD. Nuance parked for Phase 5 proper: destroyed-while-unobserved walls should render in remembered state (fog-memory applied to geometry). If this holds through implementation, mint a D-record (perception domain) when the sidequest lands.
Animation supply resolved (2026-07-06): user purchased UAL1[Source+Pro] (120 clips, identical lists) + UAL2[Source] (134 clips), unzipped in docs/assets/downloads/. Gains: Turn90_L/R + Turn180_L/R (turn-in-place), Sprint_Enter/Exit + Crouch_Enter/Exit (stance transitions), full 8-direction Walk/Jog/Crouch sets incl. diagonals, Counter_Idle + talking/phone/sitting idles (life-sim verbs), plus _RM root-motion variants (unused — in-place is correct for server-authoritative interpolation). Still absent everywhere: walk start/stop + stairs — the only remaining custom clips. Integration is NOT a drop-in swap: upstream renamed clips (Walk_Loop -> Walk_Fwd_Loop etc.), so wire via the design''s recorded plan — explicit library names + lib/Clip addressing + gait-table update. NOTE for facing design: the 8-dir walk sets unlock Q-084''s parked walk-vs-aim split (direction-matched clips relative to facing) — revisit during the S9 tuning session.
Live-session feedback (user, 2026-07-06): (1) Corridor cutaway verdict — two minds: ''extremely trippy, could be the game''s own look'' vs ''player cannot see what is in the room unless close''. Resolution: cutaway MODES, toggled live in the sandbox (corridor / bottom-walls-low / both) — bottom-wall rule is data-driven (wall drops to stub when a KNOWN floor tile sits on its camera-far side; camera-facing directions derived from WorldRoot basis at runtime, not hand-derived). Default picked by feel during the session; the trippy corridor stays available as a signature-look option. (2) NEW: mouse-over move-here marker on the hovered tile + optimal path line — client-side A* over the never-evict KNOWN tile store (info-boundary-honest: the character plans only through known tiles; fog is unpathable), 8-dir with diagonal step cost 1 (time-optimal per the no-sqrt2 wire), terrain-cost provider seam (uniform today, Phase-4 terrain later), click executes by streaming ordinary Move* step commands through the existing throttle (zero protocol change, server validates every step), cancelled by WASD override / path invalidation / arrival. Settles more of Q-084 (click-to-move half).
RMB gesture vocabulary (user, live session 2026-07-06, added to the path-preview feature): single right-click = walk there (current stance); DOUBLE right-click = sprint there (ladder ToggleStanceUp burst to Sprint via the ordinary command queue, pre-sprint stance RESTORED on arrival; a double upgrades the already-started follow in place); LONG-PRESS right-click (~0.4s, commit on release) = ''take cover at location'', prototyped as go-there-then-Crouch-on-arrival (no restore — crouching was the point). Real cover mechanics (wall adjacency, directional protection) are future combat design; the gesture is the input-vocabulary prototype. WASD always cancels any follow without stance restore (player override is deliberate).
Follow-facing refinement (user, live session 2026-07-06): during an RMB path-follow the BODY commits to the leg/movement direction (mouse no longer swings body yaw); the mouse instead drives a LAYERED LOOK-AT — Head bone (~70deg limit) plus torso twist via a spine bone (~30deg) for looking far lateral/behind; beyond their sum the character physically cannot look further without turning (correct). Pure client presentation on the D-249 model; SetFacing continues to ride the wire during follows, so the SERVER vision cone still follows the mouse (diegetic: the character looks where the player points while walking a committed path). Implementation: Godot LookAtModifier3D pair under the CharacterVisual skeleton, influence-faded in/out on follow start/end; rig gains a commit_body_to_motion flag (yaw from leg velocity while set).
SIDEQUEST CLOSE-OUT (2026-07-07): all scope delivered and pushed — sandbox (scene, greybox store, rig, gait machine, camera, cutaway modes w/ user-verdict mode-2 default recorded as D-250 amendment), RMB navigation vocabulary, layered head/torso look-at, D-252 view/movement protocol split (server+client), purchased UAL tiers wired (turn-in-place, stance enter/exits), design doc committed to docs/design/t1088-locomotion-sandbox-design.md (the ''design §'' references in sandbox code resolve in-repo now). Design-delta close-out notes: no new Gauntlet room was needed (constraint 12 never triggered, server untouched except D-252); ~40 lines of main.gd boot boilerplate duplicated with Pattern: markers for the T-962 extraction; seek-during-blend + remove_immutable_tracks caveats did not manifest in practice; ual_extended wiring superseded by the purchased-tier ual1/ual2 libraries; 2D select_yaw_target moving-branch is dead code post-D-252 (cleanup rides Phase 5). Remaining feel work parked as T-1096 (S9 live tuning — needs the user). Closing.', 'backlog', 'high', NULL, 'client', NULL, '2026-07-06 07:01:06.475', '2026-07-07 12:10:20.956', NULL, '990a574e76aab1e943fb4997885c7542', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FKCER95EK266H8RWPW8XT1F0', 'story', '06FB0TNSRXX29H5X0EB0F0GBW4', '3D character locomotion sidequest — composited character walks the Gauntlet on the live server', 'Fable-5-window sidequest (sanctioned cascade exception, 2026-07-05): the presentation layer that turns discrete server tile steps into a believable walking 3D character. Scope: 3D sandbox dev scene (SR_LIVE=1, greybox tiles derived from server snapshots, no hand-authored map), CharacterVisual instantiated in-world, locomotion rig (tile-step + facing-octant interpolation, stance-aware speeds), UAL animation state machine (idle/walk/sprint/careful/crouch), D-148 camera rig (30deg low-angle follow, 45deg rotation). Server-authoritative from day one — no client-local movement model. Builds on D-148/D-149/D-244/D-066 and the T-417 stance system. If the Fable 5 window closes mid-flight, work parks here.
Visual reference (user, 2026-07-06): Xenonauts 2 nails the target tiles/occlusion/character perspective — readable tile grid, low-angle tactical camera with angle options (matches D-148 30deg low-angle + 45deg rotation steps and the spikes/3dpipeline angle presets), and crucially its wall/roof occlusion treatment: camera-facing walls cut down/ghosted so interiors stay readable, floors peel per z-level. One deliberate difference: our camera locks to the player character (D-015/T-116) — no free map panning. Implication for the locomotion sandbox: greybox walls should prototype camera-facing cutaway occlusion early, since wall readability interacts with the locked low-angle camera.
Scoping call (user + lead agreement, 2026-07-06): wall cutaway is CLIENT-SIDE presentation, decoupled from fog-of-perception. Rationale: two occlusion systems with different subjects — perception/fog governs what the CHARACTER knows (server-enforced info boundary; client only receives observer-filtered geometry), cutaway governs what the PLAYER''S CAMERA sees (pure render mode on wall data the client already holds). They compose: cutaway cuts render height; fog overlay still gates what is visible behind. Walls remain first-class client data objects (future destruction/explosion interactions), cutaway is a render mode on them like tint/LOD. Nuance parked for Phase 5 proper: destroyed-while-unobserved walls should render in remembered state (fog-memory applied to geometry). If this holds through implementation, mint a D-record (perception domain) when the sidequest lands.
Animation supply resolved (2026-07-06): user purchased UAL1[Source+Pro] (120 clips, identical lists) + UAL2[Source] (134 clips), unzipped in docs/assets/downloads/. Gains: Turn90_L/R + Turn180_L/R (turn-in-place), Sprint_Enter/Exit + Crouch_Enter/Exit (stance transitions), full 8-direction Walk/Jog/Crouch sets incl. diagonals, Counter_Idle + talking/phone/sitting idles (life-sim verbs), plus _RM root-motion variants (unused — in-place is correct for server-authoritative interpolation). Still absent everywhere: walk start/stop + stairs — the only remaining custom clips. Integration is NOT a drop-in swap: upstream renamed clips (Walk_Loop -> Walk_Fwd_Loop etc.), so wire via the design''s recorded plan — explicit library names + lib/Clip addressing + gait-table update. NOTE for facing design: the 8-dir walk sets unlock Q-084''s parked walk-vs-aim split (direction-matched clips relative to facing) — revisit during the S9 tuning session.
Live-session feedback (user, 2026-07-06): (1) Corridor cutaway verdict — two minds: ''extremely trippy, could be the game''s own look'' vs ''player cannot see what is in the room unless close''. Resolution: cutaway MODES, toggled live in the sandbox (corridor / bottom-walls-low / both) — bottom-wall rule is data-driven (wall drops to stub when a KNOWN floor tile sits on its camera-far side; camera-facing directions derived from WorldRoot basis at runtime, not hand-derived). Default picked by feel during the session; the trippy corridor stays available as a signature-look option. (2) NEW: mouse-over move-here marker on the hovered tile + optimal path line — client-side A* over the never-evict KNOWN tile store (info-boundary-honest: the character plans only through known tiles; fog is unpathable), 8-dir with diagonal step cost 1 (time-optimal per the no-sqrt2 wire), terrain-cost provider seam (uniform today, Phase-4 terrain later), click executes by streaming ordinary Move* step commands through the existing throttle (zero protocol change, server validates every step), cancelled by WASD override / path invalidation / arrival. Settles more of Q-084 (click-to-move half).
RMB gesture vocabulary (user, live session 2026-07-06, added to the path-preview feature): single right-click = walk there (current stance); DOUBLE right-click = sprint there (ladder ToggleStanceUp burst to Sprint via the ordinary command queue, pre-sprint stance RESTORED on arrival; a double upgrades the already-started follow in place); LONG-PRESS right-click (~0.4s, commit on release) = ''take cover at location'', prototyped as go-there-then-Crouch-on-arrival (no restore — crouching was the point). Real cover mechanics (wall adjacency, directional protection) are future combat design; the gesture is the input-vocabulary prototype. WASD always cancels any follow without stance restore (player override is deliberate).
Follow-facing refinement (user, live session 2026-07-06): during an RMB path-follow the BODY commits to the leg/movement direction (mouse no longer swings body yaw); the mouse instead drives a LAYERED LOOK-AT — Head bone (~70deg limit) plus torso twist via a spine bone (~30deg) for looking far lateral/behind; beyond their sum the character physically cannot look further without turning (correct). Pure client presentation on the D-249 model; SetFacing continues to ride the wire during follows, so the SERVER vision cone still follows the mouse (diegetic: the character looks where the player points while walking a committed path). Implementation: Godot LookAtModifier3D pair under the CharacterVisual skeleton, influence-faded in/out on follow start/end; rig gains a commit_body_to_motion flag (yaw from leg velocity while set).
SIDEQUEST CLOSE-OUT (2026-07-07): all scope delivered and pushed — sandbox (scene, greybox store, rig, gait machine, camera, cutaway modes w/ user-verdict mode-2 default recorded as D-250 amendment), RMB navigation vocabulary, layered head/torso look-at, D-252 view/movement protocol split (server+client), purchased UAL tiers wired (turn-in-place, stance enter/exits), design doc committed to docs/design/t1088-locomotion-sandbox-design.md (the ''design §'' references in sandbox code resolve in-repo now). Design-delta close-out notes: no new Gauntlet room was needed (constraint 12 never triggered, server untouched except D-252); ~40 lines of main.gd boot boilerplate duplicated with Pattern: markers for the T-962 extraction; seek-during-blend + remove_immutable_tracks caveats did not manifest in practice; ual_extended wiring superseded by the purchased-tier ual1/ual2 libraries; 2D select_yaw_target moving-branch is dead code post-D-252 (cleanup rides Phase 5). Remaining feel work parked as T-1096 (S9 live tuning — needs the user). Closing.', 'done', 'high', NULL, 'client', NULL, '2026-07-06 07:01:06.475', '2026-07-07 12:10:20.986', NULL, 'ce4896d59ece08a42a88e7e026b7d15f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);