# Understand Godot scenes and state through a small game loop

Canonical page: https://yishto.com/en/learn/application-platforms/godot-small-game-loop/

Author: [Yishto](https://yishto.com/en/about/)

Build a square-collection exercise around Godot scenes, input actions, physics updates, and game state, checking pause behavior, repeated collisions, and restart cleanup.

Published: 2026-11-10
Updated: 2026-11-10

A square-collection exercise has a movable player, several targets, and a score. Restart returns the player to its starting position, recreates targets, and resets scoring. This scope exposes the game loop, scene instances, and collision events without requiring complex artwork.

Use independently made geometric shapes rather than the official starter game's characters, levels, or assets. Begin with a top-down 2D exercise without enemies, leaderboards, or networking. Teaching values do not establish game feel or performance.

## Organize scenes and round data

Godot scenes combine nodes and can be instantiated after saving. The main scene owns a round, a player scene handles movement, target scenes emit collection events, and UI displays score and controls. Node names are not unique business identities; targets need distinct IDs.

Use playing, paused, and ended states. The round controller owns score and remaining targets. Restart establishes a new round identity, allowing late signals from old nodes to be rejected rather than increasing the new score.

Targets are available or collected. Mark a target collected before emitting its event and scheduling removal. Collision callbacks can repeat, and deferred removal alone does not prevent double scoring.

## Separate input intent from movement

Define directional and pause actions in the project input map. Read actions rather than hardcoded key strings so keyboard, controller, and touch mappings can share movement intent.

`_process` runs with varying frame intervals, while physics has its own fixed scheduling. Rate-based displacement uses elapsed time, but physics APIs have specific units. Do not multiply a velocity by delta and then pass it to an API that already handles timing.

Choose physics nodes and APIs for collision. Visible graphics and collision shapes are separate; a displayed square is not automatically collidable. Normalize or limit diagonal input so combining axes does not create unintended faster movement.

## Build the project in the editor

Create a Godot 4 2D project and record its version and rendering settings. Add a main scene, player, target container, and UI. A CharacterBody2D with a graphic and CollisionShape2D can represent the player. An Area2D with its own graphic and shape can represent a target. Set layers and masks to detect the player deliberately.

Start with one target. Configure input, update velocity in the physics callback, and use the documented movement method. Check the installed version's `move_and_slide` semantics. Run the current scene to inspect movement, then set the main scene as the project entry.

Connect target collection signals to the round controller. Track remaining IDs, score, and completion, and derive UI from those states. Add pause and restart last. Restart stops the old round, recreates targets, and resets the player. This Godot project has not been run here; the reader must edit, execute, and debug these steps.

## Check rate calculations offline

The Python example sums constant velocity multiplied by time intervals. Both interval sets total one second and produce the same distance. Paused state prevents movement. It implements no Godot scheduling, collision, physics engine, or actual input.

```python
def distance(velocity, steps):
    return sum(velocity*delta for delta in steps)
assert abs(distance(10, [0.1]*10)-10) < 1e-9
assert abs(distance(10, [0.25]*4)-10) < 1e-9
state = "paused"
def tick(position, delta):
    return position if state != "playing" else position + 10*delta
assert tick(0, 0.1) == 0
print(round(distance(10, [0.1]*10), 2))
```

The output is `10.0`. Assertions compare ten 0.1-second steps with four 0.25-second steps and verify pause behavior. Floating-point comparison uses tolerance. This does not prove complex collision behavior is identical at every frame rate.

Test physical movement separately from UI animation. Window load should not change the intended speed contract, but actual collision and scheduling can vary. Performance conclusions need a stated scene, device, version, and measurements rather than a model distance.

## Handle pause, completion, and restart

Choose which nodes continue while paused. Movement stops while menus remain interactive. Configure node process modes and the installed engine's pause mechanism rather than merely hiding the player. Ended state refuses further collection and offers restart.

Stop old events before releasing nodes and creating a new round. Reset connections, score, time, and target sets. Repeated connections can double-score one event. Avoid carrying references to freed nodes across rounds.

Test holding a direction through pause and resume. Whether movement resumes immediately is a product decision. Keep target positions away from the starting player and use deterministic layouts for reproducible checks.

## Extend graphics deliberately

Pixel art requires resolution, filtering, and scaling decisions. Other 2D graphics still need camera and coordinate design. Moving to 3D changes camera, lighting, spatial input, and collision; replacing pictures does not perform that work.

Check asset rights when using generated images, and debug generated code. Collision shapes follow gameplay needs rather than necessarily copying every visual pixel. Verify entry scenes and resource paths during export; editor success does not prove a complete installed artifact.


Express scoring as a state transition on target IDs: only a playing round with an uncollected ID can remove it and increase score. Route keyboard and button restarts through the same controller path.

Add boundary walls and varied target positions to test movement limits. Resize the window and check readable UI and reachable pause controls. Inspect input maps, collision layers, imported resources, and path capitalization before export. Record deterministic coordinates for reproduction. Random layouts need a fixed test seed or retained generated positions.

## Exercise: make restart reproducible

Use three target IDs, scoring each once and ending after all are collected. Test standing on a target, paused input, repeated restart clicks, and late old-round events. Score must neither duplicate nor carry across rounds.

Change model time steps and inspect actual engine movement separately. Export to the target desktop environment and test entry, input, and assets. Record that Python checks constant-rate arithmetic while engine execution verifies scenes, collisions, and reset behavior. Add sound and further levels afterward.

## Sources & further reading

- [Godot scenes and nodes](https://docs.godotengine.org/en/stable/getting_started/step_by_step/nodes_and_scenes.html)
- [A first 2D game](https://docs.godotengine.org/en/stable/getting_started/first_2d_game/index.html)

Sources checked on 2026-11-10. Examples are teaching data, not production measurements.

## Related guides

- [Learn algorithms and data structures through lookup tasks](https://yishto.com/en/learn/computing/algorithms-and-data-structures/)
- [Prepare graphics, motion, and assets for a product](https://yishto.com/en/learn/web-interface/graphics-assets-and-motion/)
