Commit Graph

151 Commits

Author SHA1 Message Date
notevil
d3a3b400aa Audit-9 : strip Vec2i + exceptions + HitEntityList + MovementAnimation, document datapack-surface keeps
Deletes (5 files, 132 lines) :
- rig/anim/types/MovementAnimation.java (zero callers outside self-decl)
- rig/exception/DatapackException.java (dead)
- rig/exception/ShaderParsingException.java (dead)
- rig/math/Vec2i.java (dead)
- rig/util/HitEntityList.java (only consumer was HIT_PRIORITY, retiré)

Modifs :
- rig/anim/property/AnimationProperty.java : retire la constante
  AttackPhaseProperty<Priority> HIT_PRIORITY et l'import HitEntityList.Priority.

Docs (3 Javadocs retenues pour surface datapack / Phase 3) :
- CapabilityItem : précise l'usage Phase 3 (data-driven item anims,
  ON_ITEM_CHANGE_EVENT + HumanoidMobPatch.modifyLivingMotionByCurrentItem).
- AnimationProperty.ON_ITEM_CHANGE_EVENT : documenté comme hook datapack
  pour réagir au changement d'item porté.
- MoveCoordFunctions : doc class-level clarifie que les 8 constantes
  MoveCoord* sont consommées par réflection (StaticFieldArgument) côté
  datapack EF tiers — ne pas purger individuellement.

Compile GREEN, 20/20 rig tests GREEN.
2026-04-23 06:02:36 +02:00
notevil
687b810a0e Audit-8 : strip anim core dead methods (-222 LOC)
TransformSheet (-53 LOC, 4 methods): getStartTransform,
getInterpolatedRotation, getCorrectedModelCoord, extendsZCoord.
Skipped: extend (live internal caller in transformToWorldCoordOriginAsDest),
getInterpolationInfo (live internal callers in getInterpolatedTranslation /
getInterpolatedTransform).

ClientAnimator (-44 LOC, 6 methods): getAllLayers, iterVisibleLayers,
isAiming, getOwner, getJumpAnimation, getPriorityFor. Also removed now-unused
java.util.Collection import. Skipped: getCompositeLivingMotion (live callers
in tick/forceResetBeforeAction/resetCompositeMotion), applyBindModifier (live
internal callers in getPose/getComposedLayerPoseBelow/recursion), compareMotion
(live caller in tick), compareCompositeMotion (live caller in tick), iterAllLayers
(live callers in setSoftPause/renderDebuggingInfoForAllLayers), getLivingMotion
(live internal callers in tick/forceResetBeforeAction).

StaticAnimation (-125 LOC, 17 methods): getFileHash instance, idBetween,
in(StaticAnimation[]), in(AnimationAccessor[]), setResourceLocation,
invalidate, isInvalid, removeProperty, addEvents (both overloads),
newTimePair, newConditionalTimePair, addState, removeState,
addConditionalState, addStateRemoveOld, addStateIfNotExist. Also removed
now-unused imports (Collection, Function, Stream).
Skipped @Override/contract methods: getState, getStatesMap, modifyPose,
doesHeadRotFollowEntityHead, getId, equals, getRegistryName, getCoord,
getAccessor (all @Override DynamicAnimation/Object — removing breaks
polymorphism contract). Skipped methods with live callers: getFileHash static
(called in ctor line 116), addProperty (15+ external callers in registry and
AnimationSubFileReader), getModifiedLinkState (3 callers in LinkAnimation),
getSubAnimations (callers in AnimationManager and 5 internal self-calls),
setAccessor (called by AnimationManager.apply line 352), loadAnimation
(called by kept getAnimationClip), createSimulationData (implements
InverseKinematicsProvider interface contract — hot-path risk skip).

20/20 rig tests GREEN.
2026-04-23 05:53:01 +02:00
notevil
06ec7c7c5f Audit-7 : strip ParseUtil + TiedUpRenderTypes dead utilities (-682 LOC)
ParseUtil.java (-232 LOC) :
  Removed 18 zero-caller helpers inherited from Epic Fight :
  toAttributeModifier, nullOrToString, nullOrApply, nvl,
  snakeToSpacedCamel, compareNullables, nullParam, getRegistryName,
  getOrSupply, isParsableAllowingMinus, isParsable, valueOfOmittingType,
  parseOrGet, mapEntryToPair, remove, convertToJsonObject,
  parseCharacterToNumber, parseTagOrThrow.
  Kept toVector3f/toVector3d (unused but reserved for forked callers
  type TrailInfo), toLowerCase, toUpperCase, getBytesSHA256Hash,
  enumValueOfOrNull, orElse, getOrDefaultTag, and the array helpers
  actually wired into JsonAssetLoader / SkinnedMesh / StaticMesh.
  Pruned imports : AttributeModifier, IForgeRegistry, TagParser, Pair,
  JsonOps, ByteTag, CommandSyntaxException, Collectors, Nullable, UUID,
  Function, ArrayList, Collection, Set, Map.

TiedUpRenderTypes.java (-450 LOC) :
  Removed 16 zero-caller render types :
  entityUIColor, entityUITexture, debugCollider, guiTriangle,
  entityAfterimageStencil/Translucent/White, itemAfterimageStencil/
  Translucent/White, blockHighlight, coloredGlintWorldRendertype
  (both overloads), freeUnusedWorldRenderTypes, clearWorldRenderTypes,
  addRenderType(String,ResourceLocation,RenderType), makeTriangulated.
  Also dropped the private fields feeding them : ENTITY_UI_COLORED,
  ENTITY_UI_TEXTURE, OBB, GUI_TRIANGLE, ENTITY_AFTERIMAGE_WHITE,
  ITEM_AFTERIMAGE_WHITE, ENTITY_PARTICLE, ITEM_PARTICLE,
  ENTITY_PARTICLE_STENCIL, ITEM_PARTICLE_STENCIL, BLOCK_HIGHLIGHT,
  WORLD_RENDERTYPES_COLORED_GLINT, plus the newly orphaned
  PARTICLE_SHADER / ShaderColorStateShard / MutableCompositeState
  (only ever used by coloredGlint).
  Kept getTriangulated + replaceTexture (SkinnedMesh / MeshPart / Mesh),
  plus their backing TRIANGULATED_OUTLINE / TRIANGULATED_RENDER_TYPES /
  TRIANGLED_RENDERTYPES_BY_NAME_TEXTURE infra.

debugQuads : DELETED. Only StaticAnimation.renderDebugging /
DynamicAnimation.renderDebugging reference the debug path, and both
were already stripped to empty stubs in Phase 2 ('RIG : debug render
des targets IK strippé. Pas d'IK en TiedUp').

