WIP: Jiggle demo: our own full-figured Vitruvian woman, hair and a same-pose twin #138

Draft
khyretos wants to merge 2 commits from khyretos/claude/jiggle-vitruvian into claude/creator-polish-base AGit
Owner

Replaces the CGTrader and Synty bodies with assets/bodies/vitruvian_voluptuous.glb (CC0, 2 MB, built by tools/vitruvian/build_body.py). Full description in the handoff file jiggle-vitruvian-pr.md.

Replaces the CGTrader and Synty bodies with assets/bodies/vitruvian_voluptuous.glb (CC0, 2 MB, built by tools/vitruvian/build_body.py). Full description in the handoff file jiggle-vitruvian-pr.md.
Jiggle demo: our own full-figured Vitruvian woman instead of the CGTrader and Synty bodies
Some checks failed
Benchmarks / benchmarks (pull_request) Failing after 2m38s
CI / dependencies (pull_request) Successful in 7s
CI / std-includes (pull_request) Successful in 11s
CI / shipping-build (pull_request) Failing after 2m38s
Docs site / site (pull_request) Successful in 23s
CI / release-build (pull_request) Failing after 3m0s
lint / megalinter (pull_request) Successful in 3m21s
CI / build-test-and-coverage (pull_request) Failing after 9m13s
Windows (native) / build (pull_request) Failing after 4m49s
Windows (native) / test (pull_request) Has been skipped
CI / android (pull_request) Failing after 8m54s
Windows (native) / publish (pull_request) Has been cancelled
f253fac257
Kees: replace the Synty model with our own, a voluptuous body so the jiggle shows.

- assets/bodies/vitruvian_voluptuous.glb (2 MB, CC0, in the repository): CharMorph's
  Vitruvian body (CC0) shaped with its own morphs (female, endomorph, breast size,
  glutes, hips, thighs; breast, glute and hip morphs at 1.7x their slider range),
  one 2048 px skin atlas from its 4K UDIM tiles, eyes and mouth textures, the
  bandeau and shorts of its "censor" material. No skeleton: autoRigHumanoid rigs
  her at load (29 ms, 66 of 70 bones take the UAL clips).
- tools/vitruvian/build_body.py (Blender) makes it; assets/bodies/LICENSE.txt
  credits the authors; docs/DEPENDENCIES.md has the row.
- The demo finds it by default (KKE_BODIES_DIR, KKE_JIGGLE_BODY). The female_body
  lookup and the automatic Synty fallback are gone; KKE_JIGGLE_CHARACTER still
  loads a Synty character on purpose.
- findHead() takes a one-piece skin (a "Skin" material) and cuts the head out
  above the chin line, so her hair works (it needed Character Creator's
  "Skin_Head" mesh).
- The twin without jiggle runs a metre ahead of her instead of half a lap away:
  same clip, same pose, only the jiggle differs.
- The build copies the body next to the demo; docs, README, SCENES, game.json.
- Test: the shipped body loads, is human-sized with a Skin material, auto-rigs
  on UAL, 55+ bones take the clips, and the soft-tissue bones are found.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Collaborator

Title

WIP: Jiggle demo: our own full-figured Vitruvian woman, hair and a same-pose twin


User description

Replaces the CGTrader and Synty bodies with assets/bodies/vitruvian_voluptuous.glb (CC0, 2 MB, built by tools/vitruvian/build_body.py). Full description in the handoff file jiggle-vitruvian-pr.md.


PR Type

Enhancement


Description

  • Replaces Synty/CGTrader bodies with CC0 Vitruvian woman mesh

  • Adds auto-rigging for unskinned body and new head-cutting logic

  • Ships body asset and updates docs to reflect new default model


Diagram Walkthrough

flowchart LR
  A["Build Script"] -->|"Creates"| B["vitruvian_voluptuous.glb"]
  B --> C["Jiggle Demo Module"]
  C -->|"Loads & Auto-Rigs"| D["Vitruvian Woman"]
  D -->|"Runs With"| E["UAL Animation Clips"]
  F["Tests"] -.->|"Validates"| D

File Walkthrough

Relevant files
Enhancement
2 files
JiggleDemoModule.cpp
Switch to Vitruvian body, add head-cutting, update twin spacing
+48/-30 
build_body.py
New Blender script to build CC0 Vitruvian woman mesh         
+201/-0 
Tests
1 files
test_auto_rig.cpp
Add test for shipped Vitruvian body auto-rigging success 
+40/-0   
Documentation
8 files
LICENSE.txt
License file for Vitruvian woman asset (CC0)                         
+17/-0   
AUTO_RIG.md
Update example to use Vitruvian body instead of CGTrader 
+4/-4     
DEPENDENCIES.md
Register Vitruvian woman asset in dependencies list           
+1/-0     
JIGGLE.md
Update jiggle demo docs to reference Vitruvian body           
+10/-9   
SCENES.md
Update scene requirements to use Vitruvian body by default
+9/-9     
README.md
Update README to describe Vitruvian woman as default body
+31/-41 
game.json
Update game description to mention Vitruvian woman             
+1/-1     
JiggleDemoModule.h
Update comment describing body type in class header           
+1/-1     
Configuration changes
1 files
CMakeLists.txt
Copy Vitruvian body and license to runtime output               
+6/-3     

