feat: add CI-hooks for render-hook + state-transition smoke
Two env-var-gated hooks (no-op in normal play): - SPOREL_CI=1: emits 'vagrant: render_frame_ok' per frame from render() and 'vagrant: frame_avg_ms=N' after 60 frames. - SPOREL_VAGRANT_PHASE1_DRIVE=1: scripted move-right input on frames 21-40, idle otherwise. Combined with SPOREL_CI=1 produces observable idle -> walk -> idle state cycle. State-transition trace 'vagrant: state=<walk|idle>' emits exactly once per actual change in set_walk_or_idle, so the smoke greps don't get noise from per-frame repeats. Fix camera.set_target_provider (absent from camera API) to use camera.set_target(x, y) called per frame from M.update instead.
This commit is contained in:
34
init.lua
34
init.lua
@@ -19,8 +19,12 @@ local state = {
|
|||||||
local CI_FRAME_PERF = (os.getenv("SPOREL_CI") == "1")
|
local CI_FRAME_PERF = (os.getenv("SPOREL_CI") == "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_last_state = nil
|
||||||
|
|
||||||
local function set_walk_or_idle(moving)
|
local function set_walk_or_idle(moving)
|
||||||
|
local new_state = moving and "walk" or "idle"
|
||||||
if moving then
|
if moving then
|
||||||
if not puppet.is_playing(state.player, "walk") then
|
if not puppet.is_playing(state.player, "walk") then
|
||||||
puppet.stop(state.player, "idle")
|
puppet.stop(state.player, "idle")
|
||||||
@@ -32,6 +36,10 @@ local function set_walk_or_idle(moving)
|
|||||||
puppet.play(state.player, "idle", { loop = true })
|
puppet.play(state.player, "idle", { loop = true })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if CI_FRAME_PERF and new_state ~= ci_last_state then
|
||||||
|
engine.print("vagrant: state=" .. new_state)
|
||||||
|
ci_last_state = new_state
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.init(ctx)
|
function M.init(ctx)
|
||||||
@@ -55,10 +63,9 @@ function M.init(ctx)
|
|||||||
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 position (no manual pan in vagrant-style)
|
-- Camera follows player on first frame
|
||||||
camera.set_target_provider(function()
|
local init_pos = puppet.position(state.player)
|
||||||
return puppet.position(state.player)
|
camera.set_target(init_pos.x, init_pos.y)
|
||||||
end)
|
|
||||||
|
|
||||||
if CI_FRAME_PERF then
|
if CI_FRAME_PERF then
|
||||||
ci_t_start = engine.time.now()
|
ci_t_start = engine.time.now()
|
||||||
@@ -85,6 +92,21 @@ function M.update(ctx, dt)
|
|||||||
pos.x + dx / len * state.player_speed * dt,
|
pos.x + dx / len * state.player_speed * dt,
|
||||||
pos.y + dy / len * state.player_speed * dt)
|
pos.y + dy / len * state.player_speed * dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if CI_DRIVE then
|
||||||
|
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
|
||||||
|
dx = 1; dy = 0
|
||||||
|
moving = true
|
||||||
|
local pos = puppet.position(state.player)
|
||||||
|
puppet.move_to(state.player,
|
||||||
|
pos.x + dx * state.player_speed * dt, pos.y)
|
||||||
|
else
|
||||||
|
moving = false
|
||||||
|
end
|
||||||
|
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
|
||||||
@@ -92,6 +114,10 @@ function M.update(ctx, dt)
|
|||||||
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)
|
||||||
|
local cam_pos = puppet.position(state.player)
|
||||||
|
camera.set_target(cam_pos.x, cam_pos.y)
|
||||||
|
|
||||||
camera.update(dt)
|
camera.update(dt)
|
||||||
puppet.update(dt)
|
puppet.update(dt)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user