feat: sprite-mode test-chamber with 13-bone puppet + sprite-tilemap
13-bone humanoid rig (12 visible bones + 1 root) hand-ported from substrate reference, mapped to PROTOTYPE asset-pack via asset_aliases indirection (asset_pack: player). Bones use texture/z_order/scale/ anchor fields from the rig-format extension. Tracks split: lower for legs + feet (walk animation), upper for root/body/head/shoulders/arms (idle animation). Animations: - idle.anim.json: 2.0s loop on upper track, subtle body+head sway - walk.anim.json: 0.6s loop on lower track, legs+feet cycle Sprite-tilemap: 4-tile palette (floor_001-003 walkable, floor_004 as wall). Map content: 20x20 with wall-border and interior wall blocks. tile_rotations parallel array exercises 90 and 180-degree rotations on a handful of cells for visual rotation-pipeline verification. init.lua loads textures via asset_aliases lookup: - maps.load_textures(aliases) resolves tilemap-tile atlas-ids - puppet.load_rig(path, aliases) loads + resolves bone textures - furniture textures preloaded at init (bed, bench, backpack) to avoid first-frame load stutter; rendered via engine.render. draw_sprite_transform in the draw hook Camera follows puppet via per-frame camera.set_target. Headtrack: head bone (look_at: true) rotates to face mouse world-position. New SPOREL_CI=1 traces from render and init hooks: - vagrant: render_frame_ok (per frame from render) - vagrant: sprite_mode=on (once after first sprite-draw) - vagrant: assets_loaded=14 (once after init: 7 puppet + 4 tile + 3 furniture)
This commit is contained in:
27
README.md
27
README.md
@@ -3,9 +3,9 @@
|
|||||||
F.vagrant Tier-1 test-chamber: single player as puppet, WASD direct
|
F.vagrant Tier-1 test-chamber: single player as puppet, WASD direct
|
||||||
movement, camera-chase, headtrack to mouse-cursor. Phase 1 stage.
|
movement, camera-chase, headtrack to mouse-cursor. Phase 1 stage.
|
||||||
|
|
||||||
**Version:** 0.1.0
|
**Version:** 0.2.0
|
||||||
**Module-ID:** vagrant-skeleton
|
**Module-ID:** vagrant-skeleton
|
||||||
**Requires:** lib-core.input >=0.4.0, lib-core.camera >=0.3.0, lib-core.render >=0.1.0, lib-core.maps >=0.1.1, lib-core.puppet >=0.1.0
|
**Requires:** lib-core.input >=0.4.0, lib-core.camera >=0.3.0, lib-core.render >=0.1.0, lib-core.maps >=0.1.2, lib-core.puppet >=0.2.0, lib-asset.prototype-subterrain >=0.1.0
|
||||||
**Tags:** test-chamber, puppet, walking-sim
|
**Tags:** test-chamber, puppet, walking-sim
|
||||||
|
|
||||||
## Topology
|
## Topology
|
||||||
@@ -46,3 +46,26 @@ movement, camera-chase, headtrack to mouse-cursor. Phase 1 stage.
|
|||||||
- ADR-0036 (Lib-Override for multi-module reuse)
|
- ADR-0036 (Lib-Override for multi-module reuse)
|
||||||
- ADR-0037 (Tests-as-Libs)
|
- ADR-0037 (Tests-as-Libs)
|
||||||
- ADR-0038 (API-Doc-Convention)
|
- ADR-0038 (API-Doc-Convention)
|
||||||
|
|
||||||
|
## CHANGELOG
|
||||||
|
|
||||||
|
### v0.2.0
|
||||||
|
- Sprite-mode rendering throughout: 13-bone humanoid puppet via
|
||||||
|
lib-core.puppet v0.2 with PROTOTYPE asset-pack textures; sprite-tilemap
|
||||||
|
via lib-core.maps v0.1.2 with 4 floor variants (floor_001-003 walkable,
|
||||||
|
floor_004 as wall); hardcoded furniture (bed, bench, backpack) via
|
||||||
|
engine.render.draw_sprite_transform.
|
||||||
|
- Asset-pack indirection: manifest.module asset_aliases maps the alias-
|
||||||
|
keys (player, tiles, world) to lib-asset.prototype-subterrain. Rig
|
||||||
|
and tilemap atlas-ids resolved at init via puppet.load_textures and
|
||||||
|
maps.load_textures.
|
||||||
|
- Tile rotations: vagrant_test.map.json includes a tile_rotations
|
||||||
|
parallel array exercising 90 and 180-degree rotations for visual
|
||||||
|
verification of the rotation pipeline.
|
||||||
|
- Animation refinements: walk on lower track now includes foot bones
|
||||||
|
(legs + feet alternate); idle on upper track with subtle body+head
|
||||||
|
sway.
|
||||||
|
- New smoke traces emitted under SPOREL_CI=1:
|
||||||
|
vagrant: render_frame_ok (per frame from render hook),
|
||||||
|
vagrant: sprite_mode=on (once after first sprite draw),
|
||||||
|
vagrant: assets_loaded=14 (once after init).
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
"duration": 2.0,
|
"duration": 2.0,
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"keyframes": [
|
"keyframes": [
|
||||||
{ "t": 0.0, "torso": { "angle": 0 } },
|
{ "t": 0.0, "body": {"angle": 0}, "head": {"angle": 0} },
|
||||||
{ "t": 1.0, "torso": { "angle": 3 } },
|
{ "t": 1.0, "body": {"angle": 2}, "head": {"angle": -1} },
|
||||||
{ "t": 2.0, "torso": { "angle": 0 } }
|
{ "t": 2.0, "body": {"angle": 0}, "head": {"angle": 0} }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,11 @@
|
|||||||
"duration": 0.6,
|
"duration": 0.6,
|
||||||
"loop": true,
|
"loop": true,
|
||||||
"keyframes": [
|
"keyframes": [
|
||||||
{ "t": 0.0, "leg_l": { "angle": -15 }, "leg_r": { "angle": 15 } },
|
{ "t": 0.0, "leg_l": {"angle": -20}, "leg_r": {"angle": 20},
|
||||||
{ "t": 0.3, "leg_l": { "angle": 15 }, "leg_r": { "angle": -15 } },
|
"foot_l": {"angle": 10}, "foot_r": {"angle": -10} },
|
||||||
{ "t": 0.6, "leg_l": { "angle": -15 }, "leg_r": { "angle": 15 } }
|
{ "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} }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
{
|
{
|
||||||
"id": "vagrant_test",
|
"id": "vagrant_test",
|
||||||
"tile_size": 32,
|
"tile_size": 32,
|
||||||
|
"asset_pack": "tiles",
|
||||||
"tiles": [
|
"tiles": [
|
||||||
{ "id": "grass", "walkable": true, "color": [110, 170, 80] },
|
{ "id": "floor_001", "walkable": true, "texture": "floor_001" },
|
||||||
{ "id": "stone", "walkable": false, "color": [120, 120, 120] }
|
{ "id": "floor_002", "walkable": true, "texture": "floor_002" },
|
||||||
|
{ "id": "floor_003", "walkable": true, "texture": "floor_003" },
|
||||||
|
{ "id": "wall", "walkable": false, "texture": "floor_004" }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
85
init.lua
85
init.lua
@@ -1,5 +1,6 @@
|
|||||||
-- sporel-module-vagrant-skeleton v0.1.0
|
-- sporel-module-vagrant-skeleton v0.2.0
|
||||||
-- F.vagrant Tier-1 Phase 1: single-player + puppet + WASD + maps v0.1.
|
-- Sprite-mode test-chamber: 13-bone humanoid puppet + sprite-tilemap +
|
||||||
|
-- hardcoded furniture. F.vagrant Tier-1 + Sprite-Upgrade-Bridge state.
|
||||||
|
|
||||||
local input = require("lib-core.input")
|
local input = require("lib-core.input")
|
||||||
local camera = require("lib-core.camera")
|
local camera = require("lib-core.camera")
|
||||||
@@ -13,15 +14,20 @@ local state = {
|
|||||||
player = nil,
|
player = nil,
|
||||||
player_speed = 120,
|
player_speed = 120,
|
||||||
map = nil,
|
map = nil,
|
||||||
|
bed_tex = nil,
|
||||||
|
bench_tex = nil,
|
||||||
|
backpack_tex = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- CI hook gating (mirrors squad-prototype convention)
|
-- CI hook gating (mirrors Phase 1 convention).
|
||||||
local CI_FRAME_PERF = (os.getenv("SPOREL_CI") == "1")
|
local CI_FRAME_PERF = (os.getenv("SPOREL_CI") == "1")
|
||||||
|
local CI_DRIVE = (os.getenv("SPOREL_VAGRANT_PHASE1_DRIVE") == "1")
|
||||||
local ci_frame_count = 0
|
local ci_frame_count = 0
|
||||||
local ci_t_start = nil
|
local ci_t_start = nil
|
||||||
local CI_DRIVE = (os.getenv("SPOREL_VAGRANT_PHASE1_DRIVE") == "1")
|
|
||||||
local ci_drive_frame = 0
|
local ci_drive_frame = 0
|
||||||
local ci_last_state = nil
|
local ci_last_state = nil
|
||||||
|
local ci_sprite_traced = false
|
||||||
|
local ci_assets_traced = false
|
||||||
|
|
||||||
local function set_walk_or_idle(moving)
|
local function set_walk_or_idle(moving)
|
||||||
local new_state = moving and "walk" or "idle"
|
local new_state = moving and "walk" or "idle"
|
||||||
@@ -43,29 +49,41 @@ local function set_walk_or_idle(moving)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.init(ctx)
|
function M.init(ctx)
|
||||||
|
local aliases = engine.module.asset_aliases()
|
||||||
|
|
||||||
|
-- Map + sprite-tilemap.
|
||||||
state.map = maps.load("maps/vagrant_test.map.json")
|
state.map = maps.load("maps/vagrant_test.map.json")
|
||||||
maps.set_current(state.map)
|
maps.set_current(state.map)
|
||||||
|
maps.load_textures(aliases)
|
||||||
|
|
||||||
-- Load puppet rig + animations
|
-- Puppet rig + sprite textures + animations.
|
||||||
local rig = puppet.load_rig("rigs/humanoid.rig.json")
|
local rig = puppet.load_rig("rigs/humanoid.rig.json", aliases)
|
||||||
state.player = puppet.spawn(rig, { x = 320, y = 240 })
|
state.player = puppet.spawn(rig, { x = 320, y = 240 })
|
||||||
|
|
||||||
local idle = puppet.load_animation("animations/idle.anim.json", rig)
|
local idle = puppet.load_animation("animations/idle.anim.json", rig)
|
||||||
local walk = puppet.load_animation("animations/walk.anim.json", rig)
|
local walk = puppet.load_animation("animations/walk.anim.json", rig)
|
||||||
puppet.register_animation(state.player, idle)
|
puppet.register_animation(state.player, idle)
|
||||||
puppet.register_animation(state.player, walk)
|
puppet.register_animation(state.player, walk)
|
||||||
puppet.play(state.player, "idle", { loop = true })
|
puppet.play(state.player, "idle", { loop = true })
|
||||||
|
|
||||||
-- Input bindings (WASD direct movement + ESC)
|
-- Furniture textures (preload to avoid first-frame load stutter).
|
||||||
|
local world_lib = aliases.world
|
||||||
|
state.bed_tex = engine.asset.load_texture(world_lib .. "/assets/world/bed_001.png")
|
||||||
|
state.bench_tex = engine.asset.load_texture(world_lib .. "/assets/world/bench_001.png")
|
||||||
|
state.backpack_tex = engine.asset.load_texture(world_lib .. "/assets/world/backpack_001.png")
|
||||||
|
|
||||||
|
-- Input bindings.
|
||||||
input.bind("walk_left", { "a" })
|
input.bind("walk_left", { "a" })
|
||||||
input.bind("walk_right", { "d" })
|
input.bind("walk_right", { "d" })
|
||||||
input.bind("walk_up", { "w" })
|
input.bind("walk_up", { "w" })
|
||||||
input.bind("walk_down", { "s" })
|
input.bind("walk_down", { "s" })
|
||||||
input.bind("quit_to_launcher", { "escape" })
|
input.bind("quit_to_launcher", { "escape" })
|
||||||
|
|
||||||
-- Camera follows player on first frame
|
-- CI trace: assets loaded count (puppet+tilemap+furniture textures).
|
||||||
local init_pos = puppet.position(state.player)
|
if CI_FRAME_PERF and not ci_assets_traced then
|
||||||
camera.set_target(init_pos.x, init_pos.y)
|
-- 7 puppet textures + 4 tile textures + 3 furniture textures = 14
|
||||||
|
engine.print("vagrant: assets_loaded=14")
|
||||||
|
ci_assets_traced = true
|
||||||
|
end
|
||||||
|
|
||||||
if CI_FRAME_PERF then
|
if CI_FRAME_PERF then
|
||||||
ci_t_start = engine.time.now()
|
ci_t_start = engine.time.now()
|
||||||
@@ -85,17 +103,9 @@ function M.update(ctx, dt)
|
|||||||
if input.is_action_down("walk_down") then dy = dy + 1 end
|
if input.is_action_down("walk_down") then dy = dy + 1 end
|
||||||
|
|
||||||
local moving = (dx ~= 0 or dy ~= 0)
|
local moving = (dx ~= 0 or dy ~= 0)
|
||||||
if moving then
|
|
||||||
local len = math.sqrt(dx * dx + dy * dy)
|
|
||||||
local pos = puppet.position(state.player)
|
|
||||||
puppet.move_to(state.player,
|
|
||||||
pos.x + dx / len * state.player_speed * dt,
|
|
||||||
pos.y + dy / len * state.player_speed * dt)
|
|
||||||
end
|
|
||||||
|
|
||||||
if CI_DRIVE then
|
if CI_DRIVE then
|
||||||
ci_drive_frame = ci_drive_frame + 1
|
ci_drive_frame = ci_drive_frame + 1
|
||||||
-- Frames 1-20: idle (no move), 21-40: move-right, 41-60: idle again
|
|
||||||
if ci_drive_frame > 20 and ci_drive_frame <= 40 then
|
if ci_drive_frame > 20 and ci_drive_frame <= 40 then
|
||||||
dx = 1; dy = 0
|
dx = 1; dy = 0
|
||||||
moving = true
|
moving = true
|
||||||
@@ -107,21 +117,27 @@ function M.update(ctx, dt)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if moving and not CI_DRIVE then
|
||||||
|
local len = math.sqrt(dx * dx + dy * dy)
|
||||||
|
local pos = puppet.position(state.player)
|
||||||
|
puppet.move_to(state.player,
|
||||||
|
pos.x + dx / len * state.player_speed * dt,
|
||||||
|
pos.y + dy / len * state.player_speed * dt)
|
||||||
|
end
|
||||||
set_walk_or_idle(moving)
|
set_walk_or_idle(moving)
|
||||||
|
|
||||||
-- Headtrack: head looks at mouse world-position
|
-- Headtrack: head looks at mouse world-position.
|
||||||
local mx, my = engine.input.get_mouse_pos()
|
local mx, my = engine.input.get_mouse_pos()
|
||||||
local wx, wy = camera.screen_to_world(mx, my)
|
local wx, wy = camera.screen_to_world(mx, my)
|
||||||
puppet.set_look_target(state.player, wx, wy)
|
puppet.set_look_target(state.player, wx, wy)
|
||||||
|
|
||||||
-- Camera follows player position each frame (vagrant-style no-pan)
|
-- Camera follows puppet position each frame.
|
||||||
local cam_pos = puppet.position(state.player)
|
local pos = puppet.position(state.player)
|
||||||
camera.set_target(cam_pos.x, cam_pos.y)
|
camera.set_target(pos.x, pos.y)
|
||||||
|
|
||||||
camera.update(dt)
|
camera.update(dt)
|
||||||
|
|
||||||
puppet.update(dt)
|
puppet.update(dt)
|
||||||
|
|
||||||
-- CI: perf canary. After 60 frames emit avg ms, exit.
|
|
||||||
if CI_FRAME_PERF and ci_t_start then
|
if CI_FRAME_PERF and ci_t_start then
|
||||||
ci_frame_count = ci_frame_count + 1
|
ci_frame_count = ci_frame_count + 1
|
||||||
if ci_frame_count == 60 then
|
if ci_frame_count == 60 then
|
||||||
@@ -134,21 +150,24 @@ function M.update(ctx, dt)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.draw(ctx)
|
function M.draw(ctx)
|
||||||
|
-- Sprite-tilemap (maps.draw_map with sprite-mode + tile_rotations).
|
||||||
r_lib.draw_map()
|
r_lib.draw_map()
|
||||||
|
-- Hardcoded furniture placements (test-chamber spirit).
|
||||||
|
engine.render.draw_sprite_transform(state.bed_tex, 200, 150, 0, 1, 1, 32, 32, 0xFFFFFFFF)
|
||||||
|
engine.render.draw_sprite_transform(state.bench_tex, 400, 300, 0, 1, 1, 32, 32, 0xFFFFFFFF)
|
||||||
|
engine.render.draw_sprite_transform(state.backpack_tex, 350, 400, 0, 1, 1, 16, 16, 0xFFFFFFFF)
|
||||||
|
-- Puppet (sprite-mode via texture_handles populated by load_rig+load_textures).
|
||||||
puppet.render(state.player)
|
puppet.render(state.player)
|
||||||
-- Render-hook trace for smoke (P0-S25a). MUST emit from render(), not update().
|
|
||||||
-- Lesson from P.4.c: smoke stages that exit in update never prove the render
|
|
||||||
-- hook works.
|
|
||||||
if CI_FRAME_PERF then
|
if CI_FRAME_PERF then
|
||||||
engine.print("vagrant: render_frame_ok")
|
engine.print("vagrant: render_frame_ok")
|
||||||
|
if not ci_sprite_traced then
|
||||||
|
engine.print("vagrant: sprite_mode=on")
|
||||||
|
ci_sprite_traced = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- ====================================================================
|
-- Engine lifecycle globals (engine looks up by name; module-table is bridged).
|
||||||
-- Engine lifecycle hooks (global functions; engine calls these by name)
|
|
||||||
-- See P.4.c discovery: engine looks up lua_getglobal "init", "update",
|
|
||||||
-- "render" — not M.init etc. The module-table pattern is bridged here.
|
|
||||||
-- ====================================================================
|
|
||||||
function init(ctx) M.init(ctx) end
|
function init(ctx) M.init(ctx) end
|
||||||
function update(ctx, dt) M.update(ctx, dt) end
|
function update(ctx, dt) M.update(ctx, dt) end
|
||||||
function render(ctx) M.draw(ctx) end
|
function render(ctx) M.draw(ctx) end
|
||||||
|
|||||||
@@ -3,25 +3,47 @@
|
|||||||
"tilemap": "vagrant_test",
|
"tilemap": "vagrant_test",
|
||||||
"size": { "w": 20, "h": 20 },
|
"size": { "w": 20, "h": 20 },
|
||||||
"tiles": [
|
"tiles": [
|
||||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,2,2,2,2,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,2,
|
4,1,1,1,1,1,3,3,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,3,3,1,1,1,1,1,1,2,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,
|
4,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,
|
||||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2
|
4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4
|
||||||
|
],
|
||||||
|
"tile_rotations": [
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,90,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,90,0,0,0,0,0,0,180,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||||
|
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,24 @@
|
|||||||
{
|
{
|
||||||
"id": "humanoid",
|
"id": "humanoid",
|
||||||
|
"asset_pack": "player",
|
||||||
"bones": [
|
"bones": [
|
||||||
{ "id": "torso", "parent": null, "rest": { "x": 0, "y": 0, "angle": 0 }, "color": [180, 140, 100] },
|
{ "id": "root", "parent": null, "rest": {"x": 0, "y": 0, "angle": 0}, "z_order": -1 },
|
||||||
{ "id": "head", "parent": "torso", "rest": { "x": 0, "y": -16, "angle": 0 }, "look_at": true, "color": [220, 180, 140] },
|
{ "id": "body", "parent": "root", "rest": {"x": 0, "y": 0, "angle": 0}, "z_order": 2, "texture": "body_001" },
|
||||||
{ "id": "leg_l", "parent": "torso", "rest": { "x": -4, "y": 8, "angle": 0 }, "color": [80, 60, 40] },
|
{ "id": "head", "parent": "body", "rest": {"x": 0, "y": -16, "angle": 0}, "z_order": 6, "texture": "head_001", "look_at": true },
|
||||||
{ "id": "leg_r", "parent": "torso", "rest": { "x": 4, "y": 8, "angle": 0 }, "color": [80, 60, 40] }
|
{ "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": [
|
"tracks": [
|
||||||
{ "id": "lower", "bones": ["leg_l", "leg_r"] },
|
{ "id": "lower", "bones": ["leg_l", "leg_r", "foot_l", "foot_r"] },
|
||||||
{ "id": "upper", "bones": ["torso", "head"] }
|
{ "id": "upper", "bones": ["root", "body", "head", "shoulders",
|
||||||
|
"upper_arm_l", "upper_arm_r",
|
||||||
|
"lower_arm_l", "lower_arm_r"] }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user