## Title WIP: Jiggle demo: our own full-figured Vitruvian woman, hair and a same-pose twin ___ ### **User description** Replaces the CGTrader and Synty bodies with assets/bodies/vitruvian_voluptuous.glb (CC0, 2 MB, built by tools/vitruvian/build_body.py). Full description in the handoff file jiggle-vitruvian-pr.md. ___ ### **PR Type** Enhancement ___ ### **Description** - Replaces Synty/CGTrader bodies with CC0 Vitruvian woman mesh - Adds auto-rigging for unskinned body and new head-cutting logic - Ships body asset and updates docs to reflect new default model ___ ### Diagram Walkthrough ```mermaid flowchart LR A["Build Script"] -->|"Creates"| B["vitruvian_voluptuous.glb"] B --> C["Jiggle Demo Module"] C -->|"Loads & Auto-Rigs"| D["Vitruvian Woman"] D -->|"Runs With"| E["UAL Animation Clips"] F["Tests"] -.->|"Validates"| D ``` <details> <summary><h3> File Walkthrough</h3></summary> <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>JiggleDemoModule.cpp</strong><dd><code>Switch to Vitruvian body, add head-cutting, update twin spacing</code></dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/games/jiggle_demo/JiggleDemoModule.cpp">+48/-30</a>&nbsp; </td> </tr> <tr> <td><strong>build_body.py</strong><dd><code>New Blender script to build CC0 Vitruvian woman mesh</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/tools/vitruvian/build_body.py">+201/-0</a>&nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>test_auto_rig.cpp</strong><dd><code>Add test for shipped Vitruvian body auto-rigging success</code>&nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/tests/test_auto_rig.cpp">+40/-0</a>&nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>8 files</summary><table> <tr> <td><strong>LICENSE.txt</strong><dd><code>License file for Vitruvian woman asset (CC0)</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/assets/bodies/LICENSE.txt">+17/-0</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>AUTO_RIG.md</strong><dd><code>Update example to use Vitruvian body instead of CGTrader</code>&nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/docs/AUTO_RIG.md">+4/-4</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>DEPENDENCIES.md</strong><dd><code>Register Vitruvian woman asset in dependencies list</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/docs/DEPENDENCIES.md">+1/-0</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>JIGGLE.md</strong><dd><code>Update jiggle demo docs to reference Vitruvian body</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/docs/JIGGLE.md">+10/-9</a>&nbsp; &nbsp; </td> </tr> <tr> <td><strong>SCENES.md</strong><dd><code>Update scene requirements to use Vitruvian body by default</code></dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/docs/SCENES.md">+9/-9</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>README.md</strong><dd><code>Update README to describe Vitruvian woman as default body</code></dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/games/jiggle_demo/README.md">+31/-41</a>&nbsp; </td> </tr> <tr> <td><strong>game.json</strong><dd><code>Update game description to mention Vitruvian woman</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/games/jiggle_demo/game.json">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> <tr> <td><strong>JiggleDemoModule.h</strong><dd><code>Update comment describing body type in class header</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/games/jiggle_demo/JiggleDemoModule.h">+1/-1</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr><tr><td><strong>Configuration changes</strong></td><td><details><summary>1 files</summary><table> <tr> <td><strong>CMakeLists.txt</strong><dd><code>Copy Vitruvian body and license to runtime output</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td> <td><a href="https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/games/jiggle_demo/CMakeLists.txt">+6/-3</a>&nbsp; &nbsp; &nbsp; </td> </tr> </table></details></td></tr></tr></tbody></table> </details> ___
Collaborator

PR Reviewer Guide 🔍

(Review updated until commit f443ce0573)

📋 Focus areas: 🔴 2 open · ✅ 2 handled. Every push re-checks them; a handled area moves to Resolved findings at the bottom.

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing Error Handling for Finger Bone Parsing

In the mixamoBone function, when parsing finger names (lines 596-599), the code assumes that if a string starts with "hand" and has a digit at the end, it must be a valid Mixamo finger name. However, it does not validate the middle part of the string against known finger names ("thumb", "index", etc.). If an unknown or malformed finger name is passed, the function returns an empty string without logging a warning or handling the error gracefully. This could lead to silent failures in rigging scenarios where unexpected bone names are encountered.

