Skip to content

Main Scene & Run Target

What you'll learn

  • What a Godot scene is on disk and in the editor, and how the .tscn file relates to the in-memory node tree.
  • Why the root node of a UI-only scene is CanvasLayer rather than Node2D, Control, or plain Node.
  • How the engine decides which scene F5 launches, via the run/main_scene setting and Godot 4.6's UID addressing.
  • The difference between the editor window and the game window — and why F5 produces a brand-new window instead of replacing the editor view.

How it applies

  • The save-system grounding. Every save file the game writes (M7 onward) records the player's progress against the current main scene. Picking the main scene early — and not reshuffling it — is what keeps save files compatible across the project's lifespan. Players returning after a long absence expect their save to load; a relocated main scene breaks that contract silently.
  • Streamer launch flow. When a streamer F5s the game from inside the editor, OBS captures the new game window directly. There is no separate launcher, no Steam shim, nothing between the editor and the player-visible window. This shapes a streamer's recording setup; tutorials that show "open Godot, hit F5" map one-to-one to "open the recording, see the game."
  • Crash diagnostics for shipped builds. If the main-scene UID is unresolvable at runtime — because the file was deleted, renamed without UID propagation, or excluded from an export preset — Godot prints a specific error pointing at project.godot. QA hitting that error knows exactly which line to inspect, instead of chasing a vague "won't launch" report.
  • Scene-switching architecture. Later modules will need to load other scenes — a settings popup, a prestige ceremony, an upgrade panel that swaps in. All of those load on top of or in place of the main scene. The main scene is the player's home base; choosing the right one (and the right root node type) sets the rules for every later swap.
  • QA repro speed. A bug report says "the game crashes on launch." The tester opens the project, hits F5. The bug either reproduces (and they have the running game window plus the editor's debug panel side-by-side) or it doesn't (suggesting environment, not code). Without a configured main scene, F5 fails before the reproduction even starts — so the project always ships with one configured.
  • Source-control resilience. Godot 4.6's UID addressing means that renaming scenes/main.tscn to scenes/home.tscn does not break run/main_scene — the uid://... reference resolves through the .uid sidecar file. Teams that frequently restructure scene folders get this benefit for free; teams on Godot 3 (which used raw res:// paths) had to manually update project.godot every rename.

Concepts

What a scene is

In Godot, a scene is a tree of nodes treated as a single unit. The tree might be one node (a lone Label) or hundreds (an entire boss-fight arena with enemies, projectiles, particle emitters). What they share is parent/child structure, a single root node at the top, and one on-disk file ending in .tscn that stores the whole composition.

The file is plain text. Open main.tscn in Notepad and you see a header, a list of nodes with their types, and the property values that differ from the engine defaults. The text format makes diffs in source control readable — a one-pixel anchor change is one line of +/-, not a binary blob.

A scene becomes the running game by being instantiated — the engine reads the file, allocates the node objects in memory, hooks up children to parents, and inserts the result into the active scene tree. The same .tscn file can be instantiated multiple times (a UI panel scene used in three different menus is one file, three live trees).

Example

You will create scenes/main.tscn with one node in this chapter — a single CanvasLayer. Open the file in any text editor afterward. The body is roughly:

[gd_scene format=3]

[node name="CanvasLayer" type="CanvasLayer"]

Two lines of meaningful content for one node. As you add MainLayout, TopBar, ContentArea, StatusBar in M1.4, the file grows to ~12 lines. By M5 it might be 80 lines. Still text, still diffable, still one file.

Picking the root nodeCanvasLayer vs the alternatives

Every scene needs a root, and the type of the root is the most consequential decision in the file. The root's type sets the rendering and layout context for every descendant. A descendant of Node2D lives in 2D world space; a descendant of Control lives in UI/anchor space; a descendant of CanvasLayer renders on a separate layer above the rest.

The four candidates and what they imply for an idle-game main scene:

  • Node — atomic, no render context, no transform. Useful as a parent for non-visual logic (timers, an event bus). The wrong choice for the root of a player-visible scene because nothing under it would render — Control children, for example, need an ancestor that establishes a CanvasItem context.
  • Node2D — 2D world space with position, rotation, scale. The right choice for a sprite-based platformer where a Camera2D pans across a level. Wrong for a UI-only idle game: Control children laid out by anchors would technically render, but they would be parented to a moving world transform, fighting the layout system every time the camera moved.
  • Control — the UI base class. Anchors, margins, focus, theme. Acceptable as a scene root for UI-heavy projects; everything just works. The drawback: you lose the layer separation that lets later modules paint world art (a parallax background, particle effects) underneath the UI without restructuring the tree.
  • CanvasLayer — a render-layer separator. Children draw on a dedicated canvas with their own transform, above or below the default. The recommended root for UI scenes that may eventually want world art beneath the UI. Adding a parallax background later means adding a sibling CanvasLayer with a lower layer value; nothing about the UI subtree has to change.

For Blood Knight Grove the choice is CanvasLayer. The project might never grow a world layer, but choosing CanvasLayer now costs nothing and reserves the option.

Example

A Godot 4 platformer game would typically have a Node2D root for the level (with the player, enemies, a TileMap, a Camera2D), and a separate CanvasLayer somewhere in the tree for the HUD that overlays it. The HUD's CanvasLayer ignores the Camera2D's pan and zoom — that is the whole point. An idle game inverts the proportions: the CanvasLayer is the main thing, and there may or may not be a Node2D world layer underneath it.

Example

A common confusion: people sometimes pick Control for a UI-only project because "this is a UI." It works. The penalty surfaces only when M5 or M6 wants to add a low-key animated background — at which point the existing Control root has no layer-separation hook, and the workaround is restructuring or fighting the parent transform. Pick CanvasLayer once, do not revisit.

Saving the scene to disk

A scene exists in three places at any moment: in the editor's Scene dock (the panel showing the tree), in memory inside the editor process, and on disk as a .tscn file. The third one only exists after you save. Saving is Ctrl+S (or Scene → Save Scene). The first save prompts for a path; subsequent saves overwrite silently.

The path you pick at the first save is the one M1.2's folder layout starts paying off. scenes/main.tscn is the only sensible answer — it lands in the scenes/ folder you created, and the slug main is short enough to type in code references.

Two useful side effects of the save:

  • A .uid sidecar file is written next to the .tscn. This is the UID addressing mechanism described in M1.2. The UID inside (uid://6uh2wvpq3y6r or similar) is what the project will use to reference this scene from project.godot and from any code that loads it.
  • The Scene dock title (top of the dock) drops the asterisk that indicates unsaved changes. If you ever wonder "did I save?", check for the asterisk.

Example

You make a series of edits, hit Ctrl+S twice in quick succession out of habit. The first save writes the file; the second save no-ops because nothing has changed. The asterisk-check is the most reliable signal: no asterisk = saved, asterisk present = unsaved.

Setting the main scene

project.godot has a single field, run/main_scene, that names the scene the engine launches when the player (or developer hitting F5) starts the game. The setting is exposed in the editor at Project → Project Settings → Application → Run → Main Scene. It defaults to empty; until set, F5 prints "No main scene defined" and refuses to launch.

In Godot 4.6 the field accepts either a res:// path or a uid:// reference; the dialog produces a uid:// by default, which is what survives later renames. The field is also picker-driven: clicking the folder icon opens a file dialog, and selecting scenes/main.tscn writes the corresponding UID into the field.

Example

After setting the main scene, open project.godot in a text editor. There is a new line:

[application]
run/main_scene="uid://6uh2wvpq3y6r"

The actual UID will differ — it is generated when the .tscn is first saved. The point is the value is stable: rename main.tscn to home.tscn and the UID stays, so this line stays correct without editing.

F5, the editor window, and the game window

F5 is the engine's "play project" shortcut. It instantiates the main scene into a brand-new window — the game window — separate from the editor window. The editor stays open. Closing the game window with Alt+F4 or the X button stops the play session; the editor remains.

This separation matters for two reasons. First: you can edit code in the editor, F5 to launch, observe a bug in the game window, close the game, fix the code, F5 again. The editor never restarts; only the game does. Second: errors at runtime print into the editor's Output and Debugger panels, not into the game window itself. A learner who looks for an error message in the game window finds nothing; the editor window has the trace.

Example

You hit F5 with no main scene set. A modal pops up in the editor window saying "No main scene defined." No game window opens. The fix is to either set the main scene (the rest of this chapter) or to dismiss and use F6 (Play Current Scene) — which launches whatever scene is open in the editor without setting it as the persistent main scene.

Example

You hit F5 with the main scene set, the game window opens, you click in it, the game crashes. The game window vanishes. In the editor's Output panel at the bottom, a red traceback appears — file, line, error type. The traceback is the first thing to read; it almost always points at the bug directly.

Walkthrough

You will perform these in your own Godot editor, with the godot-idle-learning project open and the four top-level folders from M1.2 in place.

  1. In the FileSystem dock, click on scenes/ so it is selected. (This will determine the default save location for the new scene.)
  2. From the top menu bar, choose Scene → New Scene. The Scene dock (top-left by default) shows a placeholder labeled "Create root node:" with several large buttons.
  3. Click Other Node. A "Create New Node" search dialog opens.
  4. Type CanvasLayer in the search field. The list filters to one entry; double-click it (or select and click Create). The Scene dock now shows a single CanvasLayer node, with no children.
  5. Press Ctrl+S (or Scene → Save Scene). The save dialog opens at res://scenes/. Type main.tscn as the filename and click Save. The dock title changes from "[unsaved]" to "main"; an asterisk before the name disappears.
  6. Confirm two files now exist under scenes/ in the FileSystem dock: main.tscn and main.tscn.uid. The .uid is a tiny sidecar with the stable identifier for the scene.
  7. Open Project → Project Settings…. In the left tree, expand Application → click Run. The right pane shows several fields including Main Scene.
  8. Click the folder icon to the right of the Main Scene field. A file picker opens. Navigate to res://scenes/main.tscn and select it. The field populates with the scene's uid:// reference.
  9. Click Close on the Project Settings dialog. The setting is persisted to project.godot.
  10. Press F5 to launch the game. A blank window appears at 1280×720 (your base resolution from M1.1). The window is empty — the only node in main.tscn is a CanvasLayer, which has no rendered children.
  11. Close the game window. The editor window is still open and exactly as you left it.

The blank window is uneventful, but it is the first time your project has run. Press F5 a second time if you want to see the launch flow again — empty window, then close, then back to the editor. M1.4 fills the window with the three regions the rest of the textbook will populate; M2.1 puts the first interactive element inside one of them.

Optional sanity check. Open project.godot in a text editor (outside Godot). Find the [application] section. There should be a line like run/main_scene="uid://...". The actual UID will be unique to your scene save. If the line is missing or empty, return to Project Settings and re-set Main Scene.

Self-check quiz

Q1 — A .tscn file on disk contains:

A. A binary serialization of every node, property, and asset in the scene — opening it in a text editor shows garbage characters. B. A plain-text description of the node tree, with the root and each child listed by type, and only the property values that differ from engine defaults. C. A pointer to a parallel .tscn.bin file that holds the actual scene data; the .tscn is just a stub. D. The full GDScript source of every script attached to the scene's nodes.

Reveal answer

B — plain text, defaults omitted. Godot's text-format scenes (the .tscn extension) are diff-friendly precisely because of this: the on-disk representation is human-readable and only stores deltas from defaults. A is wrong because Godot also has a binary format (.scn) used at export time for size/load-speed reasons, but .tscn is text. C is invented — there is no .tscn.bin companion file. D is wrong: scripts live in their own .gd files and are referenced from the scene, not embedded.

Q2 — Why does Blood Knight Grove use CanvasLayer as the root of main.tscn instead of Control?

A. Because Control cannot have children — it is a leaf-only class. B. Because Control would prevent the game from launching with F5. C. Because CanvasLayer reserves the option of adding a sibling render layer underneath the UI later (e.g., a parallax background) without restructuring the tree. D. Because CanvasLayer is required for any scene that uses anchors.

Reveal answer

C — render-layer separation as a forward-compatibility hedge. A Control root would work fine for the UI itself, but adding a world layer beneath it later forces a tree restructure (re-parenting all the UI under a new ancestor). Picking CanvasLayer now costs nothing and keeps the option open. A is wrong: Control can have arbitrary children. B is wrong: any scene type runs with F5 once configured. D inverts the relationship — anchors are a Control feature, not a CanvasLayer one; CanvasLayer is just where the Control subtree gets parented.

Q3 — You hit F5 and the editor pops up 'No main scene defined.' Which fix corresponds to the actual missing setting?

A. Open Project Settings → Application → Run, set Main Scene to your saved .tscn file, and try F5 again. B. Press F6 instead — Godot interprets F6 as "play whatever scene is open in the editor," and the prompt does not apply to F6. C. Edit project.godot by hand to add run/main_scene="res://scenes/main.tscn". The dialog is a convenience; the file-level setting is the real one. D. Open the scene first (scenes/main.tscn in the FileSystem dock) and press F5 — F5 plays the currently open scene whenever the main scene is unset.

Reveal answer

A — set the Main Scene field. The run/main_scene field in project.godot is empty by default; the error message is exact about what is missing. B describes a real Godot 4.6 shortcut (F6 = Play Current Scene, which does bypass the run/main_scene requirement) but it's not the fix for the prompt's actual cause — the prompt is the engine asking for a main scene, and dodging into F6 leaves the project unable to launch from F5 or from exported builds. C is technically possible (the dialog writes the same line into project.godot) but the dialog also resolves the uid:// reference for you — hand-editing with a res:// path works in dev but breaks if the scene is later renamed without UID propagation. D conflates F5 and F6: F5 launches the configured main scene only; with no main scene, it errors regardless of which scene is open in the editor.

Integration question

Q4 — open

By the end of M1.3 the project has nothing visually interesting to a player — a blank window. Yet the textbook spends three sub-units (M1.1 stretch, M1.2 folder layout, M1.3 main scene) in the same module before producing any UI. What does each of the three lock down, and what would happen to the M2 click-button work if any of them were left for "later"?

Reveal expected answer

M1.1 locks the coordinate system in pixel space — every later anchor or font size assumes 1280×720 plus canvas_items scaling. M1.2 locks the coordinate system on disk — every res:// path in scripts and .tres files is calibrated to the four-folder layout. M1.3 locks the runtime entry point — every later scene that loads or replaces the main scene assumes scenes/main.tscn is the home base. Skipping any of them and trying to do M2's click button means: anchors that compute against the wrong base resolution, scripts that reference paths in folders that do not yet exist, and an F5 that fails before the click can be observed. The "boring" module is what makes the next module possible at all.

Glossary

Glossary

scene
A tree of nodes treated as a single unit. Saved to disk as a .tscn file. Re-instantiated at runtime when the engine loads the file.
node
The atomic unit in Godot. One node = one job (render a sprite, hold a timer, group children). All gameplay objects, UI widgets, and systems are built by composing nodes.
root node
The exactly-one node at the top of a scene's tree. Its type sets the rendering/layout context for every descendant. A scene cannot have two roots.
Node
The atomic Godot class. No render context, no transform, no input. Use as a parent for non-visual logic. Wrong for the root of a player-visible scene.
Node2D
Godot's 2D-world root. Has position/rotation/scale in 2D space. For sprite-based games where the camera moves through a level.
Control
Godot's UI base class. Supports anchors, margins, focus, theme, container parenting. Use for individual UI widgets.
CanvasLayer
A render-layer separator. Children draw on a separate canvas above (or below) the default world canvas, with their own transform stack. Recommended root for UI scenes that may eventually want world art behind them.
Scene dock
The editor pane showing the open scene's tree as indented rows. Top-left by default. Paired with the FileSystem dock — file view ↔ tree view.
Ctrl+S / save scene
The action that writes the in-editor tree to a .tscn on disk. First save prompts for a path; subsequent saves overwrite silently.
run/main_scene
The project.godot setting pointing at the scene Godot launches on F5 (or in an exported build). Set via Project → Project Settings → Application → Run → Main Scene. In 4.6 the value is typically a uid:// reference.
editor window vs game window
F5 instantiates the main scene into a new window (game window), separate from the editor. The editor stays open; runtime errors print into its Output/Debugger panels, not into the game window.
### Ask Claude (side-channel) Try one of these in a Claude Code session if a piece did not land: - `Open scenes/main.tscn in the project and explain the file format line by line.` - `Re-explain CanvasLayer vs Control as scene roots using a non-Godot analogy — maybe a web page's z-index layers.` - `Quiz me on the difference between F5 and F6 with three new scenarios.` - `Open the Godot 4.6 class reference for CanvasLayer and find every property the chapter didn't mention (layer, follow_viewport_enabled, custom_viewport). Which would you reach for if you wanted a HUD that ignores camera zoom?`