I already discussed this, but there’s lots of logic now behind units being garrisoned at the keeps. I convinced myself to cheat and teleport them, and it works sorta well. Unfortunately, this looks crap and breaks some state related stuff. And now we need superunit to interact with these units in various ways. So I guess we are doing this the hard way.
Keep in, keep out
This is the typical scenario — enemy units/mobs (red) arriving by road (beige) at the keep (blue):
The units are going to the keep’s entrance (black bridge), not the actual spots right away, as that might break some path-finding, especially if the road curves near these spots and going straight is quicker than going to the entrance first. Then they go to their assigned spots.
Note that path distance L1 (closer spot) is less than L2 (farther spot). Obviously, it takes longer to get to the far spot than it takes to get to the near spot. But we don’t care, it’s just arriving and it doesn’t look that messy. Now the units are at their spots and all is dandy:
Now, if the units leave like they entered — go to spot and proceed to next keep — it will cause a serious mistiming. Assuming keep sends a unit every 1 sec, it will send that unit 1 second (black) plus path-time seconds (red) later:
So the units will leave the keep roughly 2, 3, 4, 5, 4, 3, and 2 seconds after being triggered. This means units will have different distances between them and we really don’t want that. So what I do is, when precalculating keep spots, I also store the distance and add penalty for units closest to the exit:
So this way, everyone leaves at the same time and we keep this nice illusion of wave/column.
Obviously, units need a little more memory on than “go there”, namely “why?”. That’s a very simple way of saying I’m using states. For the above exercise, there are 4 states shown in different colors:
Red is “goto keep”. Magenta is “garrison keep”. Aqua is “defend keep”. Green is “leave keep”. Yellow is “goto keep” (but with different parameters than before). A simple reason why units need this is because they are very simple. They are on a need-to-know basis — they don’t know about keeps or enemies, or pretty much anything else, they just know how to find a path. So we need to keep track of why we came here and what we will need to do once told to — i.e. current state. Other basic stuff units are told are target keep and target coordinate. And this works very well. The best benefit is that I can code behaviors independently or equally, depending on the state. So I may choose to take state into account when deciding where to go next, but I will ignore it when animating a lightning zap.
If one follows closely, then an obvious comment is: surely, this can be simplified. Just make “goto keep” and “defend keep” and set the path-finding via the waypoint. Well, whoever you are, consider this:
The defending unit needs to attack some pesky stickman nearby. This would actually happen every time the superunit gets near a keep. But in this case we cannot attack while in “garrison keep” or “leave keep” states, because the game expects them to take a certain time and free up the space for further actions. It happens rarely, but is possible. I also don’t want units dieing in states which affect the keep without my precise control. So we only want the unit to attack enemies (orange) when already garrisoned (aqua). This way, nothing will mess with our arrival/departure.