1.8 KiB
1.8 KiB
| id | name | category | kind | tokens | sig | tip | order |
|---|---|---|---|---|---|---|---|
| phase-update | Update | phases | phase | Update | phase Update | The ordinary per-frame game-logic step, run after Input and FixedUpdate. | 3 |
Update is the everyday game-logic phase, run each frame after Input and FixedUpdate and before LateUpdate and Render. It is where most gameplay lives when you are not being strict about determinism: spawn waves on a timer, apply the intent that Input recorded, check win/lose conditions, advance animations. Reach for Update by default and reserve FixedUpdate for the simulation you specifically want reproducible. Because it runs after Input, the current frame's key press is already reflected in your program vars by the time Update reads them.
program UpdateExample {
property Position { column: int = 0, row: int = 0 }
model Enemy { Position }
const GRID_WIDTH: int = 20
state UpdateExampleState {
elapsed_frames: int = 0
score: int = 0
}
handler SpawnWave(update_example_st: mut UpdateExampleState) phase Update {
update_example_st.elapsed_frames = update_example_st.elapsed_frames + 1
if update_example_st.elapsed_frames % 30 == 0 {
let spawn_column = Random.range(low: 0, high: GRID_WIDTH - 1)
spawn Enemy { Position { column: spawn_column, row: 0 } }
update_example_st.score = update_example_st.score + 1
}
}
handler DrawWorld(update_example_st: UpdateExampleState) phase Render {
Screen.clear(Color.MidnightBlue)
for (current_position) in query [Position, {Enemy}] {
Screen.fill_rectangle(x: current_position.column * 16, y: current_position.row * 16, width: 16, height: 16, color: Color.Crimson)
}
Screen.draw_number(x: 4, y: 4, value: update_example_st.score, color: Color.Gold, scale: 1)
Screen.show()
}
}