38 KiB
Live2D Character Integration Plan
Goal: DansoriEQ에 AI 반응형 Live2D 캐릭터를 탑재한다. 최종 형태는 Equalizer APO + AI EQ 워크플로우에 맞춰 캐릭터가 상태, 감정, 말풍선, 모션으로 반응하는 WPF 앱이다.
0. Important Context
- 사용자는 Live2D, 디자인, 캐릭터 제작 지식이 없다고 전제한다.
- 캐릭터 이미지, 레이어 분리, 표정/포즈 요청서, 검수 문서는 모두 ChatGPT를 통해 만든다.
- 사람 디자이너 없이 진행하므로, 제작물은 “상업 품질 완성본”보다 “앱에 실제 탑재 가능한 반복 개선형 자산”을 우선한다.
- 코드 적용은 DansoriEQ 앱에서 진행한다.
- 제작 원본은
D:\Work_AI\Dansori\Characters_Build_Docs에 보관한다. - 앱 탑재본은
D:\Work_AI\Dansori\DansoriEQ\src\DansoriEQ.App\Assets\Characters에 복사해 사용한다.
1. Current Prepared Assets
DansoriEQ App
- .NET 8 WPF 앱 구조가 있다.
- 기존 캐릭터/애니메이션 진입점이 있다.
src/DansoriEQ.App/Controls/MascotAvatar.xamlsrc/DansoriEQ.App/Controls/MascotToast.xamlsrc/DansoriEQ.App/Controls/LottieView.cssrc/DansoriEQ.App/Controls/SoundwaveRings.xamlsrc/DansoriEQ.App/Controls/EqBarsFx.xaml
SkiaSharp.Skottie가 이미 포함되어 있어 Lottie FX 재생 기반이 있다.- AI EQ 흐름이 있다.
- user prompt
- AI provider
- EQ delta parsing
- EQ state apply
- APO writer
Character Build Docs
Prepared Live2D source packages:
D:\Work_AI\Dansori\Characters_Build_Docs\LeeSori_Live2DD:\Work_AI\Dansori\Characters_Build_Docs\Haruka_Live2DD:\Work_AI\Dansori\Characters_Build_Docs\Isabel_Live2DD:\Work_AI\Dansori\Characters_Build_Docs\Noeul_Live2D
Each package currently contains:
- Live2D layer PNG bundle under
03_Assets/Live2D/LayerPNGs layer_manifest.jsonLayerPNGs_README.mdlayer_generation_report.json- preview PNGs
- Photoshop assembler JSX
- Cubism/PSD workflow documentation
Validation status from generation:
- 78 layer PNGs generated per character.
- 67 required layers non-empty per character.
- No missing generated layer files.
2. Not Prepared Yet
The following are still required before true Live2D runtime integration:
- Cubism Editor import result
.moc3.model3.json- texture atlas PNG
.motion3.json.exp3.json- optional
.physics3.json
- WPF WebView2 Live2D host
- Cubism SDK for Web runtime files
- Character event bridge between WPF and JavaScript
- Character state model inside DansoriEQ
- AI/EQ event mapping to character reactions
- Final app asset packaging structure
3. Recommended Runtime Architecture
Use WPF + WebView2 + Cubism SDK for Web.
Reason:
- WPF-native Live2D integration is more complex and slower to debug.
- Cubism SDK for Web is the most practical runtime for loading
.model3.jsonassets. - WPF can communicate with the WebView through message passing.
- This keeps Live2D rendering isolated from Equalizer APO and AI EQ logic.
Proposed layers:
DansoriEQ WPF
MainWindow / existing panels
Live2DCharacterView.xaml
WebView2
live2d-host/index.html
live2d-host/characterHost.js
Cubism SDK for Web
Assets/Characters/{CharacterId}/model.model3.json
4. Character Production Workflow Using ChatGPT
Because no designer is available, every character asset task must be converted into a concrete ChatGPT task.
4.1 Character Identity Lock
For each character, maintain a short identity sheet:
- name
- role in DansoriEQ
- personality
- color palette
- hairstyle
- face traits
- default outfit
- forbidden changes
- reference image path
Output file per character:
{Character}_Live2D/01_Overview/Character_Lock.md
Completion criteria:
- The character can be regenerated consistently enough across multiple prompts.
- The app role is clear.
- Visual differences between characters are obvious.
4.2 Source Image Generation
ChatGPT image generation tasks:
- neutral full-body A-pose
- head expression set
- alternate hand/arm poses
- optional outfit variants
- transparent or removable background when possible
Required style constraints:
- character only
- no UI
- no text
- no logo
- clean front-facing or slight 3/4 pose
- high resolution
- consistent face and hair
- suitable for Live2D layer separation
Completion criteria:
- At least one A-pose source exists.
- Head and body are visually consistent.
- Image is suitable for part extraction.
4.3 AI-Assisted Layer Separation
Use the existing *_Live2D tooling to produce coarse Live2D layer PNGs.
Current layer categories:
- Guide
- BackHair
- Body
- Clothes
- Head
- Eyes
- Brows
- Mouth
- FrontHair
- Accessories
- SwapParts
Completion criteria:
layer_generation_report.jsonshows all required layers non-empty.- Preview image is visually recognizable.
- Obvious empty or wrong-color masks are fixed by script fallback or prompt regeneration.
4.4 PSD Assembly
Use photoshop_assemble_live2d_psd.jsx from each *_Live2D folder.
Expected outputs:
{character}_live2d_material_separation.psd{character}_live2d_import.psd
Completion criteria:
- PSD opens in Photoshop or compatible editor.
- Layers are named according to
layer_manifest.json. - Transparent background is preserved.
4.5 Cubism Editor Work
This is the only area that may require manual GUI work unless automated later.
Tasks:
- Import PSD into Cubism Editor.
- Create ArtMeshes.
- Create deformers.
- Add parameters.
- Create basic expressions.
- Create idle motion.
- Export runtime model.
Minimum viable export:
model.model3.json
model.moc3
textures/*.png
motions/idle.motion3.json
expressions/*.exp3.json
Completion criteria:
- Cubism Viewer or Web runtime can load the model.
- Idle motion plays.
- At least 3 expressions work: neutral, happy, thinking.
5. App Integration Phases
Phase 1 - Static Compatibility Baseline
Goal: Keep current DansoriEQ stable and identify where the character belongs.
Tasks:
- Build/test current solution.
- Locate existing
MascotAvatarusage. - Document current mascot UI surfaces.
- Add no Live2D yet.
Completion criteria:
- App builds.
- Existing mascot UI still works.
- We know the exact insertion point for dynamic character UI.
Phase 2 - WebView2 Live2D Host PoC
Goal: Add a WebView2-based character host without real model dependency.
Tasks:
- Add WebView2 package if missing.
- Create
Controls/Live2DCharacterView.xaml. - Create
Assets/Live2DHost/index.html. - Create
Assets/Live2DHost/characterHost.js. - Load local host page inside WPF.
- Implement basic WPF-to-JS messages.
Example commands from WPF to JS:
setCharacter(characterId)
setState(state)
playMotion(group, index)
setExpression(expressionId)
showText(message)
Completion criteria:
- WPF window displays the host page.
- WPF can send a test message to JS.
- JS can send
hostReadyback to WPF.
Phase 3 - Placeholder Character Runtime
Goal: Use generated preview PNGs before real Cubism export exists.
Tasks:
- Copy each character preview PNG into app assets.
- Show selected character in the Live2D host placeholder.
- Animate placeholder with simple CSS transforms.
- Hook app events to placeholder states.
Completion criteria:
- The app can switch LeeSori, Haruka, Isabel, Noeul.
- Idle/thinking/success/error states visibly differ.
- No Cubism model required yet.
Phase 4 - Real Cubism Model Loading
Goal: Replace placeholder with actual Cubism model.
Tasks:
- Add Cubism SDK for Web runtime assets.
- Copy one exported model into
Assets/Characters/LeeSori. - Load
model.model3.jsonin WebView2. - Play idle motion.
- Trigger expression and motion from WPF.
Completion criteria:
- LeeSori Live2D model loads inside DansoriEQ.
- Idle motion plays.
- WPF can trigger at least one expression and one motion.
Phase 5 - AI/EQ Reaction Mapping
Goal: Character reacts to real app events.
Events to map:
- App launched
- APO setup required
- AI prompt started
- AI response received
- EQ delta parsed
- EQ applied
- EQ apply failed
- bypass on/off
- preset selected
- profile not found
Recommended state mapping:
Idle -> default breathing/idle
Listening -> user is typing or prompt submitted
Thinking -> AI request in progress
Talking -> AI explanation shown
ApplyingEq -> APO write in progress
Success -> EQ applied
Error -> failed operation
Muted -> bypass/off
Guide -> setup/help required
Completion criteria:
- Character state changes are driven by app events, not hard-coded UI buttons.
- AI response text can appear in
MascotToastor Live2D host overlay. - Failure states are visible and useful.
Phase 6 - Multi-Character System
Goal: Let users choose a character.
Tasks:
- Add character registry JSON.
- Add app setting for selected character.
- Add Settings UI character selector.
- Add per-character personality text for AI explanations.
Example registry:
{
"characters": [
{ "id": "leesori", "name": "LeeSori", "model": "Assets/Characters/LeeSori/model.model3.json" },
{ "id": "haruka", "name": "Haruka", "model": "Assets/Characters/Haruka/model.model3.json" },
{ "id": "isabel", "name": "Isabel", "model": "Assets/Characters/Isabel/model.model3.json" },
{ "id": "noeul", "name": "Noeul", "model": "Assets/Characters/Noeul/model.model3.json" }
]
}
Completion criteria:
- User can select a character.
- Selection persists between app launches.
- Character-specific assets load correctly.
Phase 7 - Polish and Release Readiness
Goal: Make the feature shippable.
Tasks:
- Add fallback if Live2D fails to load.
- Add performance setting: off/static/live.
- Add reduced motion option.
- Ensure local files load in packaged app.
- Validate release build.
- Add documentation.
Completion criteria:
- App works without Live2D assets.
- App does not crash if WebView2 or model loading fails.
- Character feature can be disabled.
- Release build includes required assets.
6. Immediate Next Step
Start with Phase 1 and Phase 2.
Recommended next implementation task:
- Build current DansoriEQ solution.
- Add WebView2 dependency if missing.
- Add
Live2DCharacterViewplaceholder control. - Add local
Live2DHostHTML/JS. - Display the host in a non-invasive area of the existing UI.
- Verify WPF-to-JS and JS-to-WPF message bridge.
This can be done before real Cubism models exist.
7. Working Rule for Future Sessions
At the start of any future session, read this file first:
D:\Work_AI\Dansori\DansoriEQ\docs\LIVE2D_CHARACTER_INTEGRATION_PLAN.md
Then check:
D:\Work_AI\Dansori\Characters_Build_Docs
D:\Work_AI\Dansori\DansoriEQ
Do not assume the user can manually create character art. Convert every character-art need into a ChatGPT/image-generation task or a scriptable asset-processing task.
8. Progress Log
2026-07-03 - Phase 1, Phase 2, Phase 3 Placeholder Started
Completed:
- Baseline
dotnet build .\DansoriEQ.slnpassed with 0 warnings and 0 errors. - Added
Microsoft.Web.WebView2package toDansoriEQ.App. - Added WPF control:
src/DansoriEQ.App/Controls/Live2DCharacterView.xamlsrc/DansoriEQ.App/Controls/Live2DCharacterView.xaml.cs
- Added local WebView host:
src/DansoriEQ.App/Assets/Live2DHost/index.htmlsrc/DansoriEQ.App/Assets/Live2DHost/style.csssrc/DansoriEQ.App/Assets/Live2DHost/characterHost.jssrc/DansoriEQ.App/Assets/Live2DHost/characters.json
- Copied generated preview images into app assets:
src/DansoriEQ.App/Assets/Characters/Live2DPreview/leesori.pngsrc/DansoriEQ.App/Assets/Characters/Live2DPreview/haruka.pngsrc/DansoriEQ.App/Assets/Characters/Live2DPreview/isabel.pngsrc/DansoriEQ.App/Assets/Characters/Live2DPreview/noeul.png
- Updated project file so Live2D host files and preview PNGs are copied to output.
- Placed
Live2DCharacterViewin the main graph/character area. - Added temporary character selector ComboBox with LeeSori, Haruka, Isabel, Noeul.
- Wired AI state messages:
- idle on load
- thinking on AI request
- success on EQ apply
- error on exception
- Fixed existing parser test expectation:
LSCmaps toFilterType.LowShelfSlope.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Output folder contains Live2D host files and all 4 preview PNG files.
characters.jsonpreview paths resolve to existing files in the debug output folder.
Next recommended task:
- Run the WPF app visually and confirm that the WebView2 placeholder appears in the graph area.
- If placement is acceptable, replace the temporary selector with a proper Settings character selector.
- Then prepare one real Cubism export, starting with LeeSori.
2026-07-03 - LeeSori Placeholder Visual Correction
Finding:
- The generated
sori_live2d_layer_preview.pngis useful as a layer-composition audit image, but it is not suitable as the app-facing placeholder. - Its face, eyes, mouth, and headphone proportions are visibly distorted because some facial/accessory layers are procedurally regenerated for Live2D separation.
- The app-facing placeholder should use polished character art until a real Cubism export exists.
Changed:
- Replaced
src/DansoriEQ.App/Assets/Characters/Live2DPreview/leesori.pngwith the existing polishedsori_idle.pngartwork. - Reduced WebView host placeholder overscaling:
right: -18%->right: -6%bottom: -14%->bottom: -6%width/height: 118%->104%
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.
Rule going forward:
- Use Live2D generated previews for production QA only.
- Use polished character PNGs for in-app placeholders.
- Replace placeholders with real Cubism runtime models only after Cubism export quality is acceptable.
2026-07-03 - LeeSori Source Artwork Rework
User feedback:
- Character proportion is acceptable.
- The black WebView character area should be taller so its vertical span matches the EQ graph more closely.
- LeeSori still has a distracting white outline around the hair; this is not just missing alpha transparency.
Finding:
- Deterministic alpha cleanup reduced some edge matte, but the large white/pink/gray outline was baked into the source artwork as glow/highlight, especially around the hair/headphones.
- Continuing to erase pixels from the existing PNG damages the intended hair/headphone shape before it fully removes the outline.
- The app currently displays only
Assets/Characters/Live2DPreview/leesori.png, not the full set ofsori_*expression PNGs.
Changed:
- Increased the WPF
Live2DCharacterViewheight to better match the EQ graph area. - Created non-destructive source candidates under:
src/DansoriEQ.App/Assets/Characters/SourceCandidates/
- Generated a new ChatGPT/imagegen LeeSori candidate with the same face, outfit, pose, teal hair, and headphones, but without the original white halo/sticker-style outer glow.
- Removed the generated magenta chroma-key background into real PNG alpha.
- Replaced the app-facing LeeSori files with the clean candidate:
src/DansoriEQ.App/Assets/Characters/sori_idle.pngsrc/DansoriEQ.App/Assets/Characters/Live2DPreview/leesori.png
Preserved:
- Original app character PNGs remain backed up in:
src/DansoriEQ.App/Assets/Characters_OriginalBackup/
- Generated candidates remain available for visual comparison in:
src/DansoriEQ.App/Assets/Characters/SourceCandidates/
Next validation:
- Rebuild the app and run it visually.
- If LeeSori now looks acceptable, generate matching clean variants for
sori_avatar_*andsori_happyonly when those states become visible in-app. - If the remaining right-sleeve bright line is still distracting, create one more imagegen pass specifically targeting sleeve/jacket edge highlights.
2026-07-03 - WebView Character Motion Layer
Changed:
- Extended the WebView character host to track
currentStateindependently from the selected character. - Added state image lookup through
characters.jsonusing an optionalstatesmap. - Added LeeSori state map placeholders for:
idlethinkingsuccesserror
- Kept all LeeSori states mapped to the cleaned app-facing PNG for now, so the improved no-halo artwork remains consistent.
- Added state-specific motion in CSS:
- idle breathing/float
- thinking faster bob plus accent glow
- success upward bounce
- error short shake, then return to idle
- Added temporary message timeout in the WebView host so AI status text returns to the character/state label after a few seconds.
Validation:
node --check src/DansoriEQ.App/Assets/Live2DHost/characterHost.js: passed.characters.jsonparses successfully with PowerShellConvertFrom-Json.dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.
Next recommended task:
- Run the WPF app and verify the right-side character now feels alive during idle, AI request, success, and error states.
- If the motion direction is acceptable, create clean expression variants for LeeSori and map them into
states. - After expression variants are stable, move from PNG placeholder animation to real Cubism model export/runtime integration.
2026-07-04 - LeeSori Layered Puppet Prototype
User feedback:
- The character moved, but it was still a single whole image moving with neon effects.
- Desired direction is separate part movement, not whole-image motion.
Changed:
- Copied LeeSori legacy full-canvas puppet parts into the app:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSori/Images/src/DansoriEQ.App/Assets/Characters/Puppets/LeeSori/rig.json
- Updated
DansoriEQ.App.csprojso Puppet PNG/JSON files are copied to the build output as Content. - Replaced the WebView host's LeeSori rendering path with a layered puppet renderer:
- fetches
rig.json - creates one DOM image layer per bone/part
- stacks parts by rig
z - applies each part's pivot as CSS
transform-origin
- fetches
- Removed the previous visible neon/glow elements from the host markup.
- Added separate CSS animations for part groups:
- head/neck
- chest/body breathing
- pelvis
- left/right arms and hands
- legs
- state-specific thinking/success/error motion
- Kept the clean single PNG preview as fallback if the puppet fails to load.
Known limitation:
- This uses the existing A-pose/full-body legacy puppet parts, so visual quality and framing may differ from the cleaned app-facing LeeSori portrait.
- This step is for validating part-based motion in the actual WPF/WebView pipeline.
- If accepted, the next art task is to generate a clean upper-body puppet part set from the approved LeeSori image style.
Validation:
node --check src/DansoriEQ.App/Assets/Live2DHost/characterHost.js: passed.characters.jsonparses successfully.dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output contains
rig.jsonand 17 LeeSori puppet PNG parts.
Next recommended task:
- Run the WPF app and verify that LeeSori parts now move independently.
- If part motion is technically acceptable, regenerate a clean upper-body part set matching the improved no-outline LeeSori art and replace this legacy A-pose puppet set.
2026-07-04 - Puppet Load Fix and Rebuild
User feedback:
- The app still looked almost the same, suggesting the previous build either was not picked up or the layered puppet did not actually load.
Finding:
- The build output contained the puppet files, but the WebView was opened through a local
file://URL. - That path can make JavaScript
fetch()forrig.jsonunreliable inside WebView2, causing the host to fall back to the single clean PNG preview.
Changed:
- Updated
Live2DCharacterView.xaml.csto expose the appAssetsfolder through WebView2SetVirtualHostNameToFolderMapping. - The host now loads from:
https://dansori-assets.local/Live2DHost/index.html?v=...
- This keeps
characters.json,rig.json, and puppet PNG files under one stable virtual origin. - Added a cache-busting query string to the host URL so rebuilt HTML/JS/CSS is not silently reused.
- Increased puppet part animation amplitude so the difference between fallback PNG motion and real part motion is visibly obvious during validation.
- Ran
dotnet cleanbefore rebuilding to remove stale output files.
Validation:
dotnet clean .\DansoriEQ.sln: passed.node --check src/DansoriEQ.App/Assets/Live2DHost/characterHost.js: passed.dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Output
style.csscontains the stronger puppet animation values. - Output
characterHost.jscontainsloadPuppet(),fetch(active.puppet.rig), andhas-puppetactivation.
Next validation:
- Run the rebuilt app from the current Debug output.
- If LeeSori appears as a smaller full-body A-pose and her head/arms move separately, the puppet pipeline is working.
- If the clean portrait still appears instead, inspect WebView2 runtime console/errors next.
2026-07-04 - Replace Legacy A-Pose Puppet With Approved-Ratio Upper Puppet
User feedback:
- The layered puppet pipeline is now visible: elbows/parts move independently even in idle.
- However, the legacy A-pose puppet has wrong head/body/headphone proportions.
Finding:
- The previous
LeeSoripuppet was only useful as a technical proof that separate parts can move in the WPF/WebView pipeline. - Its source art does not match the approved clean LeeSori portrait.
Changed:
- Created a new
LeeSoriUpperpuppet set from the approved cleansori_idle.pngportrait so face, body, and headphone proportions are preserved. - Generated full-canvas overlap-based parts under:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriUpper/Images/src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriUpper/rig.json
- QA composite saved at:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriUpper/qa_composite_black.png
- Switched
characters.jsonfrom the legacyLeeSoripuppet to the newLeeSoriUpperpuppet. - Reduced motion amplitude after the previous debug pass because the new overlap-based puppet should move subtly to avoid ghosting.
Design tradeoff:
- This is not final Cubism-grade part separation. It is an overlap puppet sliced from the approved portrait.
- The benefit is exact approved visual proportions.
- The cost is that large movements can reveal duplicated underlying art, so animation must stay subtle until a proper AI-generated or Cubism-authored layered source exists.
Validation:
node --check src/DansoriEQ.App/Assets/Live2DHost/characterHost.js: passed.characters.jsonparses and points LeeSori toLeeSoriUpper.dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output
characters.jsonalso points toLeeSoriUpper.
Next validation:
- Run the WPF app and confirm proportions now match the approved LeeSori portrait.
- If motion is still acceptable, next task is to improve true part separation quality by generating clean hidden-underlay patches for head/arm gaps or moving toward proper Cubism source layers.
2026-07-04 - LeeSori Framing Adjustment
User feedback:
- The new LeeSoriUpper puppet looks natural and proportions match.
- The character display has too much top empty space, so LeeSori should sit higher and show more lower body.
Changed:
- Adjusted WebView character framing in
style.css:right: -6%->right: -8%bottom: -5%->bottom: 4%width/height: 104%->112%
- This raises LeeSori within the black display area and slightly enlarges her so more lower body is visible while reducing top dead space.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains the new framing values.
2026-07-04 - Stronger LeeSoriUpper Framing Fix
User feedback:
- The previous framing change was not visually noticeable.
- Top whitespace remained large and the hand still appeared clipped.
Finding:
- The shared
#preview, #puppetrule changedheight, but#puppethad its ownheight: auto, so the visible puppet size was still mostly controlled by width. - The LeeSoriUpper canvas aspect is
1086 / 1448, not the old legacy520 / 900, so the puppet needed its own aspect-ratio and larger width.
Changed:
- Added puppet-specific framing:
right: -30%bottom: -2%width: 160%aspect-ratio: 1086 / 1448
- This makes the puppet fill the vertical character area much more strongly, reducing top dead space and making lower body/hand position changes visible.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains the new puppet-specific framing values.
2026-07-04 - Character Column Width Adjustment
User feedback:
- The previous CSS-only framing made the character image feel enlarged.
- The character display area still felt too narrow, causing the right elbow and left wrist/hand area to be clipped.
- Better direction: reduce the EQ graph width and increase the character display width.
Changed:
- WPF layout:
Live2DCharacterViewwidth:250->350- graph right margin:
270->370 - character right margin:
6->0
- WebView puppet framing:
- reduced puppet over-scaling from
160%to116% - set puppet
bottomto0% - kept a mild
right: -8%offset
- reduced puppet over-scaling from
Reasoning:
- The prior problem was available character-column width, not the sprite size itself.
- Enlarging the sprite inside a narrow column caused clipping.
- The new layout gives the character more real horizontal room while keeping its proportions natural.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains the updated puppet framing values.
2026-07-04 - FHD Window and No-Clip Character Fit
User feedback:
- Character column width fixed side clipping, but the top of the head and left hand were still clipped.
- Suggested increasing the app window size within FHD constraints and slightly reducing character scale.
Changed:
- Main window size:
1600x980->1700x1020- minimum size:
1360x820->1460x900
- Graph/character zone:
MinHeight: 545->600Live2DCharacterView: 350x545->390x600- graph right margin:
370->410 - EQ graph height:
480->520
- WebView puppet framing:
width: 116%->108%right: -8%->-4%bottom: 0%->3%
Reasoning:
- The character needed more real vertical and horizontal display area, not more internal sprite scaling.
- The new window size remains appropriate for FHD while giving the character enough room to avoid top/head and hand clipping.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains the new no-clip puppet framing values.
2026-07-04 - Hide Character Status Bubble and Reduce Motion Clipping
User feedback:
- Need to hide the
LeeSori - idlestatus box to determine whether the wrist is covered or actually clipped. - Character should be slightly smaller because animation can still clip top/bottom edges.
Changed:
- Hid the WebView status bubble with
display: noneon#bubble. - Reduced LeeSoriUpper puppet scale:
width: 108%->100%right: -4%->0%- kept
bottom: 4%
- Reduced vertical animation travel so motion is less likely to clip at the top/bottom.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains the hidden bubble and reduced puppet framing values.
2026-07-04 - Remove Reserved Bubble Area From Character Stage
User feedback:
- Hiding the
LeeSori - idlebubble did not change the wrist/hand clipping point. - This suggested the former bubble area was not part of the active character display area.
Finding:
#characterstill usedinset: 0 0 30px 0, reserving 30px at the bottom for the bubble even after the bubble was hidden.- Therefore the puppet could not use the bottom area where the bubble used to sit.
Changed:
- Changed
#characterfrominset: 0 0 30px 0toinset: 0. - Adjusted puppet/fallback bottom placement from
4%to2%so the character can use more vertical space without floating too high.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains
#character { inset: 0; }and updatedbottom: 2%values.
2026-07-04 - Direct Framing QA and Applied Candidate
User request:
- Directly inspect and choose a better ratio/position because the left wrist still appears clipped.
Finding:
- A local 390x600 viewport composite showed the WebView was no longer clipping the bottom after removing the reserved bubble area.
- The remaining wrist cutoff is mostly from the approved source portrait itself ending near that wrist/lower sleeve area.
- However, the previous framing still had too much top dead space.
QA artifact:
- Current render QA:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriUpper/qa_view_390x600_current.png
- Applied candidate QA:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriUpper/qa_view_390x600_candidate_96_bottom12.png
Changed:
- Applied the directly inspected candidate framing:
right: 2%bottom: 12%width: 96%
- This slightly reduces the character scale and raises her in the viewport, leaving animation headroom while reducing top whitespace.
Note:
- To fully reveal a hand/wrist that is cut off in the source artwork, the next step would be source image extension/outpainting or a cleaner lower-arm/hand part, not just CSS framing.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output CSS contains the applied candidate values.
2026-07-04 - Startup EQ Disabled and Extended LeeSori Puppet
User request:
- Program should start with EQ inactive/disabled.
- Continue image extension or part rewrite so wrist and lower body are not clipped and look natural.
Changed - EQ startup:
- Changed
ActiveToggledefault from checked to unchecked:IsChecked="True"->IsChecked="False"
- Changed internal bypass default:
_bypassednow starts astrue.
- Startup
ApplyEqToApo()therefore writes only bypass/volume preamp instead of applying active EQ filters.
Changed - character art:
- Generated a new AI-extended LeeSori source with full lower body, complete visible wrist/hand, shoes, and natural continuation of pants/jacket.
- Removed magenta chroma-key background to real PNG alpha.
- Saved source and QA artifacts under:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriExtended/
- Created a new full-body overlap puppet:
leesori_ext_baseleesori_ext_legsleesori_ext_chestleesori_ext_arm_l/rleesori_ext_hand_l/rleesori_ext_head
- Switched
characters.jsonfromLeeSoriUppertoLeeSoriExtended. - Applied safe full-body framing:
right: 10%bottom: 1%width: 80%
QA artifacts:
qa_extended_black.png: full alpha result on black background.qa_view_390x600_fullbody.png: initial 390x600 viewport check.qa_view_390x600_fullbody_safe.png: selected safe framing with no hand/head/lower-body clipping.
Tradeoff:
- The extended candidate solves wrist/lower-body clipping and gives a complete natural full body.
- Its face/headphone details are close but not pixel-identical to the previously approved upper portrait. If exact identity match becomes more important than full-body completeness, the next step is a targeted imagegen pass or manual hybrid compositing: approved upper portrait + generated lower-body/hand extension.
Validation:
node --check src/DansoriEQ.App/Assets/Live2DHost/characterHost.js: passed.characters.jsonparses and points LeeSori toLeeSoriExtended.dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output contains
LeeSoriExtendedrig and safe framing CSS values.
2026-07-04 - New Sheet LeeSoriV2 Conversion
User correction:
- The previous LeeSoriExtended puppet solved clipping but used the old LeeSori design.
- The authoritative new design sheet is:
Characters_Build_Docs/LeeSori_Profile/03_Assets/Reference/sori_sheet.png
Changed:
- Created
LeeSoriV2from the new sheet's front full-body pose without AI identity drift. - Extracted alpha-clean source and overlap puppet parts:
- base, legs, chest, left/right arms, left/right hands, head.
- Replaced the app preview image with the new sheet-based LeeSori.
- Switched
characters.jsonto:../Characters/Puppets/LeeSoriV2/rig.json../Characters/Puppets/LeeSoriV2/Images/
- Updated WebView framing for the new tall sheet ratio:
right: 17.5%bottom: -20%width: 65%
- Framing goal: upper-body biased view for idle/work states while keeping head and both hands visible. Full body remains available in the source/rig for later state-specific framing.
QA artifacts:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriV2/qa_source_black.pngsrc/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriV2/qa_view_390x600_upper_bias.pngsrc/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriV2/qa_view_390x600_css_selected.png
Next:
- Build and run in WPF to verify real WebView framing.
- If this sheet-based puppet is accepted, add state-specific animation tuning and then generate Haruka/Isabel/Noeul with the same source-first process.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output contains
LeeSoriV2rig/images and selected CSS framing values.
2026-07-04 - LeeSoriV2 Knee-Up Framing and Lower-Body Outline Fix
User request:
- Frame LeeSori from around the midpoint between above-knee and left-hand tip up to the top of the head.
- Fix the doubled green outline around both legs that appeared while the lower body moved.
Changed:
- Updated WebView puppet framing:
right: 6.5%bottom: -65%width: 87%
- Removed the animated
legsbone fromLeeSoriV2/rig.json. - The lower body now remains only in the base image, so the green pants side line no longer alternates between one and two outlines.
QA artifact:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriV2/qa_view_390x600_knee_upper.png
2026-07-04 - LeeSoriV2 Outline/Left-Hand Cleanup
User feedback:
- The knee-up framing is correct.
- The green pants side line still alternates between one and two outlines.
- The left hand looks slightly awkward.
Changed:
- Regenerated
LeeSoriV2puppet parts with tighter moving masks. - Removed animated
upperarm_landhand_lbones; the pocketed left hand now stays in the base image. - Kept the lower body only in the base image.
- Kept right-side hand/arm and head/chest motion for visible idle movement.
- Retained the accepted framing values:
right: 6.5%bottom: -65%width: 87%
QA artifact:
src/DansoriEQ.App/Assets/Characters/Puppets/LeeSoriV2/qa_view_390x600_v3_clean_outline.png
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output rig no longer references
legs,upperarm_l, orhand_lanimated bones.
2026-07-04 - LeeSoriV2 Cache-Busted V3 Puppet Assets
Problem:
- Even after removing animated lower/left-side bones, WebView2 could still show stale image assets because puppet image URLs reused the same PNG filenames.
Changed:
- Regenerated active LeeSoriV2 images with
leesori_v2_v3_*filenames. - Updated
characterHost.jsto append?v=to each puppet image URL. - Kept accepted framing unchanged:
right: 6.5%,bottom: -65%,width: 87%.
Validation:
node --check Assets/Live2DHost/characterHost.js: passed.dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.- Build output rig references only
leesori_v2_v3_*active images and no longer referenceslegs,upperarm_l, orhand_lbones.
2026-07-04 - LeeSoriV2 Reduced Breathing Transform
Changed:
- Removed
scaleYfromchestBreathandchestThinkingto avoid waist/pants boundary shimmer. - Reduced
armRightIdlerotation from-1.2/0.8degto-0.6/0.4deg. - Kept accepted framing unchanged.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.
2026-07-04 - LeeSoriV2 Waist Naturalization
User request:
- The LeeSori waist was too excessively narrow. Modify only that area to look natural.
Changed:
- Backed up the prior source as
LeeSoriV2/leesori_v2_source_pre_waist_fix.png. - Used an AI edit candidate only as a local waist-patch source, not as a full replacement, to preserve LeeSori identity and pose.
- Composited only the abdomen/waistband region into
leesori_v2_source.png. - Regenerated active
leesori_v2_v3_*puppet parts and preview from the patched source. - Kept accepted framing and rig bone policy unchanged.
QA artifacts:
LeeSoriV2/qa_source_waist_patch_black.png.LeeSoriV2/qa_view_390x600_v3_clean_outline.png.
Validation:
dotnet build .\DansoriEQ.sln: passed, 0 warnings, 0 errors.dotnet test .\DansoriEQ.sln --no-build: passed, 15/15 tests.