How to serialize enemies with complex behaviour.

I am working with enemies deriving from a common enemy class, deriving again from a gameobject master class, and placing them on the map as instances, and saving maps by xml-storing object index, position, etc… But then each enemy actually has its own CLASS, which I have to code…

Each enemy has its own update loop, and draw loop, drawing one or several connected sprites , unique methods for special weapons etc…
Animations, special attacks and movement patterns, etc… Each enemy should have at least the potential for unique performance is my thought…

But when making an engine to support any number of games, this becomes a problem. I will need to load assets AND behavior from DATA FILES, probably xml…

So since xml can only store values, not code, I figured I would just hard-code classes for behavior, (basically classes which just have an update and maybe a draw loop), which would be passed some loaded parameters, and their host object… Something like “wave_pattern” or “patrol_ground”… “Flee_when_injured”…

But then again, I would still have to hard-code those behaviors, and tailor them to enemies etc, and I feel like I’m back at square one, and might AS WELL just code enemies and copy paste similar behaviors…
-And then just from MY end, manually just build each game with the needed enemy types, and just not include all the others… Since I am the only one in the world who will ever work with my engine anyway…

Thoughts?

1 Like

I don’t really know a lot about AI so take this with a grain of salt. What you’re doing, with hard-coded behaviour types, is probably what I would do as well. Enemies can have one more more behaviours which drive how they act in their environment. Making it so your XML can define those is pretty straight forward.

If you want more complex behaviours that aren’t so straight forwardly defined, the only other approach I can think of is some kind of scripting. Then you can define whatever behaviour you want, whenever you want.

Hopefully folks more in the know on this topic give you some better advice :slight_smile:

This is kind of where the ECS design pattern shines. Each behavior can be a component that is self contained. Then you abstract what you can, for example, your “patrol_ground” behavior could potentially take a list of waypoints to patrol. Then you attach the patrol_ground component to your enemy and store the data driven stuff in the xml file.

The behavior should always respond to the data.

“Flee when injured” isn’t a behavior, it’s a behavior and a property.

You could implement such a behavior like this:

Flee: IBehavior
float HealthThreshold = .25f; // if you want him never to flee, then you set it to something absurdly high like 999
IEnemy Parent;

Flee()
{ ...flee logic here;}

Update()
{
   if(Parent.Health/Parent.totalhealth < FleeThreshold)
      Flee();
}

Now you have an action that is data driven. FleeThreshold can be stored in xml and serialized/deserialized. The list of behaviors attached to the Enemy can also be serialized so the whole thing becomes data driven.

You also have an action that can be called individually, for example:

if(Enemy.IsAfraidOf("Rabbit") Enemy.GetComponent<FleeComponent>()?.Flee();

You could go many levels with this. For example, you put your IEnemy in an IVillage. The IVillage has many IPatrolRoutes. Then you assign the “Patrol” behavior to the Enemy and assign it one of the IPatrolRoutes in the village to patrol. Then your patrol code just goes through the list of points defined in IPatrolRoute. When you serialize the behavior, you just store the name/id of the PatrolRoute, and the name of the behavior, and that’s it.

1 Like

Take a look at this, it might give you some ideas:

https://shawnhargreaves.com/blog/iterator-state-machines.html

I wouldn’t try to make behaviours that can handle any game, just make the ones you need for your specific game. I find that some behaviours (ie. movement) tend to be common and I share the code between enemies but much of the code that makes the enemies different and interesting is custom for each.

1 Like

Thanks every one who have replied so far, others please feel welcome to continue, this is a good topic… I took the day to learn about ECS, and I feel like it’s pretty much what I’m thinking about, conceptually… LUA scripting is out of the question, I’m too bogged down to get into that right now.

Being alone, and having researched it some, I feel inclined to conclude that any of these approaches, attainable as they may be - and certainly cool - would be over-scoping for my current goals… I mean how many games and enemies will I make, ever? with no one else contributing, well…

I Guess I will just be serializing the obvious, static objects, textures, etc… But hard-coding unique objects…

I can always create inheritance from these initial objects, If I see some patterns emerge, ie if I find myself copy pasting code…

2 Likes