Using and Creating Resources in Godot 4
Any game out there needs assets like textures, sounds, and music to provide a fun experience to its players. Godot treats these files as resources you can use throughout your project. Besides Godot’s built-in resources, you can also create your own to build powerful, modular systems. Custom resources make it easier to manage your project. […] By Eric Van de Kerckhove.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Using and Creating Resources in Godot 4
40 mins
- Getting Started
- Shop
- Player Item Display
- Shop Item Display
- What are Resources?
- Importing and Using Resources
- Applying a Sprite Texture
- Import Parameters
- External vs Built-in Resources
- Creating Custom Resources
- Your First Custom Resource
- An Inventory of Items
- Using Custom Resources
- The Shop Inventory
- Creating a Shop Display
- Showing the Shop Items
- Making Smart Resources
- Inventory Logic
- Player Script
- Displaying Player Items
- Saving and Loading Custom Resources
- Creating a Save Manager
- Connecting the Save and Load Buttons
- Where to Go From Here?
Creating a Save Manager
To get started, open the shop scene again and toggle the visibility of the SaveButtons node, which is a child of CanvasLayer. To do this, click the closed eye icon at the right of its name in the Scene tree.
This will make two buttons visible in the bottom-left of the scene: a Save Game button and a Load Game button.
At the moment, these buttons won’t do anything, but you’ll be hooking them up later.
Now create a new node as a child of the Shop node. Name it SaveManager and attach a new script to it. Name this script save_manager.gd and move it inside the scripts folder.
Next, add the following code to the save_manager.gd script, below the extends line:
class_name SaveManager
# 1
@onready var shop = $".." as Shop
@onready var player: Node = $"../Player"
# 2
var shop_inventory_path : String = "user://shop_inventory.res"
var player_inventory_path : String = "user://player_inventory.res"
These are variables to have a reference to the shop and player’s inventories and paths to save the inventories to:
-
shop
andplayer
are references to the shop and player nodes. This is needed to access their inventories. - These paths point to where the inventories will be saved to and loaded from. These paths are relative to the user:// path, which point to a different path on the user’s computer depending on the operating system:
- Windows:
%APPDATA%\Godot\app_userdata\[project_name]
- macOS:
~/Library/Application Support/Godot/app_userdata/[project_name]
- Linux:
~/.local/share/godot/app_userdata/[project_name]
- Windows:
Now it’s just a matter of saving and loading the inventories. To create the saving logic, add the following function:
func save_game():
ResourceSaver.save(shop.shop_inventory, shop_inventory_path) # 1
ResourceSaver.save(player.player_inventory, player_inventory_path) # 2
print("Game saved!") # 3
This function saves the shop and player inventories to the paths specified above:
- Use the
ResourceSaver
class to save the shop’s inventory to the path defined above - Do the same as with the player’s inventory
- Print a message to the console
As you can see, it’s quite simple to save a single resource. All you need is one line of code and you’re done!
Loading the inventories is a bit more involved, but still straightforward. To do so, add the following function:
func load_game():
if ResourceLoader.exists(shop_inventory_path): # 1
shop.shop_inventory = ResourceLoader.load(shop_inventory_path, "", ResourceLoader.CACHE_MODE_IGNORE) # 2
# 3
shop.update_shop_items_display()
print("loaded shop inventory")
# 4
if ResourceLoader.exists(player_inventory_path):
player.player_inventory = ResourceLoader.load(player_inventory_path, "", ResourceLoader.CACHE_MODE_IGNORE)
shop.update_player_items_display()
print("loaded player inventory")
When loading a resource, you want to make sure that it exists before you try to load it using the ResourceLoader.exists()
function. Otherwise, you’ll get a nasty error.
Here’s a summary of this code:
- Use the
ResourceLoader.exists()
function to check if the shop’s inventory path exists - Use the
ResourceLoader.load()
function to load an inventory from disk and overwrite the shop’s existing inventory. TheCACHE_MODE_IGNORE
parameter tells Godot to ignore the cache when loading the resource, more on that below. - Call the
update_shop_items_display()
function to update the shop’s inventory display. Also print a message to the console. - Do the same as with the shop’s inventory, but update the player’s inventory and its display instead.
There’s one thing you might be wondering if you ever used the load()
function before to load a resource: why not use that instead of the ResourceLoader.load()
function?
The reason is that the load()
function is a simplified version of ResourceLoader.load()
that uses the default parameters, including its cache mode. Cache mode is an Enum
with three possible values:
- CACHE_MODE_IGNORE: The resource will not be cached. This will load the resource data from disk every time.
- CACHE_MODE_REUSE: This is the default behavior. If a resource is already loaded in the cache, it will be reused. If not, it will be loaded from disk.
- CACHE_MODE_REPLACE: The resource will be reloaded and cached, even if it was already cached.
Godot keeps tracks of what paths you load resources from and caches the resources in memory. For most resources, the default cache mode is optimal, as that loads the resource only once from disk. You don’t want to load the same bullet sprite hundreds of times for example.
For a dynamic resource like a saved game that you can save and reload anytime, CACHE_MODE_IGNORE is the best option. It ensures that the save game is loaded fresh from the disk each time. The other modes will prefer to reuse the resource if it’s already cached, even CACHE_MODE_REPLACE, resulting in no new data being loaded.
Connecting the Save and Load Buttons
That was quite the detour, but you’re almost done! The final step is to hook up the save and load buttons to their matching functions via the editor.
Save the save_manager.gd script and select the SaveButton node in the node tree. It’s a child of the SaveButtons node.
Now open the Node tab at the right side of the editor, next to the Inspector tab and double-click its pressed signal.
This will open the signal connection window. Select the SaveManager node in here and click the Pick button to open the list of functions.
Double-click the save_game()
function to link it to the button’s pressed signal.
Finally, click the Connect button to confirm the connection. Do the same for the LoadButton and the load_game()
function.
Great job, now all that’s left to do is playing the project to test the save and load buttons. You can do this by buying a monster and clicking the Save Game button. Check if “Game saved!” appears in the output window. Now buy some more monsters and click the Load Game button. If all went well, the player will be left with a single monster in their inventory.
That’s it, you’re now a master of resources in Godot!
Where to Go From Here?
You can download the final project at top or bottom of this tutorial by clicking the Download materials link.
Thanks for reading this tutorial to the end, I hope you enjoyed it. Now you know how resources work in Godot and how to make your own, I recommend to experiment with them in your own projects. Custom resources in particular make for a great addition to your game development tool belt.
If you have any questions or feedback, please join the discussion below.
A lot more tutorials about Godot and its features are coming soon, so stay tuned!