The small decisions good Godot programmers make automatically. Open one when a lesson makes you wonder "but why?".
_process(delta) runs once per drawn frame. That speed depends on the computer: 144 a second on a gaming monitor, 40 on a tired laptop._physics_process(delta) runs at a steady 60 ticks a second, in step with the physics engine (the part of Godot that moves bodies and checks collisions).velocity or move_and_slide(): use _physics_process()._process()._process() and movement runs on the drawing clock while walls are checked on the physics clock. They drift apart, and the player jitters into walls on someone else's computer._physics_process() is almost always the right answer.delta is how many seconds passed since the last tick. At 60 ticks a second, about 0.016.velocity.y += gravity * delta adds one second's worth of gravity, spread across the ticks that second.delta when you change something a little every tick yourself, like gravity in the platformer lessons.move_and_slide() handles delta internally, which is why the movement code never multiplies velocity by it._delta with an underscore? That means "this function receives it, but this script doesn't need it."@export var speed: float = 200.0 puts the number in Godot's Inspector.@export.z_index on the player's root node. Nearly every player in these lessons has z_index = 1, which puts it in front of everything left at the default 0, whatever the tree order.z_index is closer to you. Equal values fall back to tree order.CanvasLayer beats all of it: the HUD sits on one, which is why score and buttons never disappear behind the level.y_sort_enabled on the parent instead. It orders children by Y position every frame. A fixed z_index defeats it, which is why the Walking Behind Things lesson is the one player without one.Environment, Entities, UI.Node2D for groups that hold things you can SEE. Hiding the whole group, giving it a z_index, ticking y_sort_enabled, or sliding the whole level over are all things only a Node2D can do.Node for groups that draw nothing: timers, sound players, score keeping. A Node2D there implies a position that means nothing.CanvasLayer for UI. It ignores the camera, which is why the HUD stays pinned to the screen while the world scrolls underneath.$Player becomes $Entities/Player and any script using the old path breaks.% is for. %Player keeps working wherever you move the node, so turn on "Access as Unique Name" BEFORE you start rearranging.player.tscn. Every level places an instance of it.goal.gd to the root node inside goal.tscn. Every goal you drop into a level then knows how to be a goal, for free.goal_reached: that is what a Goal is. It belongs in goal.tscn.@export and set that value per copy, instead of writing a second script.game_events.gd, a shared announcement board any script can post to or listen to.Player, not CharacterBody2D2.$Sprite2D, and in error messages. A clear name pays off every time you read it.% in front of a name (like %ScoreLabel) means "Access as Unique Name": any script in the scene can grab it without spelling out the path.% for one-of-a-kind nodes many scripts need: the score label, a game-over panel.