In RTS games, there are special kinds of units called villagers, that collect resources from different places, and deposit it in town center. In other words, carrier units take resources from production places to the storage places. I call this system resource management. There are thus 3 parts we have to develop:
- A villager unit
- A town center (stockpile; deposit of resources).
- And finally resources themselves.
Its worth noting that some resources are grown (such as food) and some are collected. And, some even are crafted. It is up-to the building and the resource to perform that operation of how it is created. The villager unit itself is only responsible for delivering from production facility to storage facility.
In short, the resource management system consists of 3 parts: resource (source), stockpile (sink) and a villager (carrier).
Town Centers as Stockpile
In the previous tutorial, I already created a town center which is capable of holding any amounts of any resource. It just needs a resource identifier & its amount in dictionary. So we will just use it as a deposit of resources.
Making Resource Itself
Resources in RTS games can be anything, ranging from trees, rocks, gold ores, iron mines, oil rigs and so on. But they all have one thing in common; they are collectable & occupy some space.
So in Godot, start by creating a folder named “RTSResources”. For each separate resource, we will create a sub-folder later. But for now, create a script “RTSResource.gd” in the folder. This script will have properties common to all resources:
extends StaticBody3D
class_name RTSResource
# Class to represent a resource unit in the game world
# A resource must have unique name - resources are identified by their name
# Their name is saem as the scene name/root node name
enum RTSResourceTypes {
WOOD,
FOOD,
GOLD,
STONE
}
@export var resource_type : RTSResourceTypes = RTSResourceTypes.WOOD
@export var amount : int = 100
@export var economic_value : int = 1 # How much the resource is worth in terms of currency
@export var gather_rate : int = 10 # How much of the resource can be gathered per visit
@export var gather_time : int = 1 # How long it takes to gather the resource
func _ready():
add_to_group("resources")
collision_layer = 0b00000000_00000000_00000000_00001000
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
func _physics_process(delta):
pass
In above script, I defined all possible resource types possible in our RTS game. I defined variables such as economic_value
to represent value of this resource in exchange for the game currency (gold), gather_rate
and gather_time
are used to calculate how much amount of resource can be taken by the unit who gathers it and for how long he has to wait while resource has been fully gathered. At this time, the gathering animation will typically take place.
Creating Resource Scene
In this tutorial, I will only create a tree resource. For this, make a folder named “Tree”. In this folder, create a scene for the tree. Rot node must be StaticBody3D
, having MeshInshance3D
& Collisionshape3D
children. This is how it looks like:
Basically, the tree has its own script, but it just extends for base RTSResource
and adds no meaningful logic to it (in Tree.gd):
extends RTSResource
func _ready():
super()
add_to_group("trees")
func _process(delta):
super(delta)
func _physics_process(delta):
super(delta)
Making the Resource Carrier
The third part of the resource management system is a unit that carries resources from sources to deposits. This is typically a villager unit. It is created just like the Warrior unit was previously created, but it has different states and handle those states. The whole system of collecting resource and moving toward town center to deposit is made in separate post: how to make villager in RTS game.
Thank you so much for reading it <3