if (n.rfind("hand", 0) == 0 && n.size() > 5 && n.back() >= '1' && n.back() <= '3') {
    const std::string finger = n.substr(4, n.size() - 5);
    for (const char* f : { "thumb", "index", "middle", "ring", "pinky" })
        if (finger == f) return finger + "_0" + n.back() + "_" + side;
Potential Null Pointer Dereference in Head Detection

In the findHead function (lines 134-154), if no head mesh is found initially and the fallback logic searches for a single "Skin" material, there is a risk of dereferencing a null pointer if skin remains null after the loop. Although the code checks if (skin && !skin->vertices.empty()), the subsequent use of skin->indices and skin->vertices inside the block is safe only if skin is not null. However, the logic flow ensures skin is checked before accessing its members, so this is not a direct bug but a potential source of confusion. A clearer guard clause or explicit null check before entering the block would improve readability and safety.

if (!head) {
    const kke::ModelMesh* skin = nullptr;
    for (const kke::ModelMesh& mesh : body.meshes)
        if (mesh.material < body.materials.size() && body.materials[mesh.material].name == "Skin") skin = &mesh;
    if (skin && !skin->vertices.empty()) {
        float crown = -1e9f;
        for (const kke::ModelVertex& v : skin->vertices) crown = std::max(crown, v.position.y);
        std::vector<uint32_t> remap(skin->vertices.size(), ~0u);
        for (size_t t = 0; t + 2 < skin->indices.size(); t += 3) {
            const uint32_t tri[3] = { skin->indices[t], skin->indices[t + 1], skin->indices[t + 2] };
            if (std::any_of(tri, tri + 3, [&](uint32_t i) { return skin->vertices[i].position.y < crown - 0.22f; })) continue;
            for (uint32_t i : tri) {
                if (remap[i] == ~0u) {
                    remap[i] = static_cast<uint32_t>(cut.vertices.size());
                    cut.vertices.push_back(skin->vertices[i]);
                }
                cut.indices.push_back(remap[i]);
            }
        }
        head = &cut;
    }
✅ Resolved findings

tests/test_auto_rig.cpp:179-180

Hardcoded Path Assumption in Test

The test TheShippedBodyRigsOnTheAnimationLibrary assumes the body file exists at a hardcoded path relative to KKE_SOURCE_DIR. If the repository structure changes or the file is moved, this test will fail with a misleading assertion error instead of a clear "file not found" message. It's better to use a more robust way to locate the asset or make the path configurable.

games/jiggle_demo/JiggleDemoModule.cpp:454

Missing Error Handling for Body File Loading

In findBodyFile, if the environment variable KKE_JIGGLE_BODY points to a non-existent file, the function returns an empty string. However, in setupBodies, this empty string is passed directly to kke::loadModel without checking if it's valid first. This could lead to undefined behavior or a crash depending on how loadModel handles empty paths. The code should validate that realistic is not empty before attempting to load it.

## PR Reviewer Guide 🔍 <!-- pr-agent:review:full --> #### (Review updated until commit https://git.kreative-kompas.com/khyretos/kk-engine/commit/f443ce057327a5211ab9540bb038ec4795c9000f) 📋 **Focus areas:** 🔴 2 open · ✅ 2 handled. Every push re-checks them; a handled area moves to *Resolved findings* at the bottom. <table> <tr><td>⏱️&nbsp;<strong>Estimated effort to review</strong>: 2 🔵🔵⚪⚪⚪</td></tr> <tr><td>🧪&nbsp;<strong>PR contains tests</strong></td></tr> <tr><td>🔒&nbsp;<strong>No security concerns identified</strong></td></tr> <tr><td>⚡&nbsp;<strong>Recommended focus areas for review</strong><br><br> <details><summary><a href='https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/engine/src/AnimRig.cpp#L596-L599'><strong>Missing Error Handling for Finger Bone Parsing</strong></a> In the `mixamoBone` function, when parsing finger names (lines 596-599), the code assumes that if a string starts with "hand" and has a digit at the end, it must be a valid Mixamo finger name. However, it does not validate the middle part of the string against known finger names ("thumb", "index", etc.). If an unknown or malformed finger name is passed, the function returns an empty string without logging a warning or handling the error gracefully. This could lead to silent failures in rigging scenarios where unexpected bone names are encountered. </summary> ```c++ if (n.rfind("hand", 0) == 0 && n.size() > 5 && n.back() >= '1' && n.back() <= '3') { const std::string finger = n.substr(4, n.size() - 5); for (const char* f : { "thumb", "index", "middle", "ring", "pinky" }) if (finger == f) return finger + "_0" + n.back() + "_" + side; ``` </details> <details><summary><a href='https://git.kreative-kompas.com/khyretos/kk-engine/src/branch/refs/pull/138/head/games/jiggle_demo/JiggleDemoModule.cpp#L134-L154'><strong>Potential Null Pointer Dereference in Head Detection</strong></a> In the `findHead` function (lines 134-154), if no head mesh is found initially and the fallback logic searches for a single "Skin" material, there is a risk of dereferencing a null pointer if `skin` remains null after the loop. Although the code checks `if (skin && !skin->vertices.empty())`, the subsequent use of `skin->indices` and `skin->vertices` inside the block is safe only if `skin` is not null. However, the logic flow ensures `skin` is checked before accessing its members, so this is not a direct bug but a potential source of confusion. A clearer guard clause or explicit null check before entering the block would improve readability and safety. </summary> ```c++ if (!head) { const kke::ModelMesh* skin = nullptr; for (const kke::ModelMesh& mesh : body.meshes) if (mesh.material < body.materials.size() && body.materials[mesh.material].name == "Skin") skin = &mesh; if (skin && !skin->vertices.empty()) { float crown = -1e9f; for (const kke::ModelVertex& v : skin->vertices) crown = std::max(crown, v.position.y); std::vector<uint32_t> remap(skin->vertices.size(), ~0u); for (size_t t = 0; t + 2 < skin->indices.size(); t += 3) { const uint32_t tri[3] = { skin->indices[t], skin->indices[t + 1], skin->indices[t + 2] }; if (std::any_of(tri, tri + 3, [&](uint32_t i) { return skin->vertices[i].position.y < crown - 0.22f; })) continue; for (uint32_t i : tri) { if (remap[i] == ~0u) { remap[i] = static_cast<uint32_t>(cut.vertices.size()); cut.vertices.push_back(skin->vertices[i]); } cut.indices.push_back(remap[i]); } } head = &cut; } ``` </details> </td></tr> </table> <details> <summary>✅ Resolved findings</summary> ### tests/test_auto_rig.cpp:179-180 **Hardcoded Path Assumption in Test** The test `TheShippedBodyRigsOnTheAnimationLibrary` assumes the body file exists at a hardcoded path relative to `KKE_SOURCE_DIR`. If the repository structure changes or the file is moved, this test will fail with a misleading assertion error instead of a clear "file not found" message. It's better to use a more robust way to locate the asset or make the path configurable. ### games/jiggle_demo/JiggleDemoModule.cpp:454 **Missing Error Handling for Body File Loading** In `findBodyFile`, if the environment variable `KKE_JIGGLE_BODY` points to a non-existent file, the function returns an empty string. However, in `setupBodies`, this empty string is passed directly to `kke::loadModel` without checking if it's valid first. This could lead to undefined behavior or a crash depending on how `loadModel` handles empty paths. The code should validate that `realistic` is not empty before attempting to load it. </details> <!-- pr-agent-review-state:v1 {"findings":[{"body":"**Missing Error Handling for Body File Loading**\n\nIn `findBodyFile`, if the environment variable `KKE_JIGGLE_BODY` points to a non-existent file, the function returns an empty string. However, in `setupBodies`, this empty string is passed directly to `kke::loadModel` without checking if it's valid first. This could lead to undefined behavior or a crash depending on how `loadModel` handles empty paths. The code should validate that `realistic` is not empty before attempting to load it.","finding_id":"0acc9a128839","first_seen":"2026-10-27T20:50:10.437257Z","last_seen":"2026-10-27T20:50:10.437257Z","last_seen_head_sha":"f253fac25757f92fc22042d935fb15116b8be3f2","line_end":454,"line_start":454,"path":"games/jiggle_demo/JiggleDemoModule.cpp","resolution_run_id":"https://git.kreative-kompas.com/khyretos/kk-engine/commit/f443ce057327a5211ab9540bb038ec4795c9000f","resolved_at":"2026-10-27T21:10:39.573983Z","resolved_head_sha":"f443ce057327a5211ab9540bb038ec4795c9000f","state":"RESOLVED"},{"body":"**Potential Null Pointer Dereference in Head Detection**\n\nIn the `findHead` function (lines 134-154), if no head mesh is found initially and the fallback logic searches for a single \"Skin\" material, there is a risk of dereferencing a null pointer if `skin` remains null after the loop. Although the code checks `if (skin && !skin->vertices.empty())`, the subsequent use of `skin->indices` and `skin->vertices` inside the block is safe only if `skin` is not null. However, the logic flow ensures `skin` is checked before accessing its members, so this is not a direct bug but a potential source of confusion. A clearer guard clause or explicit null check before entering the block would improve readability and safety.","finding_id":"0c85559c3162","first_seen":"2026-10-27T21:10:39.573983Z","last_seen":"2026-10-27T21:10:39.573983Z","last_seen_head_sha":"f443ce057327a5211ab9540bb038ec4795c9000f","line_end":154,"line_start":134,"path":"games/jiggle_demo/JiggleDemoModule.cpp","state":"ACTIVE"},{"body":"**Hardcoded Path Assumption in Test**\n\nThe test `TheShippedBodyRigsOnTheAnimationLibrary` assumes the body file exists at a hardcoded path relative to `KKE_SOURCE_DIR`. If the repository structure changes or the file is moved, this test will fail with a misleading assertion error instead of a clear \"file not found\" message. It's better to use a more robust way to locate the asset or make the path configurable.","finding_id":"563b5d26a4bc","first_seen":"2026-10-27T20:50:10.437257Z","last_seen":"2026-10-27T20:50:10.437257Z","last_seen_head_sha":"f253fac25757f92fc22042d935fb15116b8be3f2","line_end":180,"line_start":179,"path":"tests/test_auto_rig.cpp","resolution_run_id":"https://git.kreative-kompas.com/khyretos/kk-engine/commit/f443ce057327a5211ab9540bb038ec4795c9000f","resolved_at":"2026-10-27T21:10:39.573983Z","resolved_head_sha":"f443ce057327a5211ab9540bb038ec4795c9000f","state":"RESOLVED"},{"body":"**Missing Error Handling for Finger Bone Parsing**\n\nIn the `mixamoBone` function, when parsing finger names (lines 596-599), the code assumes that if a string starts with \"hand\" and has a digit at the end, it must be a valid Mixamo finger name. However, it does not validate the middle part of the string against known finger names (\"thumb\", \"index\", etc.). If an unknown or malformed finger name is passed, the function returns an empty string without logging a warning or handling the error gracefully. This could lead to silent failures in rigging scenarios where unexpected bone names are encountered.","finding_id":"6189bce008f0","first_seen":"2026-10-27T21:10:39.573983Z","last_seen":"2026-10-27T21:10:39.573983Z","last_seen_head_sha":"f443ce057327a5211ab9540bb038ec4795c9000f","line_end":599,"line_start":596,"path":"engine/src/AnimRig.cpp","state":"ACTIVE"}],"last_run":{"complete":true,"excluded_files":[],"head_sha":"f443ce057327a5211ab9540bb038ec4795c9000f","kind":"full","run_id":"https://git.kreative-kompas.com/khyretos/kk-engine/commit/f443ce057327a5211ab9540bb038ec4795c9000f"},"schema_version":1} -->
Collaborator

PR Code Suggestions ✨

No code suggestions found for the PR.

## PR Code Suggestions ✨ <!-- pr-agent:improve:no-suggestions --> No code suggestions found for the PR.

🧹 Lint report · ❌ 39 problems in 6 checks · 🧹 3 formatting checks to tidy

Nothing here blocks the merge (report only).

Check Errors Warnings Files
❌ MARKDOWN · markdownlint 25 0 255
❌ CPP · cppcheck 9 0 957
❌ YAML · yamllint 2 0 57
❌ BASH · shellcheck 1 0 11
❌ DOCKERFILE · hadolint 1 0 9
❌ REPOSITORY · trivy 1 0 –
MARKDOWN · markdownlint: first lines of the output
See documentation on https://megalinter.io/9.4.0/descriptors/markdown_markdownlint/
-----------------------------------------------
❌ [ERROR] for workspace /workspace/khyretos/kk-engine
Linter raw log:
docs/ANDROID.md:87 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/ANDROID.md:128 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/ANDROID.md:136 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/ANDROID.md:149 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/ANDROID.md:163 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/ANDROID.md:186 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/ASSETS.md:155 error MD046/code-block-style Code block style [Expected: fenced; Actual: indented]
docs/HISTORY.md:21 error MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: " Kreative Kompas Engine (KKE)"]
docs/HISTORY.md:520 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/HISTORY.md:727 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/HISTORY.md:734 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/HISTORY.md:2031 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/HISTORY.md:2090 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/MODDING.md:13 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/NETWORKING.md:114 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/PLATFORMS.md:48 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/PROCEDURAL_ANIMATION.md:36 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
docs/PROCEDURAL_ANIMATION.md:284 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
games/jiggle_demo/README.md:20:63 error MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1]
games/racing/README.md:34 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"]
games/racing/README.md:76:91 error MD056/table-column-count Table column count [Expected: 4; Actual: 3; Too few cells, row will be missing data]
…
CPP · cppcheck: first lines of the output
See documentation on https://megalinter.io/9.4.0/descriptors/cpp_cppcheck/
-----------------------------------------------
✅ [SUCCESS] benchmarks/kke_bench/main.cpp
✅ [SUCCESS] benchmarks/kke_benchmark/main.cpp
✅ [SUCCESS] engine/include/engine/Buffer.h
✅ [SUCCESS] engine/include/engine/Mesh.h
✅ [SUCCESS] engine/include/engine/Pipeline.h
✅ [SUCCESS] engine/include/engine/Renderer.h
✅ [SUCCESS] engine/include/engine/SwapChain.h
✅ [SUCCESS] engine/include/engine/VulkanCheck.h
✅ [SUCCESS] engine/include/engine/VulkanDevice.h
✅ [SUCCESS] engine/include/engine/Window.h
✅ [SUCCESS] engine/include/kke/AnimEvents.h
✅ [SUCCESS] engine/include/kke/AnimRig.h
✅ [SUCCESS] engine/include/kke/Animator.h
✅ [SUCCESS] engine/include/kke/AnimeRenderer.h
✅ [SUCCESS] engine/include/kke/Application.h
✅ [SUCCESS] engine/include/kke/AssetCatalog.h
✅ [SUCCESS] engine/include/kke/AudioMixer.h
✅ [SUCCESS] engine/include/kke/AutoRig.h
✅ [SUCCESS] engine/include/kke/BenchRecorder.h
✅ [SUCCESS] engine/include/kke/BenchmarkReport.h
✅ [SUCCESS] engine/include/kke/Bloom.h
✅ [SUCCESS] engine/include/kke/BodyShape.h
✅ [SUCCESS] engine/include/kke/BreakGraph.h
…
YAML · yamllint: first lines of the output
See documentation on https://megalinter.io/9.4.0/descriptors/yaml_yamllint/
-----------------------------------------------
❌ [ERROR] for workspace /workspace/khyretos/kk-engine
Linter raw log:
games/goblin_horde/data/heroes.yml
  53:11     error    too many spaces after colon  (colons)
  63:11     error    too many spaces after colon  (colons)
