derkork / godot-statecharts

A state charts extension for Godot 4
MIT License
679 stars 33 forks source link

possibility of statechart use in complex inheritance entity AI #80

Closed BadBoyGodot closed 5 months ago

BadBoyGodot commented 5 months ago

My primary goal is to create a work system where entities can autonomously perform tasks such as carrying materials from one location to another, watering crops, operating machines, among other tasks. there are farmers extends entities. like palworld basically.

The challenge lies in designing a flexible, maintainable, and scalable system to reuse these behaviors and tasks. The system needs to accommodate different types of tasks, each with its own set of steps or actions (e.g., moving to a location, picking up an item, moving to another location, and then dropping the item). Moreover, it's essential to implement this system in a way that allows for easy expansion and customization of tasks and behaviors as the game develops further.

However, statecharts plugin is node-based, if i want to take an OOP approach and let different kind of entity have a different behavior set, I'll have to talk to behaviors in code like this,:

# Farmer.gd
class_name Farmer
extends Entity

var capable_tasks: Array = []
var current_task_behavior: TaskBehavior = null

func _init(task_types: Array):
    capable_tasks = task_types

func assign_task(task_behavior: TaskBehavior):
    if task_behavior in capable_tasks:
        current_task_behavior = task_behavior
        current_task_behavior.setup_task(self)
    else:
        print("This Farmer cannot perform the given ### task.")

func _physics_process(delta: float):
    if current_task_behavior and not current_task_behavior.is_task_completed(self):
        current_task_behavior.perform_task(self, delta)
    elif current_task_behavior:
        current_task_behavior = null

then write a custom_bahavior in this code:

# CarryTaskBehavior.gd
class_name CarryTaskBehavior
extends TaskBehavior

var task_completed = false
func is_task_completed(farmer) -> bool:
    return task_completed

func perform_task(farmer, delta: float) -> void:
    another_fsm_here()

I'm a beginner in game architecture, and I watched all of your YouTube tutorials and I believe if anyone has insights on this it would be you... do you think this kind of flexible behavior AI can be solved by this plugin?

Moreover, as a fan, can i ask you do you prefer OOP or ECS approach for this problem? big, big thank you!

derkork commented 5 months ago

I have not built such a system myself, so I cannot really offer substantial input based on real-world experience. I'm not really sure how much extensibility a system like that would really need, because in the end you only have a few things that the AI would need to be able to do:

Every "Task" is basically a combination of these. And now you could go with simple looped behaviours which just repeat steps, e.g. for a farmer:

This could be done with an FSM, but it's really so simple that I'm not sure how much value a FSM would bring to the table here.

Another approach would be to pick actions based on what produces the most value (a utility AI, e.g. check this GDC video) . There you would assign value to each potential action and execute the one that currently has most value. E.g. the AI would only go to the well and pick up water, if the field actually needs watering and do tilling instead or just be idle. Such a system would not use an FSM, but rather a customized utility AI system. So I'm not sure that this plugin will provide an significant aid in getting to where you want. FSMs are nice for very simple AI, e.g. patrol, chase, but I don't think they are a great fit for the thing you're trying to do. Then again - i have no real world experience in this field, so you may want to consult other people on this one.

As for OOP i'd say OOP unless you have a ton of actors that require the use of data oriented techniques to get the performance you need. OOP just works better together with the Godot engine and you really want to work with the engine, not against it .

Hope this helps at least a bit, but please also consider asking other people. There is the Godot Discord which has a lot of knowledgeable people who may have more real world AI experience than me and who may be able to provide better or more on-point advice.

BadBoyGodot commented 5 months ago

thank you! I watched this GDC video and it's very fancy and interesting about the high level decision making of AI, especially for the curve part. I joined the discord too! I realized how hard this question is for the average question there (mostly simple code issues), but I'll try to figure this out with every help I get.