Compare commits

6 Commits

Author SHA1 Message Date
ozan d54e6f431d docs: Isleborn -> Ariki rename -- safe .md sweep across all repos
🔗 GHA / 📊 Static checks (push) Failing after 14m28s
🔗 GHA / 🤖 Android (push) Has been skipped
🔗 GHA / 🍏 iOS (push) Has been skipped
🔗 GHA / 🐧 Linux (push) Has been skipped
🔗 GHA / 🍎 macOS (push) Has been skipped
🔗 GHA / 🏁 Windows (push) Has been skipped
🔗 GHA / 🌐 Web (push) Has been skipped
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 06:49:06 +01:00
ozan 0025b8676d repo: update references to ariki-game after rename
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-20 05:04:09 +01:00
ozan 476b32c7aa revert: remove retarget rest fixer patches (no longer needed)
Reverts cfce03a251 and 4e16c3f5bd. Switched to Quaternius character
system (same skeleton as animations) — no retargeting needed.
Keeps engine clean for future work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-19 02:00:00 +01:00
ozan cfce03a251 fix(import): add TINQS diagnostic logging to skeleton rest fixer
WARN_PRINT for each bone's before/after conversion values during
Overwrite Axis reimport. Confirms animation keyframe conversion is
running correctly — arms issue is downstream (animation content or
mesh skinning), not the conversion formula.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 21:19:22 +01:00
ozan a49337a552 docs(wiki): agent knowledge base - retargeting internals, build, S3 pipeline 2026-05-18 20:02:33 +01:00
ozan 4e16c3f5bd fix(import): skeleton rest fixer animation conversion in headless mode
The %GeneralSkeleton unique node resolution via get_node() fails during
headless import (--import flag), causing ALL animation tracks to be
silently skipped by ERR_CONTINUE. Rest poses get overwritten but animation
keyframe values stay in the old coordinate system, producing incorrect
bone orientations (e.g., arms crossed behind back).

Fix: fall back to find_child() when unique name resolution fails.
Added extensive logging for retarget debugging.