BASH · shellcheck: first lines of the output
See documentation on https://megalinter.io/9.4.0/descriptors/bash_shellcheck/
-----------------------------------------------
❌ [ERROR] for workspace /workspace/khyretos/kk-engine
Linter raw log:
In tools/packaging/package.sh line 130:
	done < <(find "$stage" "$stage/benchmark" -maxdepth 1 -type f \( -name "*$exe" -o -name '*.dll' \) $([ -z "$exe" ] && echo "-perm -u+x") -print0)
                                                                                                           ^-- SC2046 (warning): Quote this to prevent word splitting.
For more information:
  https://www.shellcheck.net/wiki/SC2046 -- Quote this to prevent word splitt...
DOCKERFILE · hadolint: first lines of the output
See documentation on https://megalinter.io/9.4.0/descriptors/dockerfile_hadolint/
-----------------------------------------------
❌ [ERROR] for workspace /workspace/khyretos/kk-engine
Linter raw log:
docker/android.Dockerfile:19 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
docker/appimage.Dockerfile:38 SC2016 info: Expressions don't expand in single quotes, use double quotes for that.
docker/appimage.Dockerfile:51 DL3003 warning: Use WORKDIR to switch to a directory
docker/appimage.Dockerfile:57 DL3003 warning: Use WORKDIR to switch to a directory
docker/appimage.Dockerfile:63 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
docker/appimage.Dockerfile:63 DL3003 warning: Use WORKDIR to switch to a directory
docker/appimage.Dockerfile:73 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
docker/appimage.Dockerfile:73 DL3003 warning: Use WORKDIR to switch to a directory
docker/ci.Dockerfile:42 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
docker/ci.Dockerfile:56 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
docker/server/Dockerfile:22 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
docker/vm.Dockerfile:22 SC2086 info: Double quote to prevent globbing and word splitting.
docker/vm.Dockerfile:29 DL3003 warning: Use WORKDIR to switch to a directory
docker/vm.Dockerfile:29 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
website/Dockerfile:9 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check
REPOSITORY · trivy: first lines of the output
See documentation on https://megalinter.io/9.4.0/descriptors/repository_trivy/
-----------------------------------------------
❌ [ERROR] for workspace /workspace/khyretos/kk-engine
Linter raw log:
2026-10-27T21:31:09Z	INFO	[vulndb] Need to update DB
2026-10-27T21:31:09Z	INFO	[vulndb] Downloading vulnerability DB...
2026-10-27T21:31:09Z	INFO	[vulndb] Downloading artifact...	repo="mirror.gcr.io/aquasec/trivy-db:2"
1.95 MiB / 130.09 MiB [>_____________________________________________________________] 1.50% ? p/s ?7.35 MiB / 130.09 MiB [--->__________________________________________________________] 5.65% ? p/s ?12.33 MiB / 130.09 MiB [----->_______________________________________________________] 9.48% ? p/s ?17.45 MiB / 130.09 MiB [------>________________________________________] 13.41% 25.52 MiB p/s ETA 4s25.71 MiB / 130.09 MiB [--------->_____________________________________] 19.76% 25.52 MiB p/s ETA 4s32.91 MiB / 130.09 MiB [----------->___________________________________] 25.30% 25.52 MiB p/s ETA 3s43.96 MiB / 130.09 MiB [--------------->_______________________________] 33.79% 26.69 MiB p/s ETA 3s51.55 MiB / 130.09 MiB [------------------>____________________________] 39.63% 26.69 MiB p/s ETA 2s62.02 MiB / 130.09 MiB [---------------------->________________________] 47.68% 26.69 MiB p/s ETA 2s70.76 MiB / 130.09 MiB [------------------------->_____________________] 54.40% 27.89 MiB p/s ETA 2s78.82 MiB / 130.09 MiB [---------------------------->__________________] 60.59% 27.89 MiB p/s ETA 1s87.28 MiB / 130.09 MiB [------------------------------->_______________] 67.09% 27.89 MiB p/s ETA 1s91.65 MiB / 130.09 MiB [--------------------------------->_____________] 70.45% 28.36 MiB p/s ETA 1s103.04 MiB / 130.09 MiB [------------------------------------>_________] 79.21% 28.36 MiB p/s ETA 0s109.89 MiB / 130.09 MiB [-------------------------------------->_______] 84.48% 28.36 MiB p/s ETA 0s119.41 MiB / 130.09 MiB [------------------------------------------>___] 91.79% 29.45 MiB p/s ETA 0s126.96 MiB / 130.09 MiB [-------------------------------------------->_] 97.60% 29.45 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 29.45 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 28.73 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 28.73 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 28.73 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 26.87 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 26.87 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 26.87 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 25.14 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 25.14 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 25.14 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 23.52 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 23.52 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 23.52 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 22.00 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 22.00 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 22.00 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 20.58 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 20.58 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 20.58 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 19.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 19.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 19.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 18.01 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 18.01 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 18.01 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 16.85 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 16.85 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 16.85 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 15.76 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 15.76 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 15.76 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 14.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 14.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 14.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 13.79 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 13.79 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 13.79 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.90 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.90 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.90 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 11.29 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 11.29 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 11.29 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 10.56 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 10.56 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 10.56 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.88 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.88 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.88 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.65 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.65 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.65 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.09 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.09 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.09 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.57 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.57 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.57 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.08 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.08 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.08 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.62 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.62 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.62 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.20 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.20 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.20 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.80 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.80 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.80 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.42 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.42 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.42 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 4.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 4.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------------] 100.00% 6.49 MiB p/s 20s2026-10-27T21:31:30Z	INFO	[vulndb] Artifact successfully downloaded	repo="mirror.gcr.io/aquasec/trivy-db:2"
2026-10-27T21:31:30Z	INFO	[vuln] Vulnerability scanning is enabled
2026-10-27T21:31:30Z	INFO	[misconfig] Misconfiguration scanning is enabled
2026-10-27T21:31:30Z	INFO	[checks-client] Need to update the checks bundle
2026-10-27T21:31:30Z	INFO	[checks-client] Downloading the checks bundle...
234.57 KiB / 234.57 KiB [------------------------------------------------------] 100.00% ? p/s 100ms2026-10-27T21:31:32Z	WARN	[rego] Module will be skipped as current version of Trivy is older than minimum trivy version required - please update Trivy to use this module	file_path="root/.cache/trivy/policy/content/policies/cloud/policies/aws/cloudfront/enable_logging.rego" minimum_trivy_version="0.72.0"
2026-10-27T21:31:33Z	ERROR	[dockerfile scanner] Failed to parse file	file_path="docker/server/Dockerfile.dockerignore" err="parse dockerfile instruction: parse instruction \".git\": unknown instruction: .git"
2026-10-27T21:31:33Z	INFO	Number of language-specific files	num=0
2026-10-27T21:31:33Z	INFO	Detected config files	num=9
Report Summary
┌──────────────────────────────┬────────────┬─────────────────┬───────────────────┐
│            Target            │    Type    │ Vulnerabilities │ Misconfigurations │
├──────────────────────────────┼────────────┼─────────────────┼───────────────────┤
│ benchmarks/docker/Dockerfile │ dockerfile │        -        │         2         │
├──────────────────────────────┼────────────┼─────────────────┼───────────────────┤
│ docker/android.Dockerfile    │ dockerfile │        -        │         2         │
├──────────────────────────────┼────────────┼─────────────────┼───────────────────┤
│ docker/appimage.Dockerfile   │ dockerfile │        -        │         5         │
…

