The Godot Community Forums are back up and running! Please read the the announcement post for important information on what happened. Thanks!

Data-driven enemy types generation from JSON definition file?

UnknownUserUnknownUser Posts: 0
edited September 13 in Programming

I know that the term data-driven is also used (if I'm not mistaken) for the hardware-friendly code (to avoid CPU cache misses and so on), but I'm using it with the other usual meaning: ""to be able to add content by changing only JSON (or similar) files". I don't want to start a terminology flame ^_^.

Hello, newbie here!
I would like to generate different enemy types based on a JSON like this (take it as a dummy example, not as a strict specification):

enemies.json

[
  { "name": "basic",
    "spritePath": "sprites/basic.png",
    "components": [
      { "name": "health",   "value": 100 },
      { "name": "movement", "type": "chase" },
      { "name": "attack",   "type": "mele", "power": 10 },
    ... ]
  },
  { "name": "boss",
    "spritePath": "sprites/boss.png",
    "components": [
      { "name": "health",   "value": 1000 },
      { "name": "movement", "type": "complex_movement" },
      { "name": "attack",   "type": "mele",  "power": 30 },
      { "name": "attack",   "type": "range", "power": 15 },
    ... ]
  },
... ]

Is there any resource with info on this? I've been looking for the last two days and haven't found anything. But I've never worked with Godot, so maybe I'm missing something obvious.

Clarification: I am not asking how to read the JSON file, I'm sure that's a trivial task. I am asking for some guide to implement the systems to compose the different enemy nodes. I know that, regarding the communication between nodes, you need take in to account some good practices and I don't know the right way to implement this kind of decoupled components.

For example, I could create a generic Enemy node/class and pass the parsed definition to an initialize function. But, how can you avoid the God Object anti-pattern in that class?
Is there a easy way to isolate the code of the different components? Maybe it's something as easy as a list of component factories. Maybe it's something as easy as a list of component factories. But, as I said, I've only used Godot for a couple of hours... so not sure how things are done here.

EDIT: With information from the reddit post , I did this:

I created a MyComponent autoload / singleton:

func move_obj(obj):
  obj.velocity = # calculate velocity ...
  obj.velocity = obj.move_and_slide(obj.velocity)

and called it from the node's _physics_process():

var components = [MyComponent]

func _physics_process(delta):
  for component in components:
    component.move_obj(self)

I think I can have all the code in Singletons and have generic Enemy class with just an array of components (singletons) that are called in the _physics_process() function. Do you see any problem with this?

Thanks!

Best Answer

  • TwistedTwiglegTwistedTwigleg Posts: 3,141
    Accepted Answer

    Welcome to the forums @Crul!

    I think the singleton pattern for components should work. Since you have a reference to the component and the singleton itself is not directly managing the objects, I don't see anything necessarily that would cause issues. If the singleton itself was holding references to the object, then you could run into the issue where the object does not exist but the singleton thinks it does because it has a reference, leading to a crash, but with the example code given, this should not occur.

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 3,141Admin
    Accepted Answer

    Welcome to the forums @Crul!

    I think the singleton pattern for components should work. Since you have a reference to the component and the singleton itself is not directly managing the objects, I don't see anything necessarily that would cause issues. If the singleton itself was holding references to the object, then you could run into the issue where the object does not exist but the singleton thinks it does because it has a reference, leading to a crash, but with the example code given, this should not occur.

  • UnknownUserUnknownUser Posts: 0
    edited September 14

    Thanks @TwistedTwigleg !

    I saw these videos today: ECS in Godot: playlist with 3 videos (Ombarus) that explains an architecture even more decoupled using Singletons and Signals. It would probably be better to use something that has worked for others and don't try to reinvent the wheel.

Leave a Comment

BoldItalicStrikethroughOrdered listUnordered list
Emoji
Image
Align leftAlign centerAlign rightToggle HTML viewToggle full pageToggle lights
Drop image/file