Tinqs fork v1.0.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-18 20:01:15 +01:00
4 changed files with 174 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
# Godot Fork Wiki
Tinqs custom Godot engine — agent knowledge base.
## Pages
- **[retargeting.md](retargeting.md)** — Import-time retargeting internals, rest fixer bug, bone mapping
- **[build.md](build.md)** — How to build the engine from source
- **[s3-pipeline.md](s3-pipeline.md)** — Publish to S3, fetch from ariki-game
## Quick Facts
- **Upstream:** Godot 4.6.2-stable
- **Commit:** `001aa128b1`
- **Branch:** `tinqs/main`
- **Binary:** `bin/godot.windows.editor.x86_64.mono.console.exe`
- **S3:** `s3://tinqs-cli-releases/godot/`
+36
View File
@@ -0,0 +1,36 @@
# Building the Godot Fork
## Prerequisites
- Windows 11 with Visual Studio 2022 (Build Tools)
- Python 3.10+
- SCons: `pip install scons`
- .NET SDK 8.0 (for mono build)
- Git
## Build Command
From `C:\Users\ozanb\tinqs-ltd\godot`:
```powershell
python -m SCons platform=windows target=editor module_mono_enabled=yes -j32
```
Output goes to `bin/godot.windows.editor.x86_64.mono.console.exe` and `bin/godot.windows.editor.x86_64.mono.exe`.
**Build time:** ~8 minutes on Forge (32 cores).
## Custom Modules
Our fork adds agentic engine modules (branch `tinqs-agent-modules`):
- `agent_api` — REST/WS server on ports 4328/4329
- `agent_log`, `agent_events`, `agent_console`, `agent_replay`
- `agent_vision`, `agent_fbx`, `agent_auth`, `agent_analytics`
For the base editor build (tinqs/main), no extra module flags needed.
## Version
- Current: `001aa128b1` (4.6.2-stable)
- Branch: `tinqs/main`
- Custom build identifier: `custom_build.001aa128b`
+88
View File
@@ -0,0 +1,88 @@
# Import-Time Retargeting Internals
How Godot's FBX/GLTF importer handles retargeting and where the gaps are.
## Pipeline
1. FBX → GLTF (via ufbx, built-in in 4.6+)
2. GLTF → Godot scene (with import-time retargeting if configured)
3. Rest fixer post-processes skeleton + animations
## How it's configured
Via `.import` file `_subresources` section:
```
_subresources={
"nodes": {
"PATH:Skeleton3D": {
"retarget/bone_map": Object(BoneMap,...),
"retarget/bone_renamer/rename_bones": true,
"retarget/bone_renamer/unique_node/skeleton_name": "GeneralSkeleton",
"retarget/rest_fixer/retarget_method": 1, // 0=None, 1=Overwrite Axis
...
}}}
```
Never hand-craft `_subresources` strings. Always use `ConfigFile.set_value()` with `BoneMap` and `SkeletonProfileHumanoid` objects.
## Rest Fixer Methods
| Method | Value | Behavior |
|--------|-------|----------|
| None | 0 | No rest fix |
| Overwrite Axis | 1 | Adjusts skeleton rest to Humanoid reference |
## Known Bug: Skeleton Node Resolution Fails During Import
**Severity:** Blocking for cross-skeleton animation sharing
**Source file:** `editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp`
**What's supposed to happen:** The rest fixer (lines 711-825) converts animation keyframes to the new rest pose using:
```cpp
// Rotation (line 799):
anim->track_set_key_value(i, j,
new_pg_q.inverse() * old_pg_q * qt * old_rest_q.inverse()
* old_pg_q.inverse() * new_pg_q * new_rest_q);
// Scale (line 810): similar matrix-based
// Position (line 819): new_pg_b.xform_inv(old_pg_b.xform(ps - old_rest_o)) + new_rest_o
```
**What actually happens:** Before the conversion, the code needs to find the Skeleton3D node from the animation track path (lines 732-754). The track path uses `%GeneralSkeleton:bone_name` format. When `get_node` fails (common in headless `--import`), a `[TINQS]` fallback using `find_child()` was added. If even the fallback fails, line 749 prints a warning and SKIPS the conversion:
```cpp
WARN_PRINT(vformat("[RetargetRestFixer] Failed to resolve skeleton node '%s' "
"— animation keyframes will NOT be converted to new rest pose. "
"This may cause incorrect bone orientations.", track_path));
```
**Root cause:** The `%UniqueNode` resolution doesn't work reliably in headless import context. The `find_child` fallback searches `p_base_scene` but may not find the skeleton if it's nested with a different name from what the track path expects.
**Fix needed:** The `[TINQS]` fallback (lines 734-754) needs to be more robust. Either:
1. Match skeleton by name + type (find any `Skeleton3D` child regardless of exact path)
2. Pre-resolve all skeleton paths before the animation loop
3. Use the bone map to directly identify which skeleton owns each bone
**Related commits:**
- `f3af3aedfe` — Original rest fixer (includes keyframe conversion)
- `[TINQS]` patch — Headless fallback (lines 734-754 in current source)
## Related Upstream PRs (all merged, in our fork)
| PR | Commit | What | Does it fix this? |
|----|--------|------|-------------------|
| #106537 | `3925ca0571` | GLTF: bone names unique per-skeleton | No (bone naming only) |
| #104184 | `3cc71ef8b9` | GLTF: don't collapse non-joint leaf nodes | No (structural) |
| #62939 | `f3af3aedfe` | Add rest fixer to importer retarget | Contains the conversion code — but node resolution fails |
## Our Fork Info
- Upstream: Godot 4.6.2-stable
- Fork: `tinqs-ltd/godot` on Git Studio
- Branch: `tinqs/main`
- Commit: `001aa128b1`
- Binary: `bin/godot.windows.editor.x86_64.mono.console.exe`
- Build: `python -m SCons` with mono + custom module flags
- S3: `s3://tinqs-cli-releases/godot/v1.0.0/`
+33
View File
@@ -0,0 +1,33 @@
# S3 Pipeline
How the Godot binary is published and consumed.
## Publishing (from godot repo)
```powershell
.\tools\publish.ps1
```
Zips `bin/` contents and uploads to `s3://tinqs-cli-releases/godot/v1.0.0/`.
## Fetching (from ariki-game)
The ariki-game repo uses `.engine-version` to pin which Godot version to use:
```powershell
.\tools\fetch-engine.ps1
```
Downloads the version matching `.engine-version` from S3 to `%TEMP%\tinqs-godot-v<version>\`.
Alternative via `engine.ps1`:
```powershell
.\tools\engine.ps1 fetch # download matching version
.\tools\engine.ps1 publish # upload current build
```
## URL Pattern
```
s3://tinqs-cli-releases/godot/v{VERSION}/godot.windows.editor.x86_64.mono.console.exe
```