Resources

Nodes and resources

Up to this tutorial, we focused on theNodeclass in Godot as that's the one you use to code behavior andmost of the engine's features rely on it. There isanother datatype that is just as important:Resource.

Nodes give you functionality: they draw sprites, 3D models, simulate physics,arrange user interfaces, etc.Resources aredata containers. They don'tdo anything on their own: instead, nodes use the data contained in resources.

Anything Godot saves or loads from disk is a resource. Be it a scene (a.tscnor an.scn file), an image, a script... Here are someResource examples:

When the engine loads a resource from disk,it only loads it once. If a copyof that resource is already in memory, trying to load the resource again willreturn the same copy every time. As resources only contain data, there is no needto duplicate them.

Every object, be it a Node or a Resource, can export properties. There are manytypes of Properties, like String, integer, Vector2, etc., and any of these typescan become a resource. This means that both nodes and resources can containresources as properties:

../../_images/nodes_resources.webp

External vs built-in

There are two ways to save resources. They can be:

  1. External to a scene, saved on the disk as individual files.

  2. Built-in, saved inside the.tscn or the.scn file they're attached to.

To be more specific, here's aTexture2Din aSprite2D node:

../../_images/spriteprop.webp

Clicking the resource preview allows us to view the resource's properties.

../../_images/resourcerobi.webp

The path property tells us where the resource comes from. In this case, it comesfrom a PNG image calledrobi.png. When the resource comes from a file likethis, it is an external resource. If you erase the path or this path is empty,it becomes a built-in resource.

The switch between built-in and external resources happens when you save thescene. In the example above, if you erase the path"res://robi.png" andsave, Godot will save the image inside the.tscn scene file.

Note

Even if you save a built-in resource, when you instance a scene multipletimes, the engine will only load one copy of it.

Loading resources from code

There are two ways to load resources from code. First, you can use theload() function anytime:

func_ready():# Godot loads the Resource when it reads this very line.varimported_resource=load("res://robi.png")$sprite.texture=imported_resource

You can alsopreload resources. Unlikeload, this function will read thefile from disk and load it at compile-time. As a result, you cannot callpreloadwith a variable path: you need to use a constant string.

func_ready():# Godot loads the resource at compile-timevarimported_resource=preload("res://robi.png")get_node("sprite").texture=imported_resource

Loading scenes

Scenes are also resources, but there is a catch. Scenes saved to disk areresources of typePackedScene. Thescene is packed inside aResource.

To get an instance of the scene, you have to use thePackedScene.instantiate() method.

func_on_shoot():varbullet=preload("res://bullet.tscn").instantiate()add_child(bullet)

This method creates the nodes in the scene's hierarchy, configures them, andreturns the root node of the scene. You can then add it as a child of any othernode.

The approach has several advantages. As thePackedScene.instantiate() function is fast, you can create newenemies, bullets, effects, etc. without having to load them again from disk eachtime. Remember that, as always, images, meshes, etc. are all shared between thescene instances.

Freeing resources

When aResource is no longer in use, it will automatically free itself.Since, in most cases, Resources are contained in Nodes, when you free a node,the engine frees all the resources it owns as well if no other node uses them.

Creating your own resources

Like any Object in Godot, users can also script Resources. Resource scriptsinherit the ability to freely translate between object properties and serializedtext or binary data (*.tres, *.res). They also inherit the reference-countingmemory management from the RefCounted type.

This comes with many distinct advantages over alternative datastructures, such as JSON, CSV, or custom TXT files. Users can only import theseassets as aDictionary (JSON) or as aFileAccess to parse. What sets Resources apart is theirinheritance ofObject,RefCounted,andResource features:

  • They can define constants, so constants from other data fields or objects are not needed.

  • They can define methods, including setter/getter methods for properties. This allows for abstraction and encapsulation of the underlying data. If the Resource script's structure needs to change, the game using the Resource need not also change.

  • They can define signals, so Resources can trigger responses to changes in the data they manage.

  • They have defined properties, so users know 100% that their data will exist.

  • Resource auto-serialization and deserialization is a built-in Godot Engine feature. Users do not need to implement custom logic to import/export a resource file's data.

  • Resources can even serialize sub-Resources recursively, meaning users can design even more sophisticated data structures.

  • Users can save Resources as version-control-friendly text files (*.tres). Upon exporting a game, Godot serializes resource files as binary files (*.res) for increased speed and compression.

  • Godot Engine's Inspector renders and edits Resource files out-of-the-box. As such, users often do not need to implement custom logic to visualize or edit their data. To do so, double-click the resource file in the FileSystem dock or click the folder icon in the Inspector and open the file in the dialog.

  • They can extendother resource types besides just the base Resource.

