Quick answer: When you switch layouts with "Go to layout", all non-global object instances on the previous layout are destroyed. If your events reference an object type that only exists on the old layout and is not marked as Global, the engine cannot find any instances and the reference fails. Set the object to Global, place an instance on the destination layout, or use global variables to pass data between layouts.
You have a player sprite on Layout 1 with health, score, and inventory data stored in instance variables. You use "Go to layout" to switch to Layout 2. Suddenly your events that read the player's health throw errors or silently return default values. The player object is gone — destroyed during the layout transition. This is one of the most common Construct 3 pitfalls, and it catches developers on nearly every multi-layout project.
The Symptom
After calling the Go to layout action (or Next/Previous layout), events on the new layout that reference an object type from the old layout behave incorrectly. You might see one of several failure modes:
Events that reference the object simply do not run because the object type has zero instances. Conditions like "If Player health < 0" are skipped entirely. Actions like "Set Player.x to 100" do nothing. Expressions like Player.health return 0 (the default for a numeric instance variable) instead of the value you set on the previous layout.
In some cases, especially when using "Create object" without first checking if the object type is available, you may get a runtime error in the browser console indicating that the object could not be found or created.
The confusing part is that everything works perfectly if you only have one layout. The problem only appears when you transition between layouts, and it often only appears for some objects and not others — making it seem random until you understand the underlying rule.
What Causes This
There are four common causes for this behavior:
1. The object is not set to Global. By default, every object instance in Construct 3 belongs to a specific layout. When the engine transitions to a new layout, it destroys all instances on the old layout and creates fresh instances for whatever is placed on the new layout. If your Player sprite only has instances on Layout 1, and you switch to Layout 2, those Player instances are destroyed. Any events referencing Player on Layout 2 find zero instances. This is working exactly as designed — it is just not what most developers expect.
2. The object type is not placed on the destination layout. Even if an object type exists in your project, events on a layout can only interact with instances that are alive on that layout. If you never placed a Player instance on Layout 2 and the Player is not Global, there are no instances to work with. The event sheet conditions that reference Player will simply be skipped.
3. Data is stored in instance variables instead of global variables. Instance variables are properties of individual instances. When the instance is destroyed (during layout change), all instance variable values are lost. If you stored the player's score as Player.score, that value disappears when the Player instance is destroyed. Global event sheet variables survive layout changes because they belong to the event sheet, not to any instance.
4. Dynamic creation fails because the object has no instances. If you try to use "Create object" to spawn an object type on the new layout, but the object type only existed on the old layout and has zero instances globally, the creation might fail. In Construct 3, object types need to be present in at least one layout (or set to Global) for the engine to know their full configuration at that point in the project.
The Fix
Step 1: Set persistent objects to Global. Select the object type (for example, Player) in the Project Bar or by clicking an instance on the layout. In the Properties panel, find the Global property and set it to Yes. This tells the engine to keep all instances of this object type alive across layout transitions.
// After setting Player to Global = Yes, the player
// instance persists across layouts with all its data.
// Event sheet (pseudo-code):
+ System: On start of layout
-> Player: Set position to (200, 300)
// Player still exists, health/score are intact
When an object is Global, its instances are not destroyed during layout transitions. They retain their position, instance variables, behaviors, and all other state. Be aware that the position carries over too — you may need to reposition the object on the new layout.
Step 2: Use global variables for cross-layout data. If you do not need the entire object to persist — just some data — use global event sheet variables instead of instance variables.
// Event sheet variables (set scope to Global):
// GlobalScore (Number) = 0
// GlobalHealth (Number) = 100
// GlobalPlayerName (String) = ""
// Before leaving Layout 1:
+ System: On any key pressed
+ Keyboard: Key "Enter" is down
-> System: Set GlobalScore to Player.score
-> System: Set GlobalHealth to Player.health
-> System: Go to layout "Layout 2"
// On Layout 2 start:
+ System: On start of layout
-> Player: Set instance variable score to GlobalScore
-> Player: Set instance variable health to GlobalHealth
Global variables are declared at the top of an event sheet and persist for the entire runtime session. They are the simplest way to pass individual values between layouts.
Step 3: Create objects dynamically on the new layout. If the object should be freshly created each time you enter a layout (such as enemies or collectibles), use the "Create object" action on the Start of Layout trigger.
// On Layout 2, create the object dynamically:
+ System: On start of layout
-> System: Create object EnemySprite on layer "Game"
at position (400, 200)
-> EnemySprite: Set instance variable health to 50
-> EnemySprite: Set animation to "idle"
For this to work, the object type must exist in the project and must be placed on at least one layout in the project (it does not have to be the current layout). Construct 3 needs to have loaded the object type's resources at some point.
Step 4: Use a Dictionary object for complex persistent data. For more complex data that needs to survive layout changes, create a Dictionary object and set it to Global. You can store any key-value pairs in it, and it persists across layouts.
// Set Dictionary to Global = Yes in Properties
// Before layout change, save data:
+ System: On function "SavePlayerState"
-> GameData: Add key "health" with value Player.health
-> GameData: Add key "score" with value Player.score
-> GameData: Add key "posX" with value Player.X
-> GameData: Add key "posY" with value Player.Y
// On new layout, restore data:
+ System: On start of layout
-> Player: Set health to GameData.Get("health")
-> Player: Set score to GameData.Get("score")
-> Player: Set position to
(GameData.Get("posX"), GameData.Get("posY"))
Why This Works
Construct 3's layout system is designed around the idea that each layout is a self-contained scene. When you leave a layout, the engine tears down everything on it — instances, their variables, their behavior states — and builds the new layout from scratch. This is intentional: it keeps memory usage predictable and prevents zombie instances from accumulating.
The Global flag is the explicit opt-out from this cleanup. When an object type is Global, the engine moves its instances out of the layout lifecycle entirely. They exist in a layer above the layout system, unaffected by transitions. This is why Global objects keep their position (which you may need to reset) and their instance variables (which is usually exactly what you want).
Global event sheet variables work for the same reason — they are scoped to the event sheet or the project, not to a layout. They are never cleaned up during transitions.
The Dictionary approach is particularly powerful because it combines the persistence of a Global object with the flexibility of key-value storage. You can serialize an entire game state into a Dictionary, carry it across layouts, and reconstruct whatever you need on the other side.
"If you need the object to exist on both layouts, make it Global. If you only need the data, use global variables. Do not try to have it both ways by placing non-Global instances on every layout — you will end up with duplicate instances when you revisit a layout with a Global object already alive."
Related Issues
If your audio stops playing after a layout change, this may be the same underlying problem — check our guide on audio not playing on first touch which covers the Audio object's persistence. For issues where objects exist but collisions are not registering, see collision not detected between objects. If your animations reset after a layout transition, animation not changing on trigger addresses state carryover. And if you are trying to save data permanently across game sessions rather than just between layouts, Local Storage data not persisting covers the async pitfalls of the LocalStorage plugin.
Global means it survives. Non-global means it dies with the layout.