diff --git a/animations/walk_fwd_lower.anim.json b/animations/walk_fwd_lower.anim.json index 9c65da6..8fd881a 100644 --- a/animations/walk_fwd_lower.anim.json +++ b/animations/walk_fwd_lower.anim.json @@ -5,24 +5,19 @@ "loop": true, "keyframes": [ { "t": 0.0, - "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]}, - "foot_l": {"pos": [0, 0]}, "foot_r": {"pos": [0, 0]} + "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]} }, { "t": 0.2, - "leg_l": {"scl": [-1, -1]}, "leg_r": {"scl": [ 1, 0]}, - "foot_l": {"pos": [0, 25]}, "foot_r": {"pos": [0, 0]} + "leg_l": {"scl": [-1, -1]}, "leg_r": {"scl": [ 1, 1]} }, { "t": 0.4, - "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]}, - "foot_l": {"pos": [0, 0]}, "foot_r": {"pos": [0, 0]} + "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]} }, { "t": 0.6, - "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, -1]}, - "foot_l": {"pos": [0, 0]}, "foot_r": {"pos": [0, 25]} + "leg_l": {"scl": [-1, 1]}, "leg_r": {"scl": [ 1, -1]} }, { "t": 0.8, - "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]}, - "foot_l": {"pos": [0, 0]}, "foot_r": {"pos": [0, 0]} + "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]} } ] } diff --git a/init.lua b/init.lua index 8719b51..d3b24eb 100644 --- a/init.lua +++ b/init.lua @@ -113,11 +113,10 @@ local function update_lower_anim(moving, move_x, move_y) end puppet.stop(state.player, "idle_lower") puppet.stop(state.player, "idle") - -- Slow walk to ~0.5x substrate speed (user preference: too fast for - -- actual map traversal at substrate's 0.8s/cycle). - puppet.play(state.player, anim_id, { loop = true, speed = 0.5 }) + -- Slow walk to 0.4x substrate speed (user pref: still too fast at 0.5). + puppet.play(state.player, anim_id, { loop = true, speed = 0.4 }) if not puppet.is_playing(state.player, "walk_upper") then - puppet.play(state.player, "walk_upper", { loop = true, speed = 0.5 }) + puppet.play(state.player, "walk_upper", { loop = true, speed = 0.4 }) end state.walk_anim_current = anim_id if CI_FRAME_PERF and ci_last_state ~= "walk" then @@ -156,17 +155,25 @@ function M.init(ctx) puppet.play(state.player, "idle", { loop = true }) puppet.play(state.player, "idle_lower", { loop = true }) - -- Procedural leg-orientation: hips are body-relative (legs.parent=body, so - -- cascade-position follows body); the leg ROTATION is overridden each - -- frame to align with walk-direction (independent of body rotation). - -- leg.local.rot = walk_dir_world - body.world.rot → leg.world.rot = walk_dir. - -- write_bone allowed on leg.rot because walk_fwd_lower only writes leg.scl - -- (per-channel guard v0.4.2). - puppet.set_procedural(state.player, "leg_orientation", function(handle, dt) + -- Procedural leg+foot orientation: + -- * Hips are body-relative (legs.parent=body, position cascade follows body). + -- * leg.world.rot = walk_dir (independent of body). Set leg.local.rot = + -- walk_dir - body.world.rot so cascade gives correct world rot. + -- * foot.world.rot = body.world.rot (user pref: feet stay body-oriented + -- even when legs swing to walk-direction = "tactical twist"). Cascade: + -- foot.world.rot = leg.world.rot + foot.local.rot = body.rot. + -- → foot.local.rot = body.rot - leg.world.rot = body.rot - walk_dir + -- = -leg_local_deg. + -- Per-channel guard v0.4.2 allows leg.rot + foot.rot writes alongside + -- walk_fwd_lower (which only writes leg.scl). + puppet.set_procedural(state.player, "leg_foot_orientation", function(handle, dt) local _, _, body_rot = puppet.bone_world_transform(handle, "body") - local leg_local_deg = state.lower_control_rot_deg - math.deg(body_rot) - puppet.write_bone(handle, "leg_l", { rot = leg_local_deg }) - puppet.write_bone(handle, "leg_r", { rot = leg_local_deg }) + local leg_local_deg = state.lower_control_rot_deg - math.deg(body_rot) + local foot_local_deg = -leg_local_deg + puppet.write_bone(handle, "leg_l", { rot = leg_local_deg }) + puppet.write_bone(handle, "leg_r", { rot = leg_local_deg }) + puppet.write_bone(handle, "foot_l", { rot = foot_local_deg }) + puppet.write_bone(handle, "foot_r", { rot = foot_local_deg }) end) -- Furniture textures. diff --git a/manifest.module b/manifest.module index 792031f..1cff4ab 100644 --- a/manifest.module +++ b/manifest.module @@ -15,7 +15,7 @@ {"id": "lib-core.camera", "version": "0.3.0"}, {"id": "lib-core.render", "version": "0.1.0"}, {"id": "lib-core.maps", "version": "0.1.2"}, - {"id": "lib-core.puppet", "version": "0.4.2"}, + {"id": "lib-core.puppet", "version": "0.4.3"}, {"id": "lib-asset.prototype-subterrain", "version": "0.1.1"} ] } diff --git a/rigs/humanoid.rig.json b/rigs/humanoid.rig.json index 198ba19..e182548 100644 --- a/rigs/humanoid.rig.json +++ b/rigs/humanoid.rig.json @@ -12,8 +12,8 @@ { "id": "lower_arm_r", "parent": "upper_arm_r", "rest": {"x": 13, "y": -17, "rot": 0}, "z_order": 2, "texture": "lower_arm_001" }, { "id": "leg_l", "parent": "body", "rest": {"x": -9, "y": 1, "rot": 0, "scl": [-1, -1]}, "z_order": 1, "texture": "leg_001" }, { "id": "leg_r", "parent": "body", "rest": {"x": 9, "y": 1, "rot": 0, "scl": [ 1, -1]}, "z_order": 1, "texture": "leg_001" }, - { "id": "foot_l", "parent": "leg_l", "rest": {"x": 0, "y": 25, "rot": 0, "scl": [ 1, -1]}, "z_order": 0, "texture": "foot_001" }, - { "id": "foot_r", "parent": "leg_r", "rest": {"x": 0, "y": 26, "rot": 0, "scl": [ 1, -1]}, "z_order": 0, "texture": "foot_001" } + { "id": "foot_l", "parent": "leg_l", "rest": {"x": 0, "y": 25, "rot": 0, "scl": [ 1, 1]}, "z_order": 0, "texture": "foot_001", "inherit_scale": false }, + { "id": "foot_r", "parent": "leg_r", "rest": {"x": 0, "y": 26, "rot": 0, "scl": [ 1, 1]}, "z_order": 0, "texture": "foot_001", "inherit_scale": false } ], "tracks": [ { "id": "lower", "bones": ["leg_l", "leg_r", "foot_l", "foot_r"] },