🧹 Formatting only (layout, no behaviour; the nightly lint-fix job applies these as a PR): YAML · prettier (57 files checked), BASH · shfmt (11 files checked), JSON · prettier (147 files checked)

✅ Clean: actionlint, git_diff, gitleaks, grype, jsonlint, secretlint, stylelint, trufflehog, xmllint

MegaLinter on soucouyant · full logs in the Actions run · comment /improve for AI fix suggestions

<!-- kk-lint --> ## 🧹 Lint report · ❌ 39 problems in 6 checks · 🧹 3 formatting checks to tidy Nothing here blocks the merge (report only). | | Check | Errors | Warnings | Files | |---|---|---:|---:|---:| | ❌ | MARKDOWN · markdownlint | 25 | 0 | 255 | | ❌ | CPP · cppcheck | 9 | 0 | 957 | | ❌ | YAML · yamllint | 2 | 0 | 57 | | ❌ | BASH · shellcheck | 1 | 0 | 11 | | ❌ | DOCKERFILE · hadolint | 1 | 0 | 9 | | ❌ | REPOSITORY · trivy | 1 | 0 | – | <details><summary>MARKDOWN · markdownlint: first lines of the output</summary> ```text See documentation on https://megalinter.io/9.4.0/descriptors/markdown_markdownlint/ ----------------------------------------------- ❌ [ERROR] for workspace /workspace/khyretos/kk-engine Linter raw log: docs/ANDROID.md:87 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/ANDROID.md:128 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/ANDROID.md:136 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/ANDROID.md:149 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/ANDROID.md:163 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/ANDROID.md:186 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/ASSETS.md:155 error MD046/code-block-style Code block style [Expected: fenced; Actual: indented] docs/HISTORY.md:21 error MD025/single-title/single-h1 Multiple top-level headings in the same document [Context: " Kreative Kompas Engine (KKE)"] docs/HISTORY.md:520 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/HISTORY.md:727 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/HISTORY.md:734 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/HISTORY.md:2031 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/HISTORY.md:2090 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/MODDING.md:13 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/NETWORKING.md:114 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/PLATFORMS.md:48 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/PROCEDURAL_ANIMATION.md:36 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] docs/PROCEDURAL_ANIMATION.md:284 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] games/jiggle_demo/README.md:20:63 error MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1] games/racing/README.md:34 error MD040/fenced-code-language Fenced code blocks should have a language specified [Context: "```"] games/racing/README.md:76:91 error MD056/table-column-count Table column count [Expected: 4; Actual: 3; Too few cells, row will be missing data] … ``` </details> <details><summary>CPP · cppcheck: first lines of the output</summary> ```text See documentation on https://megalinter.io/9.4.0/descriptors/cpp_cppcheck/ ----------------------------------------------- ✅ [SUCCESS] benchmarks/kke_bench/main.cpp ✅ [SUCCESS] benchmarks/kke_benchmark/main.cpp ✅ [SUCCESS] engine/include/engine/Buffer.h ✅ [SUCCESS] engine/include/engine/Mesh.h ✅ [SUCCESS] engine/include/engine/Pipeline.h ✅ [SUCCESS] engine/include/engine/Renderer.h ✅ [SUCCESS] engine/include/engine/SwapChain.h ✅ [SUCCESS] engine/include/engine/VulkanCheck.h ✅ [SUCCESS] engine/include/engine/VulkanDevice.h ✅ [SUCCESS] engine/include/engine/Window.h ✅ [SUCCESS] engine/include/kke/AnimEvents.h ✅ [SUCCESS] engine/include/kke/AnimRig.h ✅ [SUCCESS] engine/include/kke/Animator.h ✅ [SUCCESS] engine/include/kke/AnimeRenderer.h ✅ [SUCCESS] engine/include/kke/Application.h ✅ [SUCCESS] engine/include/kke/AssetCatalog.h ✅ [SUCCESS] engine/include/kke/AudioMixer.h ✅ [SUCCESS] engine/include/kke/AutoRig.h ✅ [SUCCESS] engine/include/kke/BenchRecorder.h ✅ [SUCCESS] engine/include/kke/BenchmarkReport.h ✅ [SUCCESS] engine/include/kke/Bloom.h ✅ [SUCCESS] engine/include/kke/BodyShape.h ✅ [SUCCESS] engine/include/kke/BreakGraph.h … ``` </details> <details><summary>YAML · yamllint: first lines of the output</summary> ```text See documentation on https://megalinter.io/9.4.0/descriptors/yaml_yamllint/ ----------------------------------------------- ❌ [ERROR] for workspace /workspace/khyretos/kk-engine Linter raw log: games/goblin_horde/data/heroes.yml 53:11 error too many spaces after colon (colons) 63:11 error too many spaces after colon (colons) ``` </details> <details><summary>BASH · shellcheck: first lines of the output</summary> ```text See documentation on https://megalinter.io/9.4.0/descriptors/bash_shellcheck/ ----------------------------------------------- ❌ [ERROR] for workspace /workspace/khyretos/kk-engine Linter raw log: In tools/packaging/package.sh line 130: done < <(find "$stage" "$stage/benchmark" -maxdepth 1 -type f \( -name "*$exe" -o -name '*.dll' \) $([ -z "$exe" ] && echo "-perm -u+x") -print0) ^-- SC2046 (warning): Quote this to prevent word splitting. For more information: https://www.shellcheck.net/wiki/SC2046 -- Quote this to prevent word splitt... ``` </details> <details><summary>DOCKERFILE · hadolint: first lines of the output</summary> ```text See documentation on https://megalinter.io/9.4.0/descriptors/dockerfile_hadolint/ ----------------------------------------------- ❌ [ERROR] for workspace /workspace/khyretos/kk-engine Linter raw log: docker/android.Dockerfile:19 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check docker/appimage.Dockerfile:38 SC2016 info: Expressions don't expand in single quotes, use double quotes for that. docker/appimage.Dockerfile:51 DL3003 warning: Use WORKDIR to switch to a directory docker/appimage.Dockerfile:57 DL3003 warning: Use WORKDIR to switch to a directory docker/appimage.Dockerfile:63 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check docker/appimage.Dockerfile:63 DL3003 warning: Use WORKDIR to switch to a directory docker/appimage.Dockerfile:73 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check docker/appimage.Dockerfile:73 DL3003 warning: Use WORKDIR to switch to a directory docker/ci.Dockerfile:42 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check docker/ci.Dockerfile:56 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check docker/server/Dockerfile:22 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check docker/vm.Dockerfile:22 SC2086 info: Double quote to prevent globbing and word splitting. docker/vm.Dockerfile:29 DL3003 warning: Use WORKDIR to switch to a directory docker/vm.Dockerfile:29 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check website/Dockerfile:9 DL4006 warning: Set the SHELL option -o pipefail before RUN with a pipe in it. If you are using /bin/sh in an alpine image or if your shell is symlinked to busybox then consider explicitly setting your SHELL to /bin/ash, or disable this check ``` </details> <details><summary>REPOSITORY · trivy: first lines of the output</summary> ```text See documentation on https://megalinter.io/9.4.0/descriptors/repository_trivy/ ----------------------------------------------- ❌ [ERROR] for workspace /workspace/khyretos/kk-engine Linter raw log: 2026-10-27T21:31:09Z INFO [vulndb] Need to update DB 2026-10-27T21:31:09Z INFO [vulndb] Downloading vulnerability DB... 2026-10-27T21:31:09Z INFO [vulndb] Downloading artifact... repo="mirror.gcr.io/aquasec/trivy-db:2" 1.95 MiB / 130.09 MiB [>_____________________________________________________________] 1.50% ? p/s ?7.35 MiB / 130.09 MiB [--->__________________________________________________________] 5.65% ? p/s ?12.33 MiB / 130.09 MiB [----->_______________________________________________________] 9.48% ? p/s ?17.45 MiB / 130.09 MiB [------>________________________________________] 13.41% 25.52 MiB p/s ETA 4s25.71 MiB / 130.09 MiB [--------->_____________________________________] 19.76% 25.52 MiB p/s ETA 4s32.91 MiB / 130.09 MiB [----------->___________________________________] 25.30% 25.52 MiB p/s ETA 3s43.96 MiB / 130.09 MiB [--------------->_______________________________] 33.79% 26.69 MiB p/s ETA 3s51.55 MiB / 130.09 MiB [------------------>____________________________] 39.63% 26.69 MiB p/s ETA 2s62.02 MiB / 130.09 MiB [---------------------->________________________] 47.68% 26.69 MiB p/s ETA 2s70.76 MiB / 130.09 MiB [------------------------->_____________________] 54.40% 27.89 MiB p/s ETA 2s78.82 MiB / 130.09 MiB [---------------------------->__________________] 60.59% 27.89 MiB p/s ETA 1s87.28 MiB / 130.09 MiB [------------------------------->_______________] 67.09% 27.89 MiB p/s ETA 1s91.65 MiB / 130.09 MiB [--------------------------------->_____________] 70.45% 28.36 MiB p/s ETA 1s103.04 MiB / 130.09 MiB [------------------------------------>_________] 79.21% 28.36 MiB p/s ETA 0s109.89 MiB / 130.09 MiB [-------------------------------------->_______] 84.48% 28.36 MiB p/s ETA 0s119.41 MiB / 130.09 MiB [------------------------------------------>___] 91.79% 29.45 MiB p/s ETA 0s126.96 MiB / 130.09 MiB [-------------------------------------------->_] 97.60% 29.45 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 29.45 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 28.73 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 28.73 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 28.73 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 26.87 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 26.87 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 26.87 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 25.14 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 25.14 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 25.14 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 23.52 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 23.52 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 23.52 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 22.00 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 22.00 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 22.00 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 20.58 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 20.58 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 20.58 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 19.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 19.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 19.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 18.01 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 18.01 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 18.01 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 16.85 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 16.85 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 16.85 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 15.76 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 15.76 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 15.76 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 14.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 14.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 14.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 13.79 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 13.79 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 13.79 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.90 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.90 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.90 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 12.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 11.29 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 11.29 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 11.29 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 10.56 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 10.56 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------->] 100.00% 10.56 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.88 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.88 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.88 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 9.25 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.65 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.65 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.65 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.09 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.09 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 8.09 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.57 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.57 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.57 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.08 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.08 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 7.08 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.62 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.62 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.62 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.20 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.20 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 6.20 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.80 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.80 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.80 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.42 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.42 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.42 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 5.07 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 4.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [--------------------------------------------->] 100.00% 4.75 MiB p/s ETA 0s130.09 MiB / 130.09 MiB [-------------------------------------------------] 100.00% 6.49 MiB p/s 20s2026-10-27T21:31:30Z INFO [vulndb] Artifact successfully downloaded repo="mirror.gcr.io/aquasec/trivy-db:2" 2026-10-27T21:31:30Z INFO [vuln] Vulnerability scanning is enabled 2026-10-27T21:31:30Z INFO [misconfig] Misconfiguration scanning is enabled 2026-10-27T21:31:30Z INFO [checks-client] Need to update the checks bundle 2026-10-27T21:31:30Z INFO [checks-client] Downloading the checks bundle... 234.57 KiB / 234.57 KiB [------------------------------------------------------] 100.00% ? p/s 100ms2026-10-27T21:31:32Z WARN [rego] Module will be skipped as current version of Trivy is older than minimum trivy version required - please update Trivy to use this module file_path="root/.cache/trivy/policy/content/policies/cloud/policies/aws/cloudfront/enable_logging.rego" minimum_trivy_version="0.72.0" 2026-10-27T21:31:33Z ERROR [dockerfile scanner] Failed to parse file file_path="docker/server/Dockerfile.dockerignore" err="parse dockerfile instruction: parse instruction \".git\": unknown instruction: .git" 2026-10-27T21:31:33Z INFO Number of language-specific files num=0 2026-10-27T21:31:33Z INFO Detected config files num=9 Report Summary ┌──────────────────────────────┬────────────┬─────────────────┬───────────────────┐ │ Target │ Type │ Vulnerabilities │ Misconfigurations │ ├──────────────────────────────┼────────────┼─────────────────┼───────────────────┤ │ benchmarks/docker/Dockerfile │ dockerfile │ - │ 2 │ ├──────────────────────────────┼────────────┼─────────────────┼───────────────────┤ │ docker/android.Dockerfile │ dockerfile │ - │ 2 │ ├──────────────────────────────┼────────────┼─────────────────┼───────────────────┤ │ docker/appimage.Dockerfile │ dockerfile │ - │ 5 │ … ``` </details> 🧹 Formatting only (layout, no behaviour; the nightly lint-fix job applies these as a PR): YAML · prettier (57 files checked), BASH · shfmt (11 files checked), JSON · prettier (147 files checked) ✅ Clean: actionlint, git_diff, gitleaks, grype, jsonlint, secretlint, stylelint, trufflehog, xmllint <sub>MegaLinter on soucouyant · full logs in the Actions run · comment <code>/improve</code> for AI fix suggestions</sub>
Jiggle body: Vitruvian's own skeleton and skin weights instead of a guessed rig
Some checks failed
CI / dependencies (pull_request) Successful in 7s
CI / std-includes (pull_request) Successful in 17s
CI / shipping-build (pull_request) Failing after 5m44s
Benchmarks / benchmarks (pull_request) Failing after 11m24s
CI / release-build (pull_request) Failing after 5m55s
Docs site / site (pull_request) Successful in 22s
CI / build-test-and-coverage (pull_request) Failing after 9m14s
lint / megalinter (pull_request) Successful in 3m9s
CI / android (pull_request) Failing after 8m32s
Windows (native) / build (pull_request) Failing after 15m36s
Windows (native) / test (pull_request) Has been skipped
Windows (native) / publish (pull_request) Has been skipped
f443ce0573
Kees: the limbs bend horribly. autoRigHumanoid guessed the skin weights from the
nearest bone; Vitruvian ships the artists' own (weights/mixamo.npz, a 52-bone
Mixamo skeleton, joints/Mixamo.npz), CC0 like the rest.