Godot makes it easy to create custom Resources in the Inspector.

  1. Create a new Resource object in the Inspector. This can even be a type that derives Resource, so long as your script is extending that type.

  2. Set thescript property in the Inspector to be your script.

The Inspector will now display your Resource script's custom properties. If one editsthose values and saves the resource, the Inspector serializes the custom propertiestoo! To save a resource from the Inspector, click the save icon at the top of the Inspector,and select "Save" or "Save As...".

If the script's language supportsscript classes,then it streamlines the process. Defining a name for your script alone will add it tothe Inspector's creation dialog. This will auto-add your script to the Resourceobject you create.

Let's see some examples.Create aResource and name itbot_stats.It should appear in your file tab with the full namebot_stats.tres.Without a script, it's useless, so let's add some data and logic!Attach a script to it namedbot_stats.gd (or just create a new script, and then drag it to it).

Note

To make the new resource class appear in the Create Resource GUI you need to provide a class name for GDScript, or use the [GlobalClass] attribute in C#.

@exportvarhealth:int@exportvarsub_resource:Resource@exportvarstrings:PackedStringArray# Make sure that every parameter has a default value.# Otherwise, there will be problems with creating and editing# your resource via the inspector.func_init(p_health=0,p_sub_resource=null,p_strings=[]):health=p_healthsub_resource=p_sub_resourcestrings=p_strings

Now, create aCharacterBody3D, name itBot, and add the following script to it:

extendsCharacterBody3D@exportvarstats:Resourcefunc_ready():# Uses an implicit, duck-typed interface for any 'health'-compatible resources.ifstats:stats.health=10print(stats.health)# Prints "10"

Now, select theCharacterBody3D node which we namedbot, and drag&drop thebot_stats.tres resource onto the Inspector. It should print 10! Obviously, this setup can be used for more advanced features than this, but as long you really understandhow it all worked, you should figure out everything else related to Resources.

Note

Resource scripts are similar to Unity's ScriptableObjects. The Inspectorprovides built-in support for custom resources. If desired though, userscan even design their own Control-based tool scripts and combine themwith anEditorPlugin to create customvisualizations and editors for their data.

Unreal Engine's DataTables and CurveTables are also easy to recreate withResource scripts. DataTables are a String mapped to a custom struct, similarto a Dictionary mapping a String to a secondary custom Resource script.

# bot_stats_table.gdextendsResourceconstBotStats=preload("bot_stats.gd")vardata={"GodotBot":BotStats.new(10),# Creates instance with 10 health."DifferentBot":BotStats.new(20)# A different one with 20 health.}func_init():print(data)

Instead of inlining the Dictionary values, one could also, alternatively:

  1. Import a table of values from a spreadsheet and generate these key-value pairs.

  2. Design a visualization within the editor and create a plugin that adds itto the Inspector when you open these types of Resources.

CurveTables are the same thing, except mapped to an Array of float valuesor aCurve/Curve2D resource object.

Warning

Beware that resource files (*.tres/*.res) will store the path of the scriptthey use in the file. When loaded, they will fetch and load this script as anextension of their type. This means that trying to assign a subclass, i.e. aninner class of a script (such as using theclass keyword in GDScript) won'twork. Godot will not serialize the custom properties on the script subclass properly.

In the example below, Godot would load theNode script, see that it doesn'textendResource, and then determine that the script failed to load for theResource object since the types are incompatible.

extendsNodeclassMyResource:extendsResource@exportvarvalue=5func_ready():varmy_res=MyResource.new()# This will NOT serialize the 'value' property.ResourceSaver.save(my_res,"res://my_res.tres")

User-contributed notes

Please read theUser-contributed notes policy before submitting a comment.