About this manual
This manual explains how to set up the loading screen and object pools. They exist to reduce the stumbles caused by loading and creating things: “the game freezes for a moment when the scene changes”, “objects trickle in after the screen fades back up”, “firing a burst of bullets stutters right there”.
Both features have the same aim — shifting when the work happens — and the loading screen’s progress includes the object pool’s advance creation. Setting up both together makes the effect easiest to see.
How loading works in ACTION GAME MAKER
Three things are involved, and they need very different amounts of setup.
| Feature | What it does | Setup needed |
|---|---|---|
| Asynchronous scene loading | Loads scenes in the background without stopping the game | None (always on; there is no switch) |
| Loading screen | Shows a screen you made while loading | Make a scene and pick it in the settings |
| Object pools | Creates the objects in advance and reuses them instead of throwing them away | Place one node |
Asynchronous loading is already working without any setup. Because loading runs in the background, the loading screen can keep animating while it loads, and the screen only changes once the destination scene can actually be drawn.
What object pools aim at is cutting the time it takes to instantiate an object. They are not about saving memory or avoiding fragmentation.
Loading screen
Setting it up
- Press “+ New” in the map list, choose “Loading Scene” as the kind and give it a name. It is created in
res://loadingscenesand opens ready to edit. - Open the “Settings” menu → “Basic Settings”.
- Turn on “Enabled” under “Loading Scene”.
- Pick the scene you made in step 1 from the “Scene Path” dropdown.
That is all. There is nothing to set for when it is removed, or per transition type.
The dropdown lists the loading scenes in your project (it finds scenes whose root is a LoadingScene automatically). Setting it back to “Not Set” clears it.
Turning “Enabled” back off returns to the old behaviour with no loading screen.
To change where they are stored, use the asset folder fields in the same “Basic Settings” and change the folder for “Loading Scenes”.
Editing it
A loading scene is edited in the same map-making view as maps and menus. Set the kind dropdown in the map list to “Loading Scene” to see them listed.
The root row in the layer dock is “Loading Settings”, and its “+” offers these six. The list is limited to visuals and animation because the game is not running while loading.
Sprite / Color Rect / Animation / Label / Rich Text / Nine Patch Rect
Unlike a map there are no layers. Elements sit directly under the root.
The root node type
Anything works. CanvasLayer, Control, Node2D and so on can be used as they are. The engine handles drawing it in front of everything, so you do not need to adjust layer. Creating one from the map list gives you a LoadingScene.
Only scenes whose root is a GameScene, MenuScene or CoreScene cannot be used. Those are managed by the game and two of them cannot exist at once. Choosing one logs an error and no loading screen is shown.
Use the dedicated LoadingScene when you want to receive the start and end of loading, or to place a character driven by a visual script (see below).
Things that work just by placing them
Place these in the loading scene and the engine takes care of them. No wiring needed.
| What you place | What happens |
|---|---|
Simple Gauge / Image Gauge / ProgressBar |
The engine updates the value. It uses the node’s min / max as they are, so the default 0–100 works |
An animation named hide on an AnimationPlayer |
Played when the loading screen is removed, and the screen disappears after it finishes (the name loading_out works the same way) |
Autoplay on an AnimationPlayer |
Keeps running for the whole load. It does not stop even while the game is paused |
Any node deriving from Range can act as the progress bar. ACTG’s Simple Gauge and Image Gauge are included, so placing one is enough (a gauge with no variable assigned simply shows whatever value is written to it from outside).
Note that only the first one found in tree order is updated. To feed several bars, implement set_progress on the root’s script (the argument runs 0.0–1.0). Implementing set_progress stops the automatic gauge update, so that nothing is written twice.
If you do not place a hide animation, the engine’s own curtain fades it out instead.
Turn looping off on hide. A looping animation never ends, so the completion notice never arrives. The engine detects looping, logs why, and falls back to removing the screen with the curtain.
Only if you want a character driven by a visual script do you need the root to be a LoadingScene (see the next section).
What a LoadingScene root adds
You can use LoadingScene as the loading screen’s root. It is optional and has no settings of its own. It adds these two things.
| What you get | Details |
|---|---|
| Load notifications | Progress changes, load start and load finish arrive as signals |
| Visual script characters run | Objects with a visual script placed as children behave just like they do in a normal scene |
The second one is done by LoadingScene walking its descendants and registering them, so it does not work while the root is a plain CanvasLayer. Use LoadingScene when you want a character walking around during the load.
Everything listed in the previous section (automatic gauge updates, the hide animation, autoplay, the curtain, when it disappears, set_progress) works regardless of the root type. If you only want to format the progress yourself, implementing set_progress is enough and LoadingScene is not needed.
When it disappears
It disappears once all of these are true. There is nothing to configure.
- The destination scene has finished loading
- The destination scene is placed on screen and running
- Two frames have been drawn since it was placed
- The object pool has finished creating its instances in advance
- The minimum display time (0.3 seconds) has passed
The third one is what prevents “objects appearing after the screen fades back up”. The scene is warmed up behind the loading screen before it is removed, so the game is playable the moment it goes away.
The destination scene does not start running until the removal is decided. This keeps the game from progressing out of sight for as long as the advance creation takes. It starts the moment the removal effect (the curtain closing, or hide) begins, so the first frames run while the screen is hidden and everything is settled by the time it becomes visible.
The BGM set on the game scene also waits for the removal. The music will not start while the screen is still up.
The fifth one prevents the loading screen from flickering when loading finishes instantly. The 0.3 seconds is measured from when the curtain has fully opened, so it never “appears for an instant and vanishes”.
The fade in and out (the curtain)
A loading screen that appears and disappears abruptly looks like a flash, so the engine opens and closes a curtain to make sure the screen is always a solid colour at the moment things switch.
| Movement | Length | Colour |
|---|---|---|
| The loading screen appears | 0.2 seconds | Matches the pre-transition effect’s colour |
| The loading screen disappears | 0.2 seconds | Matches the post-transition effect’s colour |
| The destination scene appears | The post-transition effect’s length (at least 0.2 seconds) | Matches the post-transition effect’s colour |
The last one uses the length of the post-transition effect (the fade up) set in the scene transition editor, as it is. Even with the post-transition effect set to “none”, it still fades for at least 0.2 seconds so that it is not a hard cut.
If the post-transition effect is a slide (SLIDE_UP and so on), the curtain wipes away in the direction you specified. The real slide, where the new scene’s image moves in, cannot be reproduced: the camera lives inside the scene, so moving the scene moves the camera with it and nothing moves on screen. The direction itself is respected.
If you place your own hide animation, everything from the disappearance onwards is left to you (the curtain is not used), so that it does not fade twice.
About how the progress bar moves
The progress bar shows an estimate of how much is left, not an exact percentage.
| Range | What it covers |
|---|---|
| 0–60% | Loading the resources |
| 60–85% | From the load finishing to the scene being placed |
| 100% | Removal is confirmed |
It eases smoothly towards the top of each range and speeds up as the stages advance. It never goes backwards, and it never sits at 100% waiting.
When the object pool creates instances in advance, that progress fills from there up to 99%. This part is the ratio of instances actually created, so it moves exactly as the creation progresses rather than easing over time. The advance creation starts at 30% at the earliest and never before that, so the bar does not appear stuck while loading.
The value cannot be exact because of engine constraints: there is no way to read the progress of a load, and the destination scene is usually already prefetched as a neighbouring scene, in which case the load itself finishes instantly.
What happens at startup
On startup the ACTION GAME MAKER splash is shown for one second, and then the loading screen follows.
Loading runs in the background while the splash is up, so showing the splash does not make startup slower. If the first scene is light and loading finishes while the splash is up, the game starts directly without a loading screen, to avoid a flicker.
The splash reflects the “Application” → “Boot Splash” settings (image / background colour / scaling / filter) as they are. With nothing specified, the built-in ACTION GAME MAKER splash is used.
One exception: if the object pool still has instances to create at startup, showing the loading screen takes priority over avoiding the flicker, because something has to wait for the advance creation to finish.
Not shown for connected slide transitions
Transitions set to a connected slide (SLIDE_UP_CONNECT and so on) in the scene transition editor do not show the loading screen. A connected slide exists to move seamlessly into the next room, and putting a loading screen in the middle would hide both the slide and the player’s movement.
It is skipped if either the pre-transition or the post-transition effect is a connected slide.
Object pools
When they help
Creating a new object takes time. One at a time goes unnoticed, but when several are created at once — firing 20 bullets simultaneously — the frame rate drops right there.
An object pool creates those instances in advance during loading, and when an object disappears it is put to sleep instead of being thrown away so the next creation can reuse it. There is no wait to create, so a burst does not stutter.
Setting it up
- In the layer dock of the map-making view, press the “+” on “Map Settings” and choose “Game Object Pools”.
- Add an entry to “Pool List”.
- Set “Object Path” to the scene of the object you want to pool.
- Adjust “Create Count” and the rest as needed.
That is all. The setup is complete with this node alone. There is nothing to set on the object, on the bullet data or in the visual script. Once a scene is registered, every creation path uses the pool.
It is added directly under Map Settings — not inside a layer — because the advance creation is planned when the scene is loaded.
The Game Object Pools settings
Each entry in “Pool List” has these fields.
| Field | Meaning | Default |
|---|---|---|
| Pool Name | A label to tell entries apart in the list. Not used to look anything up | empty |
| Object Path | The scene to create instances from. This scene identifies the pool | empty |
| Is Prewarm Only | Only load in advance; keep no pool | off |
| Create Count | How many to create in advance | 8 |
| Auto Expand | Whether to create extra instances when the pool runs out | on |
With “Auto Expand” off, anything beyond the stock is created normally and that instance is not returned to the pool. It is not an error; it simply behaves as it did before the pool existed.
The advance creation is done a little at a time across frames (there is a per-frame time limit). It never creates everything at once and stalls a frame. The progress is handed to the loading screen, and the loading screen does not disappear until the advance creation is done.
Where to place the node
The sleeping stock is held by this node, so destroying the node loses the stock too. Where you place it changes the behaviour.
| Where | Behaviour |
|---|---|
| Somewhere not destroyed by scene transitions | The stock survives across scenes. Objects on loan are returned during the transition, so it is ready to use afterwards |
| Inside a game scene | The node is destroyed with the scene and the stock is lost. The node in the destination scene creates its own instances again |
To reuse the stock across scenes, make it persistent. The easy way is autoload: make a scene containing just one Game Object Pools node and register it under Project Settings → “Globals” → “Autoload”. A node registered there is created once when the game starts and is not destroyed by scene transitions.
You can also copy one over from another map. It is pasted directly under Map Settings.
Do not place it under a game object that is created at runtime. The advance creation must be planned by the time the scene is loaded, so place it in the scene as a node of its own.
Is Prewarm Only
With “Is Prewarm Only” on, only the loading is done in advance and no stock is kept.
- One instance is created once the source scene has loaded, and discarded immediately. The scene and its assets stay loaded, so there is less of a hitch when it is actually created
- Objects for that scene are created normally (not handed out from a pool, and simply deleted when they disappear)
- The root node type does not matter. Scenes that are not game objects, and UI scenes, can be registered
- “Create Count” and “Auto Expand” are unused, so they cannot be edited
It suits objects you do not want to reuse but whose first appearance you want to smooth out.
This setting is what you want for effects and particles. EffectObject and ParticleObject cannot be reused (see below), but “Is Prewarm Only” does not care about the root type, so they can be registered. Loading them ahead of the first time they are shown makes that first hitch much smaller. Registering the effects you plan to use is worth doing.
Which objects can be pooled
Only game objects and lightweight objects can be reused, because the return happens from those two kinds’ disappearance handling.
Objects driven by physics (PhysicsGameObject), effects (EffectObject), particles (ParticleObject) and other nodes are not supported: they have no path that returns them to the pool when they disappear. Any .tscn can be set as “Object Path”, but a scene whose root is not a supported kind gets no pool (it is reported in the log at runtime).
“Is Prewarm Only” is free of this restriction. Register effects and particles there to get their first load out of the way.
Which creation paths use it
Once a scene is registered, all of these go through the pool automatically. There is nothing to set per path.
| Path | Example |
|---|---|
| Firing bullets | The bullet-firing action |
| Creating objects | The “Generate Object” action |
| Connected objects | Objects created as children |
| Changing objects | The “Change Object” action |
| Revival | Reviving a vanished object, coming back from off-camera, restoring after a scene change |
When objects are returned
When an object disappears, it goes back to the pool instead of being deleted. It is returned by the disappear action, by changing the object, and by scene transitions.
A returned instance is restored to the state saved in the scene at the moment it is returned: properties changed at runtime go back to their saved values, nodes added at runtime are deleted, and the visual script goes back to starting from its initial action. The cleanup happens on the way back, not on the way out, so bursts of creation do not get more expensive.
Objects placed in the scene from the start are not returned (they were not handed out by a pool, so they are simply deleted).
Editor warnings and logs
Mistakes in the settings show up as warnings in the scene tree.
- “Object Path” is not set
- “Object Path” is duplicated (registering the same scene twice means the later one is never used)
At runtime, failures of the advance creation are logged (path not set / path cannot be resolved / duplicated / load failed / root is not a supported kind).
The absence of a pool is not logged. An object that is not registered is simply created normally, which is not a mistake.
Worked examples
Firing 20 bullets at once stutters
- Place a Game Object Pools node and set “Object Path” to the bullet’s scene.
- Set “Create Count” a little above the most that will be on screen at once (24 for 20 bullets, say).
- Run it without changing anything on the bullet data.
To check whether the stock is enough, turn “Auto Expand” off and try it. If it is short, only the later bullets stutter, so raise “Create Count” by that much. Turning it back on afterwards means bullets will not stop appearing in situations you did not anticipate.
Showing “Now Loading”
- Use “+ New” in the map list → kind “Loading Scene”.
At that point you already have a black background, a gauge, a “NOW LOADING …” label and an animation that cycles the dots. All that is left is to enable it under “Settings” → “Basic Settings” and pick the scene from the dropdown.
To change the look, add elements from the “+” in the layer dock and adjust the label text and the gauge colours. To make your own removal effect, add an animation named hide to the AnimationPlayer (with looping off).
Loading just the boss scene ahead of time
For something you do not want to reuse but whose appearance you want to smooth out.
- Add an entry to “Pool List” on a Game Object Pools node.
- Set “Object Path” to the boss’s scene.
- Turn on “Is Prewarm Only”.
The boss is created normally, but the scene and its assets are already loaded, so it appears without a hitch.
Reusing the stock across stages
- Make a scene containing just one Game Object Pools node and save it under
res://. - Register that scene under Project Settings → “Globals” → “Autoload”.
- Put the pool entries on the node in that scene.
The advance creation runs once when the game starts and is not repeated by later scene transitions. The only difference from placing one per stage is whether the stock survives; the settings are the same.
Things to watch out for
- There is no switch for asynchronous loading. Scenes always load in the background. Only the loading screen and the object pools need setting up.
- The loading scene settings live under “Settings” → “Basic Settings”. To reach them from Project Settings directly they are on the advanced side (
application/loading_scene/*), so turn the toggle on or typeloadinginto the search box. - A loading screen’s root cannot be a
GameScene,MenuSceneorCoreScene. Choosing one logs an error and nothing is shown. - To place a visual script character in the loading screen, make the root a
LoadingScene. Other types are not registered, so the character will not move. Nothing is logged, which makes it easy to miss. - Turn looping off on the
hideanimation. A looping animation never reports completion. The engine detects it, logs why, and falls back to removing the screen with the curtain. - If the removal never becomes possible, the screen is removed by force after a while. What it was waiting for is written to the log. A very large advance-creation count can also be cut short here, but the rest is created on demand so nothing breaks.
- Only one progress bar is updated automatically. To drive several, implement
set_progresson the root’s script; doing so stops the automatic update. - Connected slide transitions do not show the loading screen. It is skipped if either the pre- or the post-transition effect is a connected slide (by design).
- Destroying the Game Object Pools node loses the stock. To reuse it across scenes, make it persistent with autoload or similar.
- Do not register the same scene in more than one pool. The source scene identifies the pool, so the later one is never used. The scene tree warning points it out.
- Only game objects and lightweight objects can be pooled. Anything else set as “Object Path” gets no pool (“Is Prewarm Only” does not care about the type).
- Running out of stock is quiet. With “Auto Expand” off it just falls back to normal creation, with nothing logged. To check whether the stock is enough, turn it off deliberately and try.
- Reuse only means “an instance that came back is not rebuilt”. The object’s state is restored to the scene’s saved values on return, so it never carries on from last time — and equally, you cannot keep nodes added at runtime for the next use.
- Do not place a Game Object Pools node under an object created at runtime. The advance creation must be planned by the time the scene is loaded.
- What object pools aim at is cutting creation time. Memory use grows by however much you create in advance.
- The advance creation count translates directly into loading time. How long one instance takes depends on the object’s size, but a bullet with a visual script takes a few milliseconds. Several hundred adds seconds, so decide based on how many are really on screen at once.