From efba00d005a9fe9a0432e61cf389030b2d3870a5 Mon Sep 17 00:00:00 2001 From: notevil Date: Fri, 24 Apr 2026 11:57:15 +0200 Subject: [PATCH] Bondage test items : placeholder assets for Phase 3 pipeline validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds minimum viable assets to exercise the Phase 3 anim pipeline in-game : - 5 placeholder anim JSON files in assets/tiedup/animmodels/animations/ (identity keyframes matching context_stand_idle template) : armbinder_idle, armbinder_walk, armbinder_struggle, armbinder_equip_oneshot, classic_collar_idle - armbinder.json enriched with 'animations' block binding IDLE + WALK + WALK_BOUND + STRUGGLE_BOUND living_motions + on_equip oneshot - classic_collar.json enriched with IDLE binding for multi-item composition test Purpose : validate end-to-end that the data-driven pipeline fires correctly (rebuild, motion switch, oneshot sound, rehydrate) via F6 debug overlay. Visual pose does not change (identity anims) — body keyframe authoring remains blocked on Blender artist assets. Runtime note : the placeholder JSONs lack the EF 'constructor' block, so readResourcepackAnimation does not register them in AnimationManager.animationByName. resolveWithFallback will return EMPTY_ANIMATION with a dedup WARN per missing ID — this exercises the binding resolution path without needing a real StaticAnimation (the map livingAnimations still receives the accessor, F6 overlay still reports bindings:N). Real registration will land when either InstantiateInvoker.getArmature() is implemented (Phase 2 armature registry) or a dedicated AnimationRegistryEvent handler is added. Gameday verification steps documented in docs/plans/rig/GAMEDAY_CHECKLIST.md (gitignored, local only). --- .../animations/armbinder_equip_oneshot.json | 15 +++++++++++++++ .../animmodels/animations/armbinder_idle.json | 16 ++++++++++++++++ .../animations/armbinder_struggle.json | 14 ++++++++++++++ .../animmodels/animations/armbinder_walk.json | 15 +++++++++++++++ .../animations/classic_collar_idle.json | 14 ++++++++++++++ .../assets/tiedup/tiedup_items/armbinder.json | 9 +++++++++ .../tiedup/tiedup_items/classic_collar.json | 5 +++++ 7 files changed, 88 insertions(+) create mode 100644 src/main/resources/assets/tiedup/animmodels/animations/armbinder_equip_oneshot.json create mode 100644 src/main/resources/assets/tiedup/animmodels/animations/armbinder_idle.json create mode 100644 src/main/resources/assets/tiedup/animmodels/animations/armbinder_struggle.json create mode 100644 src/main/resources/assets/tiedup/animmodels/animations/armbinder_walk.json create mode 100644 src/main/resources/assets/tiedup/animmodels/animations/classic_collar_idle.json diff --git a/src/main/resources/assets/tiedup/animmodels/animations/armbinder_equip_oneshot.json b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_equip_oneshot.json new file mode 100644 index 0000000..023d5e7 --- /dev/null +++ b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_equip_oneshot.json @@ -0,0 +1,15 @@ +{ + "_comment": "PLACEHOLDER gameday — oneshot d'équipement pour armbinder (2 keyframes Root, 0.5s non-repeat). Testera le trigger on_equip via PacketPlayRigAnim.handleOnClient + LivingEntityPatch.playAnimationSync. F6 overlay doit montrer une brève spike d'animation HIGH priority au moment de l'équipement, puis retour au base layer IDLE. Remplacement Blender (bras qui se replient derrière le dos) quand dispo.", + "_comment_registration": "Même statut que les autres placeholders : résolution vers EMPTY_ANIMATION. La spike visuelle via PacketPlayRigAnim testera le binding du oneshot même si l'effet rendu est nul.", + "format": "ATTRIBUTES", + "animation": [ + { + "name": "Root", + "time": [0.0, 0.5], + "transform": [ + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] }, + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] } + ] + } + ] +} diff --git a/src/main/resources/assets/tiedup/animmodels/animations/armbinder_idle.json b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_idle.json new file mode 100644 index 0000000..d2103e1 --- /dev/null +++ b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_idle.json @@ -0,0 +1,16 @@ +{ + "_comment": "PLACEHOLDER gameday — identity idle pour armbinder (2 keyframes Root, 2s loop). Même structure que context_stand_idle.json : le but n'est PAS d'avoir un rendu visuel different mais de valider le pipeline P3-05 end-to-end (binding résolu, anim jouée, F6 overlay 'motion: IDLE, bindings: N'). À remplacer par un export Blender authored (bras derrière le dos, épaules sanglées) quand dispo.", + "_comment_registration": "Ce JSON n'est PAS auto-registered dans AnimationManager.animationByName : readResourcepackAnimation exige un bloc 'constructor' absent ici, et InstantiateInvoker.getArmature() throw actuellement (Armature registry pas Phase 2). resolveWithFallback retourne donc EMPTY_ANIMATION, ce qui est OK pour le smoke test du pipeline (la map livingAnimations reçoit bien un accessor, juste vide).", + "_comment_armature": "Pas de champ 'armature' ici — le loader ne lit pas ce champ au runtime. L'armature est résolue par le call site.", + "format": "ATTRIBUTES", + "animation": [ + { + "name": "Root", + "time": [0.0, 2.0], + "transform": [ + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] }, + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] } + ] + } + ] +} diff --git a/src/main/resources/assets/tiedup/animmodels/animations/armbinder_struggle.json b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_struggle.json new file mode 100644 index 0000000..47d61f5 --- /dev/null +++ b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_struggle.json @@ -0,0 +1,14 @@ +{ + "_comment": "PLACEHOLDER gameday — struggle bondage pour armbinder (2 keyframes Root, 0.8s loop). Testera le binding de la motion custom TiedUpLivingMotions.STRUGGLE_BOUND. Remplacement Blender (gesticulation limitée bras sanglés) quand dispo.", + "format": "ATTRIBUTES", + "animation": [ + { + "name": "Root", + "time": [0.0, 0.8], + "transform": [ + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] }, + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] } + ] + } + ] +} diff --git a/src/main/resources/assets/tiedup/animmodels/animations/armbinder_walk.json b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_walk.json new file mode 100644 index 0000000..76006fb --- /dev/null +++ b/src/main/resources/assets/tiedup/animmodels/animations/armbinder_walk.json @@ -0,0 +1,15 @@ +{ + "_comment": "PLACEHOLDER gameday — identity walk pour armbinder (2 keyframes Root, 1s loop). Le but est de tester le switch de motion IDLE→WALK au runtime : F6 overlay doit afficher 'motion: WALK' quand le joueur bouge. Identité visuelle pour l'instant, remplacement Blender-authored (démarche contrainte, épaules raides) quand dispo.", + "_comment_registration": "Même statut que armbinder_idle.json : pas de bloc 'constructor' => resolveWithFallback retourne EMPTY_ANIMATION. Valide le switch de motion côté binding map sans besoin d'un StaticAnimation réel.", + "format": "ATTRIBUTES", + "animation": [ + { + "name": "Root", + "time": [0.0, 1.0], + "transform": [ + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] }, + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] } + ] + } + ] +} diff --git a/src/main/resources/assets/tiedup/animmodels/animations/classic_collar_idle.json b/src/main/resources/assets/tiedup/animmodels/animations/classic_collar_idle.json new file mode 100644 index 0000000..2ad8d23 --- /dev/null +++ b/src/main/resources/assets/tiedup/animmodels/animations/classic_collar_idle.json @@ -0,0 +1,14 @@ +{ + "_comment": "PLACEHOLDER gameday — identity idle pour classic_collar (NECK region). Apairé avec armbinder_* pour tester le cas multi-item composition : armbinder (ARMS pose_priority 30) + classic_collar (NECK pose_priority 5) doivent tous deux écrire dans la map livingAnimations (pose_priority ASC sort => collar appliqué d'abord, armbinder écrase). F6 overlay doit afficher 'bindings: 2+' quand les deux items sont équipés.", + "format": "ATTRIBUTES", + "animation": [ + { + "name": "Root", + "time": [0.0, 2.0], + "transform": [ + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] }, + { "loc": [0.0, 0.0, 0.0], "rot": [1.0, 0.0, 0.0, 0.0], "sca": [1.0, 1.0, 1.0] } + ] + } + ] +} diff --git a/src/main/resources/assets/tiedup/tiedup_items/armbinder.json b/src/main/resources/assets/tiedup/tiedup_items/armbinder.json index 0766cea..dc8cf71 100644 --- a/src/main/resources/assets/tiedup/tiedup_items/armbinder.json +++ b/src/main/resources/assets/tiedup/tiedup_items/armbinder.json @@ -22,6 +22,15 @@ "leftArm" ] }, + "animations": { + "living_motions": { + "IDLE": "tiedup:armbinder_idle", + "WALK": "tiedup:armbinder_walk", + "WALK_BOUND": "tiedup:armbinder_walk", + "STRUGGLE_BOUND": "tiedup:armbinder_struggle" + }, + "on_equip": "tiedup:armbinder_equip_oneshot" + }, "components": { "lockable": {}, "resistance": { diff --git a/src/main/resources/assets/tiedup/tiedup_items/classic_collar.json b/src/main/resources/assets/tiedup/tiedup_items/classic_collar.json index fcae2eb..4c136ef 100644 --- a/src/main/resources/assets/tiedup/tiedup_items/classic_collar.json +++ b/src/main/resources/assets/tiedup/tiedup_items/classic_collar.json @@ -11,6 +11,11 @@ "body" ] }, + "animations": { + "living_motions": { + "IDLE": "tiedup:classic_collar_idle" + } + }, "display_name": "Classic Collar", "translation_key": "item.tiedup.classic_collar", "model": "tiedup:models/gltf/v2/collars/classic_collar.glb",