- tools/vitruvian/build_body.py builds the armature from the joint definitions on
  the *morphed* body, applies the weights, and exports a skinned .glb (3 MB).
- The bandeau and shorts are cloth shells 4 mm over the skin, cut by clipping
  triangles at level planes and at the 0.5 line of a smooth weight field (the file's
  own "censor" mask had a ragged, torn edge), with interpolated skin weights.
- canonicalBoneName() knows Mixamo's own names (LeftArm, LeftForeArm, LeftUpLeg,
  Spine1, LeftHandIndex1...) for names carrying "mixamorig": before, only Hips
  matched and 3 of 57 bones took the UAL clips; now 52 do. No other rig is touched.
- The demo keeps a body's own skeleton and skips reshaping for it; a file with no
  skeleton is still auto-rigged.
- Tests: Mixamo names pair with UAL's; the shipped body is skinned, every vertex's
  weights add up to 1, 50+ bones take the clips, the soft-tissue bones are found.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Some checks failed
CI / dependencies (pull_request) Successful in 7s
CI / std-includes (pull_request) Successful in 17s
CI / shipping-build (pull_request) Failing after 5m44s
Benchmarks / benchmarks (pull_request) Failing after 11m24s
CI / release-build (pull_request) Failing after 5m55s
Docs site / site (pull_request) Successful in 22s
CI / build-test-and-coverage (pull_request) Failing after 9m14s
lint / megalinter (pull_request) Successful in 3m9s
CI / android (pull_request) Failing after 8m32s
Windows (native) / build (pull_request) Failing after 15m36s
Windows (native) / test (pull_request) Has been skipped
Windows (native) / publish (pull_request) Has been skipped
This pull request is marked as a work in progress.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin +refs/pull/138/head:khyretos/claude/jiggle-vitruvian
git switch khyretos/claude/jiggle-vitruvian

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch claude/creator-polish-base
git merge --no-ff khyretos/claude/jiggle-vitruvian
git switch khyretos/claude/jiggle-vitruvian
git rebase claude/creator-polish-base
git switch claude/creator-polish-base
git merge --ff-only khyretos/claude/jiggle-vitruvian
git switch khyretos/claude/jiggle-vitruvian
git rebase claude/creator-polish-base
git switch claude/creator-polish-base
git merge --no-ff khyretos/claude/jiggle-vitruvian
git switch claude/creator-polish-base
git merge --squash khyretos/claude/jiggle-vitruvian
git switch claude/creator-polish-base
git merge --ff-only khyretos/claude/jiggle-vitruvian
git switch claude/creator-polish-base
git merge khyretos/claude/jiggle-vitruvian
git push origin claude/creator-polish-base
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
khyretos/kk-engine!138
No description provided.