overlayModel : DELETED. PatchedLivingEntityRenderer.getOverlayCoord
explicitly comments out the modifyOverlay path ('RIG Phase 2.5 :
EntityDecorations.modifyOverlay strippé — utilise les defaults
vanilla'), so OVERLAY_MODEL has no reachable caller.

Compile GREEN. 20/20 rig tests GREEN.
2026-04-23 05:38:00 +02:00
notevil
8530671a49 Audit-6 : strip dead math utilities (-300 LOC)
Confirmed-dead method cleanup in rig/math/ following AUDIT_2026-04-22
essentiality cross-check. All removals verified via grep across src/
showing zero live callers.

- MathUtils.java (-242 LOC) : bezierCurve (both overloads), rotWrap,
  lerpDegree, greatest/least (all 6 numeric overloads), translateStack,
  rotateStack, scaleStack (+ their OPEN_MATRIX_BUFFER field),
  lerpMojangVector, setQuaternion, mulQuaternion, getLeastAngleVector
  (idx variant kept, used by ClothSimulator), packColor, unpackColor,
  normalIntValue, wrapClamp, worldToScreenCoord. Unused imports
  (Vector4i, Vector4f, Axis, Camera, Vec2) stripped.

- OpenMatrix4f.java (-56 LOC net) : 3-arg add, mulAsOrigin, createScale,
  ofScale. mulAsOriginInverse (task-KEEP) inlined to no longer depend
  on mulAsOrigin.

- Vec3f.java (-2 LOC net) : toMojangVector, fromMojangVector.

ValueModifier.java NOT deleted despite task instruction : grep found
live references in rig/anim/property/AnimationProperty.java
(4 AttackPhaseProperty constants + import). Task explicitly says
"STOP and report" in this case. The 4 constants have no downstream
readers and could be purged in a follow-up, but that is outside this
task's scope.

20/20 rig tests GREEN (--rerun-tasks verified), ./gradlew compileJava
GREEN after each file group.
2026-04-23 05:26:34 +02:00
notevil
03c28e3332 Audit-3 : align H-04/H-05 signatures vs EF upstream
Deux signatures avaient dérivé du fork EF pendant Phase 0. Les réaligner
maintenant évite du frottement quand on re-porte des fixes EF upstream.

H-04 — ActionAnimation.correctRootJoint
  Avant : correctRootJoint(LinkAnimation linkAnimation, ...)
  Après : correctRootJoint(DynamicAnimation animation, ...)
  LinkAnimation extends DynamicAnimation → widening safe, le call-site
  dans LinkAnimation.modifyPose (ligne 118) passe toujours `this` qui
  type-matche DynamicAnimation sans édition.

H-05 — AttackAnimation.phases
  Avant : public final List<Phase> phases = Collections.emptyList();
  Après : public final Phase[] phases = new Phase[0];
  Le seul caller (JsonAssetLoader.java:477) est un for-each, donc
  array-compatible sans édition. Aucun .size()/.get()/.stream() nulle
  part. Imports java.util.{List,Collections} retirés.

Compile GREEN. 20/20 tests rig GREEN.
2026-04-23 05:03:35 +02:00
notevil
4152f9fc71 Audit-2 : strip EF extension chain + AnimationConfig dead fields (-334 LOC)
H-02 (EF extension chain DEAD) :
- Delete 5 unreferenced EF-derived files :
  - event/EntityPatchRegistryEvent (ModLoader event for third-party patch
    registration — no third-party EF mods to host).
  - event/RegisterResourceLayersEvent (extra renderer layers registration
    event — no consumers).
  - render/layer/LayerUtil (+ empty package) — sole LayerProvider interface
    only used by the deleted RegisterResourceLayersEvent.
  - render/item/RenderItemBase (+ empty package) — abstract weapon renderer
    stub, TiedUp does not host weapon trails.
  - asset/SelfAccessor — AssetAccessor variant never created.
- PatchedRenderersEvent : drop inner classes RegisterItemRenderer (tied to
  RenderItemBase) and Modify (never posted). Keep Add, used by
  TiedUpRenderEngine.
- JsonAssetLoader : remove loadArmature(ArmatureContructor) + its private
  getJoint helper. Armatures are loaded via the GLB path in Phase 1 — this
  EF JSON route has no callers.
- TiedUpRigRegistry : drop inner interface ArmatureContructor (EF-style
  typo preserved) now that loadArmature is gone.
- EntityPatchProvider : drop CUSTOM_CAPABILITIES map + putCustomEntityPatch
  + clearCustom. No third-party extension surface needed ; inline the
  provider lookup to CAPABILITIES only.

H-03 (TiedUpAnimationConfig dead fields) :
- Remove enableOriginalModel, enableAnimatedFirstPersonModel,
  enableCosmetics, enablePovAction, autoSwitchCamera, preferenceWork,
  combatPreferredItems, miningPreferredItems. None had callers — they were
  inherited from EF ClientConfig without a TiedUp consumer.
- Keep activateComputeShader — read at SkinnedMesh.java:249 to toggle the
  GPU skinning path.

Compile green, 20/20 rig tests still green.
2026-04-23 04:55:07 +02:00
notevil
647894508d Audit-1 review : fix stale '6 ticks' comment + track NONE_MASK null
Reviewer flagged two MEDIUM cosmetic items :
- SMELL-001 : TiedUpAnimationRegistry:97 comment still said '6 ticks' —
  updated to '0.15s = 3 ticks' to match the new constant.
- SMELL-002 : JointMaskReloadListener.getNoneMask() can still return
  null if a resource pack omits tiedup:none. Call sites tolerate null
  today; logged in PHASE0_DEGRADATIONS for a Phase 3 fallback JSON +
  warn log.
2026-04-23 04:46:22 +02:00
notevil
f4aae9adb7 Audit-1 : fix transition time + JointMaskReloadListener
C-01 : GENERAL_ANIMATION_TRANSITION_TIME was int 6 while all consumers
expect a float transitionTime in seconds — 6s gave inter-animation
transitions of 120 ticks. Change to float 0.15F (3 ticks).

C-02 : JointMaskReloadListener was never registered, leaving
AnimationSubFileReader callers at lines 170/182/184 to receive null
from getNoneMask()/getJointMaskEntry() with no data loaded. Register
it in V2ClientSetup at LOW priority so it fires after the GLB cache
clear and alongside the other bondage client reload listeners.

M-03 : ASSETS_NEEDED.md JSON example already corrected in the earlier
doc-keeper pass (Torso=7, Chest=8, etc.).

Drive-by: add logs/ to .gitignore — the runClient logs were
accidentally tracked.
2026-04-23 04:41:48 +02:00
notevil
f80dc68c0b Phase 2.8 review fixes : strip player fallback + backlog V3-REW-12-14 + QA edge cases
- BondageAnimationManager : strip total du path joueur, tous les call sites
  'player' retournent null/false avec WARN once-per-UUID. getOrCreateLayer
  court-circuite sur Player direct. Retire dead code factory/furniture
  (FACTORY_ID, FURNITURE_*, npcFurnitureLayers, getPlayerLayer, etc.).
  Javadoc init() reflete la semantique NPC-only.
- DogPoseHelper.applyHeadCompensationClamped : @Deprecated(since=2.8)
  pointant vers V3-REW-07 (dead apres retrait MixinPlayerModel).
- DogPoseRenderHandler.getAppliedRotationDelta + isDogPoseMoving :
  @Deprecated(since=2.8) meme raison.
- Docs (gitignored) : V3_REWORK_BACKLOG.md ajoute V3-REW-12/13/14 (pet bed
  body-lock, human chair yaw clamp, context layer sit/kneel/sneak), tableau
  recap 14 -> 17 items. PHASE2_QA.md ajoute sec 2.5 edge cases + corrige
  le grep pattern 4 -> >=4 lignes. PHASE0_DEGRADATIONS.md ajoute la section
  Phase 2.8 findings.

Compile GREEN. 20/20 tests rig GREEN. Net LOC src : -239 (strip dead code
+ guards player).

Call sites player no-op (attendu par design) :
- PacketSyncPetBedState.playAnimation -> V3-REW-12
- PacketPlayTestAnimation.playAnimation (debug) -> V3-REW-14
- FurnitureClientAnimator.playFurniture -> furniture seat rework V3
2026-04-23 01:10:02 +02:00
notevil
5a39fb0c1c Phase 2.8 : V2 player rendering cleanup + QA checklist doc
Cut wholesale du pipeline V2 player-anim suite au bascule RIG (pas d'opt-in,
pas de rollback — accepté par le mainteneur).

- rm MixinPlayerModel : le renderer RIG patched ne passe plus par
  PlayerModel.setupAnim, donc l'injection @TAIL devenait dead code.
  Les features dog pose head compensation seront ré-exprimées en
  StaticAnimation pose_dog.json (V3-REW-07).
- Strip tiedup.mixins.json : retiré client/MixinPlayerModel, restent
  MixinCamera + MixinLivingEntitySleeping.
- BondageAnimationManager.init() : retiré les 3 PlayerAnimationFactory
  registrations (context / item / furniture), le path joueur n'en
  dépend plus. Factory IDs conservés car les getPlayerLayer*() sont
  tolérantes au null retour via try/catch existants — et restent
  utilisées par le cache fallback remote. Les NPCs continuent
  d'utiliser cette classe via l'accès direct animation stack
  (IAnimatedPlayer.getAnimationStack().addAnimLayer), inchangé.
- TiedUpMod.onClientSetup : suppression de l'appel BondageAnimationManager.init()
  (la méthode est maintenant un log no-op, conservée pour la signature
  publique + doc du changement).
- AnimationTickHandler.onClientTick : retrait de la boucle
  mc.level.players() + updatePlayerAnimation + tickFurnitureSafety +
  cold-cache furniture retry. Les joueurs sont ticked par
  RigAnimationTickHandler (Phase 2.7). Conservé : le cleanup
  périodique ClothesClientCache (hygiène mémoire indépendante), le
  hook onPlayerLogout (cleanup per-UUID des caches NPC restants), et
  le hook onWorldUnload (caches V2 encore utilisés par NpcAnimationTickHandler).
  Imports unused strippés.
- DogPoseHelper : mis à jour la javadoc pour refléter le retrait
  du path player (NPCs only désormais).

Compile GREEN. 20/20 tests rig GREEN.

QA runtime : cf. docs/plans/rig/PHASE2_QA.md (non commit — fichier
working doc sous docs/plans/ gitignored par convention repo).

Net LOC : -276.
2026-04-23 00:42:10 +02:00
notevil
b494b60d60 Phase 2.7 review fixes : resetLoggedErrors wiring + IDLE self-heal + JSON cleanup + tests 2026-04-23 00:27:26 +02:00
notevil
08808dbcc1 Phase 2.7 : animation registry + tick handler + placeholder assets
TiedUpAnimationRegistry.CONTEXT_STAND_IDLE instancié au FMLCommonSetupEvent
via DirectStaticAnimation + armature BIPED. Placeholder JSON 2-keyframes
identity (joueur statique) à assets/tiedup/animmodels/animations/ jusqu'à
ce qu'un export Blender authored remplace. biped.json de même (hiérarchie
identity) placé dans assets/tiedup/armatures/ — parse via JsonAssetLoader
mais pas encore chargé au runtime (l'armature reste procédurale côté Java).

RigAnimationTickHandler tick chaque player visible côté client (phase END) :
- patch.getAnimator().tick() → avance les layers EF
- trigger playAnimation(CONTEXT_STAND_IDLE, 0.2f) quand motion=IDLE et anim
  courante ≠ CONTEXT_STAND_IDLE (idempotent)
- try/catch per-entity avec dedup des erreurs par UUID (pattern
  TiedUpRenderEngine.loggedRenderErrors)
- skip si level null / paused

PlayerPatch.initAnimator bind désormais IDLE → CONTEXT_STAND_IDLE quand le
registry est prêt (fallback EMPTY_ANIMATION si patch construit avant setup).

Voir docs/plans/rig/ASSETS_NEEDED.md pour la spec des assets authored
définitifs (anim idle swing respiration 3 keyframes + offsets biped
anatomiques).
2026-04-23 00:07:32 +02:00
notevil
73264db3c6 Phase 2.6 review fixes : level guard + thread-safety + priority revert + V3-REW-11 track
RISK-001 : early-return si entity.level() == null dans onRenderLiving
  (NPE guard sur detach race despawn / dim teleport). Aligne sur EF.

RISK-004 : clear loggedRenderErrors en tête de onAddLayers() — reset
  du set anti-spam sur reload resources (F3+T), borne aussi la taille
  en session longue.

RISK-005 : remplace HashSet par ConcurrentHashMap.newKeySet() pour
  loggedRenderErrors — render thread + loader thread + test runner
  muteront le set.

RISK-002 : retire priority = EventPriority.HIGH sur onRenderLiving,
  revert au défaut NORMAL aligné EF upstream. Aucun cas concret ne
  justifie HIGH aujourd'hui ; on réévaluera si conflit d'interception
  apparaît Phase 3+. Import EventPriority supprimé.

RISK-003 : tracké V3-REW-11 dans V3_REWORK_BACKLOG.md (inventory GUI
  special-case EF pas porté — rotation/scale/pose preview inventaire).

Docs locaux (gitignored) mis à jour :
  - PHASE0_DEGRADATIONS.md : nouvelle section Phase 2.6 findings
  - V3_REWORK_BACKLOG.md : V3-REW-11 ajouté section MAJEURE

Tests : compileJava GREEN, 18/18 rig tests GREEN.
2026-04-22 23:41:07 +02:00
notevil
987efde86b Phase 2.6 : TiedUpRenderEngine dispatch (RenderLivingEvent hook)
Câble le dispatch renderer RIG via deux subscribers auto-registered (split
MOD bus pour AddLayers, FORGE bus pour RenderLivingEvent.Pre) — pas besoin
de wiring explicite dans TiedUpMod.

onAddLayers (MOD bus) : construit la map entityRendererProvider avec
EntityType.PLAYER → TiedUpPlayerRenderer (Phase 2) ; poste
PatchedRenderersEvent.Add pour extensions tierces.

onRenderLiving (FORGE bus, priority HIGH) : filtre strict instanceof
Player || AbstractTiedUpNpc (protège MCA villagers cf. V3-REW-10) ;
vérifie patch.overrideRender() ; dispatche vers PatchedEntityRenderer et
cancel l'event. Try/catch robuste : log WARN une seule fois par UUID sur
exception, fallback vanilla (event non-canceled).

3 tests unitaires (pure-logic, sans MC runtime) : null-safety du filtre
et idempotence du reset. Le dispatch complet sera validé Phase 2.8
runClient smoke test.

Le biped armature étant identity (Phase 2.4 stub), le hook rendra le
player effondré à l'origine dès qu'il s'active — attendu, warn déjà en
place depuis Phase 2.5.
2026-04-22 23:28:45 +02:00
notevil
d129983eb7 Phase 2.5 review fixes : P0 biped warn + CME guard + double-draw prevention
P0-BUG-001 : LOGGER.warn dans TiedUpArmatures.Holder static init quand les
joints biped sont en identity (Phase 2.4 stub). Sans ça, Phase 2.6 renderer
afficherait un mesh effondré sans signal dev. Warn apparaît une seule fois
(class-init lock JVM).

P0-BUG-002 : Lists.newArrayList(renderer.layers) copie défensive dans
PatchedLivingEntityRenderer.renderLayer. Mods tiers (Wildfire, SkinLayers3D,
Cosmetic Armor) peuvent muter renderer.layers runtime via AddLayers event
-> CME garantie sans copie. TiedUp va au-dela d'EF upstream.

P1-RISK-001 : Pose.orElseEmpty(name) utilise Map.getOrDefault qui retourne
un JointTransform.empty() detache non stocke dans la map -> toute mutation
.frontResult est perdue si le joint est absent. En pratique l'Animator peuple
toujours Head via getComposedLayerPose, mais defensif : on recupere l'instance,
mute, puis pose.putJointData(Head, mutatedTransform). Meme bug latent en EF
upstream.

P1-RISK-003 : PlayerItemInHandLayer extends ItemInHandLayer mais le dispatch
patchedLayers.containsKey(layer.getClass()) est strict -> layer player-specifique
passe au travers. Ajout du mapping explicite dans TiedUpPlayerRenderer
constructor avec le meme stub PatchedItemInHandLayer. Preventif Phase 3.

P2-RISK-004 : @SuppressWarnings scope resserre des 2 methodes aux 2 call sites
dispatch raw PatchedLayer qui en ont reellement besoin. Commentaire pointant
vers l'invariant runtime addPatchedLayer.

Tests : 15/15 rig tests GREEN, compile GREEN.
Doc : docs/plans/rig/PHASE0_DEGRADATIONS.md section Phase 2.5 findings ajoutee
(fichier gitignore, changements locaux pour future session).
2026-04-22 23:16:35 +02:00
notevil
8dff4c0e03 WIP Phase 2.5 : fork render pipeline (PatchedEntityRenderer family)
Fork EF client renderer patched/entity/ → rig/render/, imports rewrités.

Nouveaux fichiers :
 - render/PatchedEntityRenderer.java   (~96 LOC, était stub 16 LOC)  — base abstraite,
   mulPoseStack + setArmaturePose + nameplate via mixin invoker
 - render/PatchedLivingEntityRenderer.java  (~230 LOC, EF 294 → stripped)  — hot path
   render, strippé du JSON customLayers loading + EntityDecorations (pas impl. côté
   LivingEntityPatch TiedUp)
 - render/PHumanoidRenderer.java       (~95 LOC, EF 53 → adapté)  — intermediate
   biped, baby head scale, enregistre PatchedArmorLayer + PatchedItemInHandLayer
 - render/TiedUpPlayerRenderer.java    (~95 LOC, EF PPlayerRenderer 60 → adapté)  —
   dispatch slim/default (Meshes.ALEX vs BIPED), propage modelParts visible flags,
   skip cape/bee/arrow layers (V3-REW-08/09)
 - render/PatchedLayer.java            (~55 LOC)  — base no-op layer
 - render/PatchedArmorLayer.java       (~45 LOC)  — stub no-op (V3-REW-04)
 - render/PatchedItemInHandLayer.java  (~45 LOC)  — stub no-op (Phase 3)
 - mixin/client/MixinEntityRenderer.java       (~35 LOC)  — invoker shouldShowName +
   renderNameTag (EF verbatim)
 - mixin/client/MixinLivingEntityRenderer.java (~30 LOC)  — invoker isBodyVisible,
   getRenderType, getBob

Modifs :
 - resources/tiedup-rig.mixins.json : enregistre les 2 nouveaux mixins client

Dépendances stubbées :
 - PatchedArmorLayer / PatchedItemInHandLayer no-op — "mangent" le layer vanilla
   équivalent pour éviter double-rendu, mais ne dessinent rien. À implémenter
   Phase 3 (armor : V3-REW-04 ; item-in-hand : tool joints GLB).
 - EntityDecorations (color/light/overlay modifiers) strippées du render path —
   le patch TiedUp n'expose pas encore cette API. Hurt/death overlay natifs
   conservés. À rework si feature premium glow/tint NPC.

TODOs Phase 2.6 / Phase 3 :
 - animated_layers/*.json datapack-driven loading (strippé du constructor) si
   besoin futur
 - PlayerItemInHandLayer (version player-spécifique, distincte de ItemInHandLayer
   générique) pas encore mangée côté player → layer vanilla continue de draw
 - ElytraLayer / CustomHeadLayer pas mangés (cohérent "on mange juste les layers
   qui entrent en conflit avec le mesh skinné")

Surprise pendant le fork :
 - ItemInHandLayer vanilla MC 1.20.1 exige M extends EntityModel<E> & ArmedModel,
   pas HeadedModel comme PatchedItemInHandLayer EF 1.20.1 pouvait le suggérer
   via ses anciennes versions. Alignement forcé sur ArmedModel.
 - EF utilise 2 mixins @Invoker (MixinEntityRenderer / MixinLivingEntityRenderer)
   pour accéder aux méthodes protected de vanilla — forkés verbatim dans
   rig/mixin/client/.

Tests :
 - ./gradlew compileJava : BUILD SUCCESSFUL
 - ./gradlew test --tests "com.tiedup.remake.rig.*" : 15/15 GREEN
   (TiedUpArmaturesTest 4 + GlbJointAliasTableTest 4 + GltfToSkinnedMeshTest 6 =
   14 rig + 1 utilitaire)
2026-04-22 22:39:41 +02:00
notevil
39f6177595 Phase 2.4 review fixes : P0-BUG-001 joint order + P0-BUG-002 singleton + tests
P0-BUG-001 — Ordre IDs joints Elbow/Hand/Tool ≠ EF
  TiedUpArmatures.buildBiped() assignait Arm_R=11, Elbow_R=12, Hand_R=13,
  Tool_R=14 (idem gauche 16/17/18/19) alors que VanillaModelTransformer.RIGHT_ARM
  encode upperJoint=11, lowerJoint=12, middleJoint=14 — donc Arm_R=11, Hand_R=12,
  Elbow_R=14. Résultat : lowerJoint=17 (SimpleTransformer qui attache les
  vertices à Hand) pointait en fait vers Elbow_L → bras tordus au rendu.
  Fix : réassigner les IDs dans buildBiped() pour matcher le layout EF
  (Arm_R=11, Hand_R=12, Tool_R=13, Elbow_R=14 ; symétrique 16-19).
  VanillaModelTransformer non touché (source de vérité EF).

P0-BUG-002 — Singleton BIPED non thread-safe
  if (BIPED_INSTANCE == null) BIPED_INSTANCE = buildBiped() est un double-init
  race. En SP intégré (client + server threads sur la même JVM), deux threads
  peuvent entrer simultanément dans le if null et créer deux HumanoidArmature
  distincts — pose matrices incohérentes selon les call sites.
  Fix : Holder idiome (static inner class). Le class-init lock JVM garantit
  (JLS §12.4.1) qu'une seule init, visible à tous les threads, sans
  synchronized ni volatile. Zero overhead après init.

P1 — Nouveau TiedUpArmaturesTest (4 tests)
  - bipedHas20Joints : BIPED.get().getJointNumber() == 20
  - searchBipedJointByNameReturnsNonNull : vérifie les 20 noms EF
  - jointIdsMatchEfLayout : verrou P0-BUG-001 (id=12→Hand_R, id=14→Elbow_R,
    etc.) — aurait attrapé le bug en review initiale
  - bipedSingleton : BIPED.get() == BIPED.get() (verrou P0-BUG-002)

P2 backlog tracé dans docs/plans/rig/PHASE0_DEGRADATIONS.md :
  biped collapsed visuellement jusqu'à Phase 2.7, PlayerPatch.yBodyRot sans
  lerp, ridingEntity non géré, isFirstPersonHidden nommage ambigu,
  ServerPlayerPatch hérite méthodes client-only sans @OnlyIn.

Tests : 15 GREEN (11 bridge pré-existants + 4 nouveaux biped).
Compile clean.
2026-04-22 22:27:01 +02:00
notevil
79fc470aa0 Phase 2.4 : étoffer PlayerPatch stubs + biped armature procédurale
PlayerPatch : getArmature→TiedUpArmatures.BIPED, overrideRender→true,
getModelMatrix avec PLAYER_SCALE=15/16, initAnimator bind IDLE→EMPTY.
ServerPlayerPatch : ré-override overrideRender→false (le serveur ne rend pas).
ClientPlayerPatch : stub isFirstPersonHidden() pour Phase 3 (V3-REW-01).
LocalPlayerPatch : override render→false si on est soi-même en first-person
(laisse rendre les bras vanilla), true sinon.

TiedUpArmatures.BIPED : HumanoidArmature procédurale 20 joints identity
(Root → Thigh/Leg/Knee_R/L, Torso → Chest → Head + Shoulder/Arm/Elbow/
Hand/Tool_R/L). Phase 2.7 remplacera par JSON Blender-authored.

Fixe P2-RISK-01 (InitAnimatorEvent listeners NPE si getArmature()=null).

Tests : 11 bridge tests GREEN, full suite GREEN, compile clean.
2026-04-22 22:12:44 +02:00
notevil
ccec6bd87e Phase 2.3 review fixes : P2-BUG-01/02/03 + RISK-02
Résout les findings P0 remontés par la review post-Phase 2.3 (@4780c96).

P2-BUG-01 — Pipeline RIG dormant au runtime
  EntityPatchProvider.registerEntityPatches() et registerEntityPatchesClient()
  étaient définis mais JAMAIS appelés depuis TiedUpMod setups → CAPABILITIES
  map vide → aucun patch ne se crée, pipeline entier dormant.
  Fix :
  - commonSetup : event.enqueueWork(EntityPatchProvider::registerEntityPatches)
  - ClientModEvents.onClientSetup : event.enqueueWork(
    EntityPatchProvider::registerEntityPatchesClient) avant BondageAnimationManager.init

P2-BUG-02 — Memory leak LazyOptional non invalidée
  EntityPatchProvider.optional jamais invalidated → chaque respawn/dim change
  fuit patch + animator + armature.
  Fix :
  - EntityPatchProvider.invalidate() public méthode qui appelle optional.invalidate()
  - TiedUpCapabilityEvents.attachEntityCapability : event.addListener(provider::invalidate)
    après addCapability. Pattern aligné sur V2BondageEquipmentProvider existant.

P2-BUG-03 — NPE latent HumanoidModelBaker.bakeArmor
  Ligne 88 retournait entityMesh.getHumanoidArmorModel(slot).get() mais le
  getter retourne null (Phase 0 strip S-03 : Meshes.HELMET/CHESTPLATE/LEGGINS/BOOTS
  strippés). Null-check + fallback null + commentaire pointant vers V3-REW-04.

P2-RISK-02 — @OnlyIn(Dist.CLIENT) sur transformers
  VanillaModelTransformer, HumanoidModelTransformer, HumanoidModelBaker
  importent HumanoidModel/PoseStack (client-only). Risque NoClassDefFoundError
  si code serveur touche HumanoidModelBaker.VANILLA_TRANSFORMER static field.
  Fix : @OnlyIn(Dist.CLIENT) sur les 3 classes.

P2-RISK-01/03 + SMELL-01/02/03 tracés dans docs/plans/rig/PHASE0_DEGRADATIONS.md
Phase 2.1-2.3 findings section.

Compile BUILD SUCCESSFUL + 11 tests bridge GREEN maintenus.
2026-04-22 21:42:22 +02:00
notevil
faad0ced0f Phase 2.3 : capability system RIG (EntityPatchProvider + events)
5 classes ajoutées dans rig/patch/ :

- TiedUpCapabilities.java
  Holder du Capability<EntityPatch> CAPABILITY_ENTITY (CapabilityToken
  auto-register) + helpers getEntityPatch / getPlayerPatch /
  getPlayerPatchAsOptional. Simplifié de EF (pas de ITEM/PROJECTILE/SKILL
  caps, combat only).

- EntityPatchProvider.java
  ICapabilityProvider + Map<EntityType, Function<Entity, Supplier<EntityPatch<?>>>>.
  registerEntityPatches() pour commonSetup (EntityType.PLAYER seul Phase 2),
  registerEntityPatchesClient() pour clientSetup (dispatch LocalPlayerPatch vs
  ClientPlayerPatch<RemotePlayer> vs ServerPlayerPatch). CUSTOM_CAPABILITIES
  pour extensions futures. Pas de GlobalMobPatch combat fallback.
  IMPORTANT : n'enregistre PAS EntityType.VILLAGER (MCA conflict V3-REW-10).

- TiedUpCapabilityEvents.java
  @Mod.EventBusSubscriber sur AttachCapabilitiesEvent<Entity>. Check oldPatch
  pour éviter double-attach, construit provider, appelle onConstructed eager
  (D-01 pattern EF), addCapability. Priority NORMAL (order d'attachement
  ne matière pas, c'est les runtime cross-cap reads qui importent et ceux-là
  sont déjà lazy dans onConstructed).

3 stubs PlayerPatch subclasses (placeholders Phase 2.4) :

- ServerPlayerPatch : overrideRender=false, getArmature=null stub, updateMotion no-op
- ClientPlayerPatch<T extends AbstractClientPlayer> : overrideRender=true, @OnlyIn CLIENT
- LocalPlayerPatch extends ClientPlayerPatch<LocalPlayer> : vide pour l'instant

Ces stubs satisfont le compile de EntityPatchProvider.registerEntityPatchesClient().
Le getArmature() null est non-bloquant Phase 2.3 mais devra être fixé Phase 2.4
pour le vrai rendering (lien avec TiedUpRigRegistry.BIPED à créer Phase 2.7).

Compile BUILD SUCCESSFUL + 11 tests bridge GREEN maintenus.
2026-04-22 21:23:01 +02:00
notevil
3aec681436 Phase 2.2 : fork mesh/transformer/ (vanilla PlayerModel → SkinnedMesh)
COPY verbatim EF + rewrite imports :
- rig/mesh/transformer/VanillaModelTransformer.java (~700 LOC)
  Transformer principal : bake PlayerModel vanilla / HumanoidModel → SkinnedMesh biped
  EF. Utilise les PartTransformer (HEAD/ARM/LEG/CHEST) avec AABB cover area.
- rig/mesh/transformer/HumanoidModelTransformer.java (~70 LOC)
  Base abstract commune aux transformers humanoïdes.
- rig/mesh/transformer/HumanoidModelBaker.java (~115 LOC)
  Entry point bake() + export JSON + registry MODEL_TRANSFORMERS.

L'ancienne stub de VanillaMeshPartDefinition (record 55 LOC) est remplacée par
la vraie record dans le fork — API identique (of(partName), of(partName, path,
invertedParentTransform, root)).

Ajouté mixin accessor :
- rig/mixin/client/MixinAgeableListModel.java (@Invoker pour headParts/bodyParts
  sur AgeableListModel).
- src/main/resources/tiedup-rig.mixins.json (nouveau mixin config, package
  com.tiedup.remake.rig.mixin).
- build.gradle : args '-mixin.config=tiedup-rig.mixins.json' dans client+server
  run configs.
- META-INF/mods.toml : [[mixins]] config="tiedup-rig.mixins.json"

Logger EpicFightMod.LOGGER → TiedUpRigConstants.LOGGER dans HumanoidModelBaker.
Packages correctement rewrités par scripts/rig-rewrite-imports.sh. Compile
BUILD SUCCESSFUL maintenu.
2026-04-22 20:59:32 +02:00
notevil
4a587b7478 Phase 2.1 : D-01 fix — LivingEntityPatch animator field + eager init
Close le trap CRITIQUE tracé dans docs/plans/rig/PHASE0_DEGRADATIONS.md D-01
(getAnimator()=null → NPE garanti sur premier appel à MoveCoordFunctions:202,263).

Pattern EF-style conforme LivingEntityPatch EF:146-156 :
- protected Animator animator field
- Override onConstructed(T) : super + factory apply + initAnimator + postInit
- initAnimator(Animator) hook no-op pour subclasses (bind LivingMotion→Anim)
- getAnimator() retourne le field (non-null après onConstructed)
- getClientAnimator() : cast conditionnel instanceof ClientAnimator

Factory TiedUpRigConstants.ANIMATOR_PROVIDER (déjà en place, pattern lazy
method-ref client/server split) fournit la bonne instance selon Dist.

Compile + tests GREEN maintenus (11 tests bridge).
2026-04-22 20:31:00 +02:00
notevil
4d90a87b48 Phase 1 polish : SMELL-001, DOC-001, TEST-001 fixes
Résout les 3 items remontés par la review globale pré-Phase 2 :

SMELL-001 — TiedUpRigConstants.ANIMATOR_PROVIDER
  Le ternaire retournait ServerAnimator::getAnimator dans les 2 branches
  alors que ClientAnimator est maintenant forké (présent dans rig/anim/client/).
  Switch vers ClientAnimator::getAnimator côté client (pattern lazy method-ref
  préserve la non-chargement sur serveur dédié).

DOC-001 — AnimationManager:211
  Commentaire ambigu "SkillManager.reloadAllSkillsAnimations() strippé"
  clarifié : préciser que l'appel upstream EF venait de yesman.epicfight.skill.*
  et que le combat system est hors scope TiedUp.

TEST-001 — GltfToSkinnedMeshTest coverage gaps
  Tests précédents utilisaient [1,0,0,0] → drop trivial, renorm no-op.
  Ajoute 3 tests :
  - convertDropsLowestWeightAndRenormalizes : poids [0.5, 0.3, 0.15, 0.05]
    force le drop du plus faible (0.05) + renorm des 3 restants.
  - convertHandlesZeroWeightVertex : weights tous-zéro → fallback Root w=1.
  - convertFallsBackToRootForUnknownJointName : joint GLB inconnu ("TentacleJoint42")
    → log WARN + fallback Root id=0 sans crash.

11 tests bridge GREEN (5 alias + 6 convert). Compile BUILD SUCCESSFUL.
2026-04-22 19:58:51 +02:00
notevil
29c4fddb90 Phase 1.4 : tests unitaires bridge GLB→SkinnedMesh
8 tests GREEN :

GlbJointAliasTableTest (5) :
- mapLegacyPlayerAnimatorNames : body→Chest, leftUpperArm→Arm_L,
  leftLowerArm→Elbow_L, leftUpperLeg→Thigh_L, leftLowerLeg→Knee_L, etc.
- isCaseInsensitive : BODY/LeftUpperArm/leftupperarm tous remappés
- bypassBipedNames : Arm_L, Elbow_R, Head, Chest, Torso, Root non transformés
- unknownReturnsNull : null pour nom inconnu / vide / null
- isBipedJointNameDetection : _R/_L suffix + Root/Torso/Chest/Head

GltfToSkinnedMeshTest (3) :
- convertSyntheticGltfDoesNotThrow : 3 vertices + armature biped minimale (4
  joints manuels Root→Chest→{Arm_L,Arm_R}) → SkinnedMesh non null
- convertSyntheticGltfHasExpectedParts : partName dérivé du materialName de la
  primitive glTF
- convertThrowsOnNullArmature : IllegalStateException si armature null

Fixture : buildMinimalArmature() construit une hiérarchie 4 joints via Joint()
+ addSubJoints() + Armature(name, count, root, jointMap).bakeOriginMatrices().
buildSyntheticGltf() produit un triangle 3-vertices avec jointNames
(body, leftUpperArm, rightUpperArm) pour tester le mapping PlayerAnimator→EF.
2026-04-22 19:08:05 +02:00
notevil
94fcece05a Phase 1.1-1.3 : bridge GLB → SkinnedMesh
Premier jalon Phase 1 : conversion d'un GltfData (format legacy 11-joints
PlayerAnimator) vers SkinnedMesh Epic Fight (biped ~20 joints).

Files :
- rig/bridge/GlbJointAliasTable.java : table mapping statique PlayerAnimator
  → biped EF (body/torso→Chest, leftUpperArm→Arm_L, leftLowerArm→Elbow_L, etc).
  Fallback Root pour inconnus. Bypass si nom déjà biped (Root/Torso/Chest/Head
  ou suffixe _R/_L).
- rig/bridge/GltfToSkinnedMesh.java : convert(GltfData, AssetAccessor<Armature>)
  → SkinnedMesh. Pré-calcule jointIdMap, boucle vertices (pos/normal/uv + drop 4th
  joint à plus faible poids + renormalise 3 restants), groupe indices par
  primitive (material) en VanillaMeshPartDefinition.

Note : animations GLB ignorées (scope Phase 4 JSON EF authored).

Compile BUILD SUCCESSFUL maintenu.
2026-04-22 14:28:37 +02:00
notevil
4a615368df Phase 0 audit findings : fixes D-07 + D-08 post-verification
Cross-check de l'audit Phase 0 contre les sources EF (4 agents) a remonté :

D-08 RÉFUTÉ partiellement :
  - EF LivingEntityPatch.getTarget() = getLastHurtMob() — identique à notre stub.
  - MAIS MobPatch.getTarget() override avec Mob.getTarget() manquait chez nous.
  - Fix : override ajouté, ref commentée à EF MobPatch.java:171-174.
  - Sans ça, MoveCoordFunctions.MOB_ATTACK_TARGET_LOOK aurait la mauvaise
    sémantique (dernier mob qui m'a frappé vs cible AI courante) → NPC ne
    tourne pas vers sa cible pendant attack anim.

D-07 VALIDÉ :
  - correctRootJoint zero-out X/Z de la Root en espace monde pour éviter
    sliding visuel pendant LinkAnimation vers ActionAnimation.
  - Safe Phase 1 (idle/walk = StaticAnimation, pas ActionAnimation).
  - Critical Phase 2+ dès qu'une vraie ActionAnimation bondage est jouée.
  - Fix : dev assertion LOGGER.warn en IS_DEV_ENV pointant vers
    PHASE0_DEGRADATIONS.md D-07. Empêche découverte tardive.

Autres findings post-vérification (traçés en doc gitignorée) :
  D-01 getAnimator()=null : fix Phase 2 (pas Phase 1) — field protected EF-style
  D-02 sync() stripped : FAUX-POSITIF partiel — BEGINNING_LOCATION non affecté
       (IndependentVariableKey non-synced), seul DESTINATION en MP dédié
  D-03 InstantiateInvoker throws : swallowed par try/catch, silent no-op
  D-04 Patch suppression : doc EXTRACTION.md §3.12/§10 corrigée (Option A)
  D-05 reloadAllSkillsAnimations : était déjà dans SkillManager (commentaire OK)
  D-06 playAnimationAt : ARCHITECTURE.md §5.5.1 pseudocode (signature fantôme)
       → notes ajoutées pointant vers D-06
  D-09 AnimationBegin/EndEvent : listeners EF uniquement skill system interne,
       ON_BEGIN/END_EVENTS data-driven continuent de fonctionner
  D-10 AT 127 lignes : ~50% utile (GUI TiedUp existant), ne pas fix maintenant

IK stack (S-05 pas dans les docs) : section R12 ajoutée à ARCHITECTURE.md §11.

Compile BUILD SUCCESSFUL maintenu (0 errors).
2026-04-22 03:39:44 +02:00
notevil
1cef57a472 Phase 0 : compile SUCCESS (464 -> 0 errors)
Core data model du rig EF extractible compile désormais cleanly.

Changements clé :

1. AccessTransformer wiring (-80 errors)
   - Copie EF accesstransformer.cfg dans resources/META-INF/
   - Uncomment accessTransformer = file(...) dans build.gradle
   - Débloque l'héritage des package-private RenderType.CompositeState +
     RenderType.CompositeRenderType + RenderType.OutlineProperty nécessaires
     à TiedUpRenderTypes.

2. Stubs compat rendering Phase 2
   - PatchedEntityRenderer<E,T,M,R> : type param 4 pour PrepareModelEvent
   - RenderItemBase : type marker pour PatchedRenderersEvent.RegisterItemRenderer
   - LayerUtil + LayerProvider : interface fonctionnelle 5-params pour RegisterResourceLayersEvent
   - PlayerPatch<T extends Player> : extends LivingEntityPatch
   - ToolHolderArmature interface : leftTool/rightTool/backToolJoint()

3. Stubs compat combat Phase 2+
   - AttackResult + ResultType enum : utilisé comme type pour StateFactor ATTACK_RESULT
   - TrailInfo record : stubbé avec playable=false → particle trail jamais émis
   - AttackAnimation.Phase.hand = InteractionHand.MAIN_HAND
   - AttackAnimation.JointColliderPair : stub pour instanceof check
   - AttackAnimation.getPhaseByTime(float) : retourne Phase neutre
   - ActionAnimation.correctRootJoint() : no-op Phase 0
   - ActionAnimation.BEGINNING_LOCATION + INITIAL_LOOK_VEC_DOT re-exposés comme AnimationVariables

4. Physics types alignés
   - InverseKinematicsProvider extends SimulationProvider<...>
   - InverseKinematicsSimulator implements PhysicsSimulator<Joint, ...>
   - InverseKinematicsObject implements SimulationObject<...>
   - InverseKinematicsBuilder extends SimulationObject.SimulationObjectBuilder
   - ik.bake() signature : (Object, Object, boolean, boolean) conforme StaticAnimation usage

5. Mesh/compute stubs
   - ComputeShaderSetup.TOTAL_POSES + TOTAL_NORMALS : OpenMatrix4f[MAX_JOINTS] pool
   - ComputeShaderSetup.MeshPartBuffer inner class + destroyBuffers()
   - ComputeShaderProvider.supportComputeShader() = false
   - VanillaModelTransformer.VanillaMeshPartDefinition record minimal
   - HumanoidMesh.getHumanoidArmorModel() : return null (armor rendering Phase 2)

6. Fixes typage / API
   - TiedUpRenderTypes.prefix("x").toString() x15 : ResourceLocation -> String
   - AnimationManager Logger : log4j -> slf4j
   - TiedUpRigConstants.logAndStacktraceIfDevSide 4-arg overload + Throwable instead of RuntimeException
   - LivingEntityPatch.getReach(InteractionHand) overload
   - StaticAnimation(boolean, String, AssetAccessor) 3-arg overload

Result : compileJava -> BUILD SUCCESSFUL
Prochain jalon : runClient + verify rig se charge sans crash.
2026-04-22 03:16:14 +02:00
notevil
bdbd429bdf WIP: fork patch/collider/codec stubs, 464->135 compile errors
Phase 0 compile progress (70% reduction). Core data model compile :

Refs yesman.epicfight strippées (hors 4 javadocs) :
- AnimationProperty : combat properties EXTRA_DAMAGE, STUN_TYPE, PARTICLE
- ClientAnimator : playAnimationAt(..., AnimatorControlPacket.Layer, Priority)
- ClothSimulator : OBBCollider -> fork geometry-only dans rig/collider/
- InstantiateInvoker : Collider, ColliderPreset, Armatures, DatapackEditScreen
- MoveCoordFunctions : GrapplingAttackAnimation
- SimulationTypes : InverseKinematicsSimulator (path rewrite)

Stubs patch/ :
- EntityPatch<T> abstract — getOriginal, isLogicalClient, getMatrix, getAngleTo
- LivingEntityPatch<T> abstract — getAnimator, getArmature, getTarget, getYRot*
- MobPatch<T extends Mob> — instanceof check only
- item/CapabilityItem — type marker

Forks utilitaires :
- rig/collider/OBBCollider — geometry only (strip Entity collision, drawInternal)
- anim/types/StateSpectrum — identique EF, imports rewrités
- util/PacketBufferCodec — StreamCodec backport
- util/TimePairList — identique EF
- util/HitEntityList — shell pour Priority enum uniquement
- util/ExtendableEnum + ExtendableEnumManager — register/assign enum

Fix package declarations :
- armature/Joint.java + JointTransform.java : package rig.anim -> rig.armature
- Imports JointTransform ajoutés dans anim/{Pose,Keyframe,TransformSheet}

Residu 135 errors = cluster rendering (Phase 2) :
- render/TiedUpRenderTypes (17) : CompositeState package-private MC
- event/PatchedRenderersEvent (11) : missing PatchedEntityRenderer
- mesh/SkinnedMesh (13) : VanillaMeshPartDefinition, compute shader fields
- asset/JsonAssetLoader (6), anim/LivingMotion (5)
2026-04-22 02:45:18 +02:00
notevil
f0d8408384 WIP: stub ClientConfig + gameasset registries, strip Meshes mobs
Nouveaux stubs core :
- TiedUpAnimationConfig     — remplace yesman.epicfight.config.ClientConfig.
                              Flags animation/rendu, no-op pour combat.
- TiedUpRigRegistry         — remplace gameasset.Animations.EMPTY_ANIMATION +
                              gameasset.Armatures.ArmatureContructor.

Fichiers forkés additionnels (dépendances transitives découvertes) :
- anim/types/DirectStaticAnimation.java   (EMPTY_ANIMATION est un DirectStaticAnimation)
- event/InitAnimatorEvent.java            (postInit() forge event)
- event/EntityPatchRegistryEvent.java     (mod bus event pour register patches)

Strip combat :
- Meshes.java : retiré les 11 mob meshes (CreeperMesh, DragonMesh, VexMesh,
                WitherMesh, etc.) + armor + particle + cape. Garde BIPED
                et ALEX / BIPED_OLD_TEX / BIPED_OUTLAYER (variants joueur).
- Animator.playDeathAnimation : Animations.BIPED_DEATH (ARR asset) →
                                EMPTY_ANIMATION fallback.
- AnimationManager.apply : Armatures.reload() stripped (no-op, à rebrancher
                           Phase 2 sur TiedUpArmatures).
- ClientPlayerPatch.entityPairing : body entier strippé (combat skills
                                    Technician/Adrenaline/Emergency Escape).

sed global : ClientConfig.* → TiedUpAnimationConfig.*
sed global : Animations.EMPTY_ANIMATION → TiedUpRigRegistry.EMPTY_ANIMATION
sed global : Armatures.ArmatureContructor → TiedUpRigRegistry.ArmatureContructor

Résidus yesman.epicfight : 86 → 74 (-12)
Reste : physics (16) + network (13) + world combat (10) + particle (3) +
collider (2) + client misc (2) + skill (2). Tous combat-entangled,
demandent strip méthode par méthode.
2026-04-22 00:53:42 +02:00
notevil
324e7fb984 WIP: create TiedUpRigConstants, replace EpicFightMod/SharedConstants refs
- Nouveau TiedUpRigConstants.java : centralise MODID/LOGGER/identifier/prefix,
  constantes runtime (IS_DEV_ENV, A_TICK, GENERAL_ANIMATION_TRANSITION_TIME,
  MAX_JOINTS), factory ANIMATOR_PROVIDER (client/server split) + helpers
  stacktraceIfDevSide/logAndStacktraceIfDevSide.

- sed global : EpicFightMod.* → TiedUpRigConstants.*
- sed global : EpicFightSharedConstants.* → TiedUpRigConstants.*
- sed global : EpicFightRenderTypes → TiedUpRenderTypes (class rename upstream)
- Fix package declarations : Armature.java + TiedUpRenderTypes.java

Résidus yesman.epicfight : 115 → 86 (-29)
Reste : gameasset/physics/network/world/config/skill (combat deps à strip) +
combat mode refs dans patch/LocalPlayerPatch + ClientPlayerPatch (Phase 2).
2026-04-22 00:33:39 +02:00
notevil
cbf61906e0 WIP: initial epic fight core extraction (Phase 0)
83 files forkés d'Epic Fight (~18k LOC). Base non-compilable en l'état.

Contenu extrait :
- math/ — OpenMatrix4f, Vec3f/4f/2f, QuaternionUtils, MathUtils, ...
- armature/ — Armature, Joint, JointTransform, HumanoidArmature
- anim/ — Animator, ServerAnimator, ClientAnimator, LivingMotion, ...
- anim/types/ — StaticAnimation, DynamicAnimation, MovementAnimation, LinkAnimation,
                ConcurrentLinkAnimation, LayerOffAnimation, EntityState
- anim/client/ — Layer, ClientAnimator, JointMask
- mesh/ — SkinnedMesh, SingleGroupVertexBuilder, Mesh, HumanoidMesh, ...
- cloth/ — AbstractSimulator, ClothSimulator (dépendance transitive de StaticMesh)
- asset/ — JsonAssetLoader, AssetAccessor
- patch/ — EntityPatch, LivingEntityPatch, PlayerPatch, ClientPlayerPatch
- util/ — ParseUtil, TypeFlexibleHashMap
- exception/ — AssetLoadingException
- event/ — PatchedRenderersEvent, PrepareModelEvent, RegisterResourceLayersEvent
- render/ — TiedUpRenderTypes

Headers GPLv3 + attribution injectés sur tous les .java.
Package declarations fixées sur Armature.java et TiedUpRenderTypes.java.

115 imports résiduels à résoudre manuellement :
- yesman.epicfight.main (EpicFightMod, EpicFightSharedConstants) — 30
- yesman.epicfight.gameasset (Animations, Armatures, EpicFightSounds) — 12
- yesman.epicfight.api.physics + physics.ik (combat physics) — 16
- yesman.epicfight.network.* (combat packets) — 13
- yesman.epicfight.world.* (combat entity logic) — 10
- yesman.epicfight.config.ClientConfig — 3
- yesman.epicfight.skill, .client.gui, .particle, .collider — divers combat/UI

Stratégie fix (2-3 sem manuel) : strip usage combat, stubs pour refs
core (EpicFightMod → TiedUpMod, SharedConstants → TiedUpRigConstants,
ClientConfig → TiedUpAnimationConfig).
2026-04-22 00:26:29 +02:00
notevil
b141e137e7 add rig extraction scripts
scripts/rig-rewrite-imports.sh  — package rewrites yesman.epicfight.* → com.tiedup.remake.rig.*
scripts/rig-headers.sh          — GPLv3 + attribution Epic Fight header injection
scripts/rig-extract-phase0.sh   — master script Phase 0 (copy + rewrite + headers)

Cf. docs/plans/rig/EXTRACTION.md §9 (docs restent locales).
2026-04-22 00:26:09 +02:00
notevil
b0b719b3dd relicense to GPL-3.0-or-later
Drop Commons-Clause and monetization restrictions to enable
incorporating third-party GPLv3 code in upcoming rig system work.

Prior versions (0.1.0–0.5.x) remain under GPL-3.0 WITH Commons-Clause.
From 0.6.0-ALPHA, GPL-3.0-or-later pure.
2026-04-22 00:13:50 +02:00
5d0c7c6c69 Merge pull request 'Polish V2 subsystem: lockpick kinds, package boundaries, client extractions' (#22) from refactor/v2-polish into develop
Reviewed-on: #22
2026-04-19 00:06:54 +00:00
NotEvil
cc6a62a6e5 Polish V2 subsystem: lockpick kinds, package boundaries, client extractions
Architectural debt cleanup on top of the earlier V2 hardening pass.

Minigame:
  - LockpickMiniGameState splits the overloaded targetSlot int into a
    LockpickTargetKind enum + targetData int. Body-vs-furniture
    dispatch is now a simple enum check; the NBT-tag nonce it
    previously depended on is gone, along with the AIOOBE risk at
    BodyRegionV2.values()[targetSlot].
  - PacketLockpickAttempt.handleFurnitureLockpickSuccess takes the
    entity and seat id as explicit parameters. Caller pre-validates
    both before any side effect, so a corrupted ctx tag can no longer
    produce a "Lock picked!" UI with a used lockpick and nothing
    unlocked.

Package boundaries:
  - client.gltf no longer imports v2.bondage. Render-layer attachment,
    DataDrivenItemReloadListener, and GlbValidationReloadListener all
    live in v2.client.V2ClientSetup.
  - GlbValidationReloadListener moved to v2.bondage.client.diagnostic.
  - Reload-listener ordering is preserved via EventPriority (HIGH for
    the generic GLB cache clear in GltfClientSetup, LOW for bondage
    consumers in V2ClientSetup).
  - Removed the unused validateAgainstDefinition stub on GlbValidator.

Extractions from EntityFurniture:
  - FurnitureSeatSyncCodec (pipe/semicolon serialization for the
    SEAT_ASSIGNMENTS_SYNC entity data field), with 8 unit tests.
  - FurnitureClientAnimator (client-only seat-pose kickoff, moved out
    of the dual-side entity class).
  - EntityFurniture drops ~100 lines with no behavior change.

Interface docs:
  - ISeatProvider Javadoc narrowed to reflect that EntityFurniture is
    the only implementation; callers that need animation state or
    definition reference still downcast.
  - FurnitureAuthPredicate.findOccupant uses the interface only.
  - AnimationIdBuilder flagged as legacy JSON-era utility (NPC
    fallback + MCA mixin).

Artist guide: corrected the "Monster Seat System (Planned)" section
to match the ISeatProvider single-impl reality.
2026-04-19 02:06:02 +02:00
d391b892aa Merge pull request 'Refactor V2 animation, furniture, and GLTF rendering' (#21) from refactor/v2-animation-hardening into develop
Reviewed-on: #21
2026-04-18 22:26:58 +00:00
NotEvil
355e2936c9 Refactor V2 animation, furniture, and GLTF rendering
Broad consolidation of the V2 bondage-item, furniture-entity, and
client-side GLTF pipeline.

Parsing and rendering
  - Shared GLB parsing helpers consolidated into GlbParserUtils
    (accessor reads, weight normalization, joint-index clamping,
    coordinate-space conversion, animation parse, primitive loop).
  - Grow-on-demand Matrix4f[] scratch pool in GltfSkinningEngine and
    GltfLiveBoneReader — removes per-frame joint-matrix allocation
    from the render hot path.
  - emitVertex helper dedups three parallel loops in GltfMeshRenderer.
  - TintColorResolver.resolve has a zero-alloc path when the item
    declares no tint channels.
  - itemAnimCache bounded to 256 entries (access-order LRU) with
    atomic get-or-compute under the map's monitor.

Animation correctness
  - First-in-joint-order wins when body and torso both map to the
    same PlayerAnimator slot; duplicate writes log a single WARN.
  - Multi-item composites honor the FullX / FullHeadX opt-in that
    the single-item path already recognized.
  - Seat transforms converted to Minecraft model-def space so
    asymmetric furniture renders passengers at the correct offset.
  - GlbValidator: IBM count / type / presence, JOINTS_0 presence,
    animation channel target validation, multi-skin support.

Furniture correctness and anti-exploit
  - Seat assignment synced via SynchedEntityData (server is
    authoritative; eliminates client-server divergence on multi-seat).
  - Force-mount authorization requires same dimension and a free
    seat; cross-dimension distance checks rejected.
  - Reconnection on login checks for seat takeover before re-mount
    and force-loads the target chunk for cross-dimension cases.
  - tiedup_furniture_lockpick_ctx carries a session UUID nonce so
    stale context can't misroute a body-item lockpick.
  - tiedup_locked_furniture survives death without keepInventory
    (Forge 1.20.1 does not auto-copy persistent data on respawn).

Lifecycle and memory
  - EntityCleanupHandler fans EntityLeaveLevelEvent out to every
    per-entity state map on the client.
  - DogPoseRenderHandler re-keyed by UUID (stable across dimension
    change; entity int ids are recycled).
  - PetBedRenderHandler, PlayerArmHideEventHandler, and
    HeldItemHideHandler use receiveCanceled + sentinel sets so
    Pre-time mutations are restored even when a downstream handler
    cancels the render.

Tests
  - JUnit harness with 76+ tests across GlbParserUtils, GltfPoseConverter,
    FurnitureSeatGeometry, and FurnitureAuthPredicate.
2026-04-18 17:34:03 +02:00
17815873ac Merge pull request 'chore/final-polish' (#19) from chore/final-polish into develop
Reviewed-on: #19
2026-04-17 02:08:26 +00:00
NotEvil
b5ae04a1f1 guard ResourceLocation.parse() against corrupted NBT in furniture reconnect 2026-04-17 04:08:02 +02:00
NotEvil
fe36a1a47e vary room theme weights — sculk rare, inferno/ice uncommon 2026-04-17 04:08:02 +02:00
cc8adfe015 Merge pull request 'feature/gltf-pipeline-v2' (#18) from feature/gltf-pipeline-v2 into develop
Reviewed-on: #18
2026-04-17 02:07:43 +00:00
NotEvil
f37600783a docs(artist-guide): update for Full/FullHead conventions, custom bones, frame 0 behavior, validation tools 2026-04-17 04:06:33 +02:00
NotEvil
168c0675bb fix(animation): fix variant caching bug in multi-item path — same fix as single-item 2026-04-17 04:06:33 +02:00
NotEvil
a3287b7db8 fix(animation): variant randomness no longer permanently cached + fix FullHead false-positive
Two fixes from the animation audit:

1. Variant cache key now includes the resolved animation name (e.g., Struggle.2).
   Previously, the cache key only used context+parts, so the first random variant
   pick was reused forever. Now each variant gets its own cache entry, and a fresh
   random pick happens each time the context changes.

2. FullHead check changed from contains("Head") to startsWith("gltf_FullHead")
   to prevent false positives on names like FullOverhead or FullAhead.
2026-04-17 04:06:33 +02:00
NotEvil
e56e6dd551 fix(animation): extend resolver fallback chain to include FullHead variants
The resolver now tries FullHead* before Full* at each fallback step.
Example: FullHeadStruggle → FullStruggle → Struggle → FullHeadIdle → FullIdle → Idle

Previously FullHead* names were dead — the resolver never constructed them,
so animations named FullHeadStruggle were unreachable.
2026-04-17 04:06:33 +02:00
NotEvil
806a1e732d feat(animation): add FullHead convention — opt-in head animation in Full animations
FullStruggle, FullWalk etc. animate body+legs but preserve head tracking.
FullHeadStruggle, FullHeadWalk etc. also animate the head.
The 'Head' keyword in the animation name is the opt-in signal.
2026-04-17 04:06:33 +02:00
NotEvil
3d57d83a5b fix(animation): preserve head tracking in Full animations — head never enabled as free bone 2026-04-17 04:06:33 +02:00
NotEvil
229fc66340 fix(animation): free bones only enabled for Full-prefixed animations
Previously, any GLB with keyframes on free bones would animate them,
even for standard animations like Idle. This caused accidental bone
hijacking — e.g., handcuffs freezing the player's head because the
artist keyframed all bones in Blender.

Now the Full prefix (FullIdle, FullStruggle, FullWalk) is enforced:
only Full-prefixed animations can animate free bones. Standard
animations (Idle, Struggle, Walk) only animate owned bones.

This aligns the code with the documented convention in ARTIST_GUIDE.md.
2026-04-17 04:06:33 +02:00
NotEvil
b0766fecc6 feat(validation): show toast notification when GLB errors are detected on reload 2026-04-17 04:06:33 +02:00
NotEvil
9dfd2d1724 fix(validation): reduce log spam + add OOM guard + check correct mesh for WEIGHTS_0
- DataDrivenItemParser: downgrade animation_bones absence log from INFO to
  DEBUG (was spamming for every item without the optional field)
- GlbValidator: read 12-byte GLB header first and reject files declaring
  totalLength > 50 MB before allocating (prevents OOM on malformed GLBs)
- GlbValidator: WEIGHTS_0 check now uses the same mesh selection logic as
  GlbParser (prefer "Item", fallback to last non-Player) instead of
  blindly checking the first mesh
2026-04-17 04:06:33 +02:00