From fa511204c2018ffa2d5a545ef29f5e61fc64be60 Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Mon, 18 May 2026 18:55:34 +0200 Subject: [PATCH] =?UTF-8?q?feat(vagrant):=20v0.3.0=20=E2=80=94=20substrate?= =?UTF-8?q?-port=20rig=20+=20animations=20+=20locomotion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - humanoid.rig.json rewrite: legs->root, rest.rot+rest.scl on all bones, Y-mirror via scl=-1 on leg_l/r/foot_l/r, locomotion-block with procedural footplant config - walk.anim.json: substrate walk_fwd_lower port; track=lower; pos+scl channels on legs+feet - walk_upper.anim.json (NEW): substrate walk_upper port; arm-swing - idle.anim.json: substrate idle_upper port; pos+rot on shoulders+arms - init.lua: walk_upper parallel-play wiring - manifest bump v0.2->v0.3; puppet dep ^0.3.0 --- animations/idle.anim.json | 45 +++++++++++++++++++++------ animations/walk.anim.json | 38 +++++++++++++++-------- animations/walk_upper.anim.json | 53 ++++++++++++++++++++++++++++++++ init.lua | 8 +++-- manifest.module | 4 +-- rigs/humanoid.rig.json | 54 ++++++++++++++++++++------------- 6 files changed, 156 insertions(+), 46 deletions(-) create mode 100644 animations/walk_upper.anim.json diff --git a/animations/idle.anim.json b/animations/idle.anim.json index 1dd640b..b22865f 100644 --- a/animations/idle.anim.json +++ b/animations/idle.anim.json @@ -1,11 +1,38 @@ { - "id": "idle", - "track": "upper", - "duration": 2.0, - "loop": true, - "keyframes": [ - { "t": 0.0, "body": {"angle": 0}, "head": {"angle": 0} }, - { "t": 1.0, "body": {"angle": 2}, "head": {"angle": -1} }, - { "t": 2.0, "body": {"angle": 0}, "head": {"angle": 0} } - ] + "id": "idle", + "track": "upper", + "duration": 2.0, + "loop": true, + "keyframes": [ + { + "t": 0, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": 0 }, + "upper_arm_l": { "rot": -15 }, + "lower_arm_l": { "rot": 10 }, + "upper_arm_r": { "rot": 15 }, + "lower_arm_r": { "rot": -10 }, + "head": { "rot": 0 } + }, + { + "t": 1, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, -0.5], "rot": 0 }, + "upper_arm_l": { "rot": -13 }, + "lower_arm_l": { "rot": 8 }, + "upper_arm_r": { "rot": 13 }, + "lower_arm_r": { "rot": -8 }, + "head": { "rot": 0 } + }, + { + "t": 2, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": 0 }, + "upper_arm_l": { "rot": -15 }, + "lower_arm_l": { "rot": 10 }, + "upper_arm_r": { "rot": 15 }, + "lower_arm_r": { "rot": -10 }, + "head": { "rot": 0 } + } + ] } diff --git a/animations/walk.anim.json b/animations/walk.anim.json index 7463c2f..5ad8d0a 100644 --- a/animations/walk.anim.json +++ b/animations/walk.anim.json @@ -1,14 +1,28 @@ { - "id": "walk", - "track": "lower", - "duration": 0.6, - "loop": true, - "keyframes": [ - { "t": 0.0, "leg_l": {"angle": -20}, "leg_r": {"angle": 20}, - "foot_l": {"angle": 10}, "foot_r": {"angle": -10} }, - { "t": 0.3, "leg_l": {"angle": 20}, "leg_r": {"angle": -20}, - "foot_l": {"angle": -10}, "foot_r": {"angle": 10} }, - { "t": 0.6, "leg_l": {"angle": -20}, "leg_r": {"angle": 20}, - "foot_l": {"angle": 10}, "foot_r": {"angle": -10} } - ] + "id": "walk", + "track": "lower", + "duration": 0.8, + "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]} + }, + { "t": 0.2, + "leg_l": {"scl": [-1, -1]}, "leg_r": {"scl": [ 1, 1]}, + "foot_l": {"pos": [-0.044, 25.47]}, "foot_r": {"pos": [0.249, 25.85]} + }, + { "t": 0.4, + "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]}, + "foot_l": {"pos": [0, 0]}, "foot_r": {"pos": [0, 0]} + }, + { "t": 0.6, + "leg_l": {"scl": [-1, 1]}, "leg_r": {"scl": [ 1, -1]}, + "foot_l": {"pos": [ 0.044, -25.47]}, "foot_r": {"pos": [-0.249, -25.85]} + }, + { "t": 0.8, + "leg_l": {"scl": [-1, 0]}, "leg_r": {"scl": [ 1, 0]}, + "foot_l": {"pos": [0, 0]}, "foot_r": {"pos": [0, 0]} + } + ] } diff --git a/animations/walk_upper.anim.json b/animations/walk_upper.anim.json new file mode 100644 index 0000000..a612626 --- /dev/null +++ b/animations/walk_upper.anim.json @@ -0,0 +1,53 @@ +{ + "id": "walk_upper", + "track": "upper", + "duration": 0.8, + "loop": true, + "keyframes": [ + { + "t": 0, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": -10 }, + "upper_arm_l": { "pos": [-18.835941314697266, -2.7534308433532715], "rot": -75, "scl": [-1, 1] }, + "lower_arm_l": { "pos": [14.152748107910156, -18.200172424316406], "rot": 90, "scl": [1, -0.4] }, + "upper_arm_r": { "pos": [20.023988723754883, -4.000017166137695], "rot": 5 }, + "lower_arm_r": { "rot": 0 } + }, + { + "t": 0.2, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": 0 }, + "upper_arm_l": { "pos": [-18.835941314697266, -2.7534308433532715], "rot": -50, "scl": [-1, 1] }, + "lower_arm_l": { "pos": [14.152749061584473, -18.200170516967773], "rot": 90, "scl": [1, 0] }, + "upper_arm_r": { "pos": [20.023988723754883, -4.000017166137695], "rot": 50 }, + "lower_arm_r": { "pos": [13.348801612854004, -17.08159637451172], "rot": 0, "scl": [1, 0] } + }, + { + "t": 0.4, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": 10 }, + "upper_arm_l": { "pos": [-18.83592987060547, -2.75343132019043], "rot": -5, "scl": [-1, 1] }, + "lower_arm_l": { "pos": [14.152749061584473, -18.200170516967773], "rot": 0, "scl": [1, 1] }, + "upper_arm_r": { "pos": [20.023984909057617, -4.000016689300537], "rot": 75 }, + "lower_arm_r": { "pos": [13.34880542755127, -17.08159637451172], "rot": 90, "scl": [1, 0.4] } + }, + { + "t": 0.6, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": 0 }, + "upper_arm_l": { "pos": [-18.835941314697266, -2.7534308433532715], "rot": -50, "scl": [-1, 1] }, + "lower_arm_l": { "pos": [14.152749061584473, -18.200170516967773], "rot": 90, "scl": [1, 0] }, + "upper_arm_r": { "pos": [20.023988723754883, -4.000017166137695], "rot": 50 }, + "lower_arm_r": { "pos": [13.348801612854004, -17.08159637451172], "rot": 0, "scl": [1, 0] } + }, + { + "t": 0.8, + "body": { "rot": 0 }, + "shoulders": { "pos": [0, 0], "rot": -10 }, + "upper_arm_l": { "pos": [-18.835941314697266, -2.7534308433532715], "rot": -75, "scl": [-1, 1] }, + "lower_arm_l": { "pos": [14.152748107910156, -18.200172424316406], "rot": 90, "scl": [1, -0.4] }, + "upper_arm_r": { "pos": [20.023988723754883, -4.000017166137695], "rot": 5 }, + "lower_arm_r": { "rot": 0 } + } + ] +} diff --git a/init.lua b/init.lua index 916cfb4..957ca5c 100644 --- a/init.lua +++ b/init.lua @@ -34,11 +34,13 @@ local function set_walk_or_idle(moving) if moving then if not puppet.is_playing(state.player, "walk") then puppet.stop(state.player, "idle") - puppet.play(state.player, "walk", { loop = true }) + puppet.play(state.player, "walk", { loop = true }) + puppet.play(state.player, "walk_upper", { loop = true }) end else if not puppet.is_playing(state.player, "idle") then puppet.stop(state.player, "walk") + puppet.stop(state.player, "walk_upper") puppet.play(state.player, "idle", { loop = true }) end end @@ -59,10 +61,12 @@ function M.init(ctx) -- Puppet rig + sprite textures + animations. local rig = puppet.load_rig("rigs/humanoid.rig.json", aliases) state.player = puppet.spawn(rig, { x = 320, y = 240 }) - local idle = puppet.load_animation("animations/idle.anim.json", rig) local walk = puppet.load_animation("animations/walk.anim.json", rig) + local walk_upper = puppet.load_animation("animations/walk_upper.anim.json", rig) + local idle = puppet.load_animation("animations/idle.anim.json", rig) puppet.register_animation(state.player, idle) puppet.register_animation(state.player, walk) + puppet.register_animation(state.player, walk_upper) puppet.play(state.player, "idle", { loop = true }) -- Furniture textures (preload to avoid first-frame load stutter). diff --git a/manifest.module b/manifest.module index 75adb8a..448afa7 100644 --- a/manifest.module +++ b/manifest.module @@ -1,6 +1,6 @@ { "id": "vagrant-skeleton", - "version": "0.2.0", + "version": "0.3.0", "kind": "module", "api": "^0.1", "ci_frames": 60, @@ -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.2.0"}, + {"id": "lib-core.puppet", "version": "^0.3.0"}, {"id": "lib-asset.prototype-subterrain", "version": "0.1.0"} ] } diff --git a/rigs/humanoid.rig.json b/rigs/humanoid.rig.json index a0471bc..f2da3d3 100644 --- a/rigs/humanoid.rig.json +++ b/rigs/humanoid.rig.json @@ -1,24 +1,36 @@ { - "id": "humanoid", - "asset_pack": "player", - "bones": [ - { "id": "root", "parent": null, "rest": {"x": 0, "y": 0, "angle": 0}, "z_order": -1 }, - { "id": "body", "parent": "root", "rest": {"x": 0, "y": 0, "angle": 0}, "z_order": 2, "texture": "body_001" }, - { "id": "head", "parent": "body", "rest": {"x": 0, "y": -16, "angle": 0}, "z_order": 6, "texture": "head_001", "look_at": true }, - { "id": "shoulders", "parent": "body", "rest": {"x": 0, "y": 0, "angle": 0}, "z_order": 5, "texture": "shoulder_001" }, - { "id": "upper_arm_l", "parent": "shoulders", "rest": {"x": -19, "y": -3, "angle": 0}, "z_order": 3, "texture": "upper_arm_001", "scale": [-1, 1] }, - { "id": "upper_arm_r", "parent": "shoulders", "rest": {"x": 19, "y": -3, "angle": 0}, "z_order": 3, "texture": "upper_arm_001", "scale": [ 1, 1] }, - { "id": "lower_arm_l", "parent": "upper_arm_l", "rest": {"x": 14, "y": -18, "angle": 0}, "z_order": 2, "texture": "lower_arm_001", "scale": [-1, 1] }, - { "id": "lower_arm_r", "parent": "upper_arm_r", "rest": {"x": 14, "y": -18, "angle": 0}, "z_order": 2, "texture": "lower_arm_001", "scale": [ 1, 1] }, - { "id": "leg_l", "parent": "body", "rest": {"x": -4, "y": 8, "angle": 0}, "z_order": 1, "texture": "leg_001" }, - { "id": "leg_r", "parent": "body", "rest": {"x": 4, "y": 8, "angle": 0}, "z_order": 1, "texture": "leg_001" }, - { "id": "foot_l", "parent": "leg_l", "rest": {"x": 0, "y": 12, "angle": 0}, "z_order": 0, "texture": "foot_001" }, - { "id": "foot_r", "parent": "leg_r", "rest": {"x": 0, "y": 12, "angle": 0}, "z_order": 0, "texture": "foot_001" } - ], - "tracks": [ - { "id": "lower", "bones": ["leg_l", "leg_r", "foot_l", "foot_r"] }, - { "id": "upper", "bones": ["root", "body", "head", "shoulders", - "upper_arm_l", "upper_arm_r", - "lower_arm_l", "lower_arm_r"] } + "id": "humanoid", + "asset_pack": "player", + "bones": [ + { "id": "root", "parent": null, "rest": {"x": 0, "y": 0, "rot": 0}, "z_order": -1 }, + { "id": "body", "parent": "root", "rest": {"x": 0, "y": 0, "rot": 0}, "z_order": 2, "texture": "body_001" }, + { "id": "head", "parent": "body", "rest": {"x": 0, "y": -3, "rot": 0}, "z_order": 6, "texture": "head_001", "look_at": true }, + { "id": "shoulders", "parent": "body", "rest": {"x": 0, "y": 0, "rot": 0}, "z_order": 5, "texture": "shoulder_001" }, + { "id": "upper_arm_l", "parent": "shoulders", "rest": {"x": -19, "y": -3, "rot": 0, "scl": [-1, 1]}, "z_order": 3, "texture": "upper_arm_001" }, + { "id": "upper_arm_r", "parent": "shoulders", "rest": {"x": 20, "y": -4, "rot": 0}, "z_order": 3, "texture": "upper_arm_001" }, + { "id": "lower_arm_l", "parent": "upper_arm_l","rest": {"x": 14, "y": -18, "rot": 0}, "z_order": 2, "texture": "lower_arm_001" }, + { "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": "root", "rest": {"x": -9, "y": 1, "rot": 0, "scl": [-1, -1]}, "z_order": 1, "texture": "leg_001" }, + { "id": "leg_r", "parent": "root", "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" } + ], + "tracks": [ + { "id": "lower", "bones": ["leg_l", "leg_r", "foot_l", "foot_r"] }, + { "id": "upper", "bones": ["root", "body", "head", "shoulders", "upper_arm_l", "upper_arm_r", "lower_arm_l", "lower_arm_r"] } + ], + "locomotion": { + "mode": "procedural", + "step_trigger": [6, 24], + "step_placement": [16, 28], + "step_duration": 0.18, + "step_height": 0, + "idle_return_delay": 0.5, + "idle_return_stagger": 0.3, + "idle_step_duration": 0.25, + "legs": [ + { "leg": "leg_l", "foot": "foot_l", "group": 0 }, + { "leg": "leg_r", "foot": "foot_r", "group": 1 } ] + } }