Godot Version
Godot Engine v4.4
Question
In my game I have people who can do several jobs, there will be farmers, teachers, fishermans and so on.
For each of them I am thinking to create a different script because they will have to act differently and could have different attributes (i.e. a farmer will have a defined work place assigned, the farm, but a gatherer will not, because it will be enough to roam around looking for proper bushes).
At any point the player will be able to change the number of any type of workers, or to remove a building where someone was working, this will lead to have citizens that change their jobs.
My first thought has been to despawn the character and to spawn a new one of the correct type copying the relevant attributes from the old to the new one (money, inventory, home…).
Is that a good solution? Would you do differently?
There are lots of ways you can do this.
Personally, I’d suggest giving your characters a job
var, or jobs
if you want it to be an array. You can make global scripts that define the jobs:
# people script
[...]
enum Jobs { Blacksmith, Farmer, Fisherman, Lumberjack, Teacher }
var JobActions: Array = [
{ "job": Jobs.Blacksmith, "start": Blacksmith.Start, "end": Blacksmith.End, "action": Blacksmith.Act} ,
{ "job": Jobs.Farmer, "start": Farmer.Start, "end": Farmer.End, "action": Farmer.Act },
[...and so on...]
]
var ActiveJobs: Array = []
func add_job(job: Jobs):
if ActiveJobs.has(job): # Are we already doing this?
return
ActiveJobs.append(job)
var actions = JobActions[job]
actions["start"].call(self)
func remove_job(job: Jobs):
if !ActiveJobs.has(job): # Are we not doing this?
return
# .erase(job) does the right thing even if job isn't in the array, but
# we might want to do an action only when we're removing an active job...
ActiveJobs.erase(job)
var actions = JobActions[job]
actions["end"].call(self)
func do_job(job):
if !ActiveJobs.has(job): # Are we not doing this?
return
var actions = JobActions[job]
actions["action"].call(self)
And then:
# Global Blacksmith Script
[...]
func Start(person):
# Do whatever is needed for someone assuming the blacksmith job...
func End(person):
# Do whatever is needed for someone leaving the blacksmith job...
func Act(person):
# Do a blacksmith action.
if person.strength < 20: # Can this person wield a hammer?
...
That should let you isolate your jobs in their own scripts, and add new jobs as you please.
Note that I haven’t done any error checking or much for robustness (it might, for instance, be better to scan the array for a matching “job” entry rather than counting on array ordering matching enum ordering…), but you could build a fairly robust and expandable job system on this basic idea.
1 Like