Creating Point and Click Games with Escoria


If you want your game to be a success, one of the thing is it has to be fluid, even after hours of use. Optimizing with simple technics we will briefly describe can be a first approach that might be improved later on specifically in each project. In fact, optimization can be done at every step, including in the graphics and sounds. The technique shown are related to the project management.

Preloaded scenes

Even though all main scenes are a "self contained game", there are many things we don't want to load more than once. For example the inventory items, the hud, the main character, etc. To avoid this, we can keep a list of preloaded scenes in memory for the duration of the game. Theses scenes are loaded using a thread at the start of the game, and we make sure they're loaded before the first game starts.

To add scenes to your preload list, use the file game/ with a const array named "scenes" containing a list of your scenes

const scenes=[

Preloading resources

During a game cutscene, it could be useful to preload a resource before it's needed, to speed up the game loading. For this we have the esc command queue_resource, which sends the resource to a load queue on a separate thread.

queue_resource "res://scenes/next_scene.tscn" false
cut_scene player open_door
cut_scene telon fade_in
change_scene "res://scenes/next_scene.tscn"
cut_scene telon fade_out

Queued resources are unloaded after the main scene changes, but not before the next scene is loaded, meaning you can use this to start preloading the next scene, or to preload resources contained on that scene.

When the second parameter is true, the resource is put at the front of the queue.

Animations with placeholder scenes

Sometimes an item or the main player can get too heavy with many animations. This section will discuss how to split the animations into many scenes that can be loaded on-demand, or preloaded at an appropriate time.

Suppose you have a big animation on your character, that you want to load only when necessary. Your animation has a number of frames, either on a sprite sheet or multiple files.

Step 1: animate using a separate Sprite or AnimatedSprite node

First, make a separate Sprite or AnimatedSprite node with the frames for this animation. On your animation, make the node visible at the start, and hide it at the end of the animation. If the animation loops, make sure other animations make this node invisible when they start. Remember that on a game we might not always know what animation will follow another, so it's better to prepare for all combinations.

Step 2: make the node an external scene, and "Load as placeholder"

Once your node contains all the sprites, save the node as a separate scene using the option menu option SceneConvert to > Subscene... Once your node is a subscene, you'll see a folder icon next to it in the scene tree panel. Open the folder, and check the option Load as placeholder. This will cause the new scene to not be loaded when the main player scene is loaded.

Step 3: run the "" script on the scene

Outside of the device/ directory, you'll find the file "tools/". Using the menu option Scene > Run Script..., run this script on the scene. The script will find all the placeholder sub-scenes, and match them with animations that use them, and store this in the "placeholders" property of your item or character.

Now, when your scene is loaded, the placeholder scenes won't be loaded. When an animation is played from an esc file, the script will know it needs to load the placeholder before playing the animation.

Preloading placeholders

If the placeholder scene takes to long to load at the moment of playing the animation, you can combine this with the "queue_resource" esc command. You can also use the "queue_animation" command, which looks up which placeholders are needed for a specific animation, and queues them for you:

queue_animation player open_door
say player "I better open the door"
cut_scene player open_door

Il y a une erreur de communication avec le serveur Booktype. Nous ne savons pas actuellement où est le problème.

Vous devriez rafraîchir la page.