Magivoid Devlog #2 - Teams, AI, combat, and a thingamajig
Today we get some shootin' goin'
With a landscape and a character shooting fireballs in place, it’s time to add things that a game might have. Continuing our multiplayer MOBA-like concept, a solid addition at this point is the notion of teams. Luckily this was easy to do with the gameplay tag system in Unreal Engine. These tags are essentially just labels but implemented in a fairly performant way with indexed strings. I think they’re also cheap to replicate across the network, but I haven’t actually looked close at this.
I set up two bases, one red and one blue, with a lane between them and a thingamajig in the center. The idea for the goal of the game is to destroy the other team’s base. There will be minions spawning at specific intervals from each base, walking down the lane, and fighting any enemies they encounter. Once the minions reach the enemy base, they engage in destroying it. Simple and recognizable formula. I’m not sure what the thingamajig in the center will end up being, but I like the idea of having some object where the minions will presumably first encounter each other (unless the players intervene earlier).
The gameplay tags make it really easy to propagate properties through various code systems. I’ve already used the team tags in a few different places. First, there’s two spawn points, one at each base. The player character gets a specific team tag applied based on what spawn point they spawn at. Second, the base itself has a team tag applied to it. This will stop players damaging their own base, accidentally or otherwise. Third, the minions that spawn have a team tag applied. This will be used by the AI to identify who is and who isn’t an enemy. Fourth, and lastly for now, I use team tags on my waypoint actors.
The waypoints are just blueprints in UE that store an index and belong to a team. The index is used by the AI to know which waypoint to move towards. The minions, for now, have very simple behaviors: move down the list of waypoints and stop and shoot when an enemy is within range. If the minion gets to the enemy base, stop moving and start shooting until either the base or minion is destroyed.
You’ll notice in the screenshot above the waypoints for the blue team are just slightly above the waypoints for the red team. The behavior tree for the minion AI uses EQS queries to get random points around each waypoint for the minion to move towards so it’s always a slightly different path, though probably not noticeable. This should be enough for multiple minions to not pick the same location and bump into each other. In fact, minions from opposing teams wouldn’t bump into each other anyway as they would stop and shoot before they got close enough to touch.
Speaking of minions bumping into each other, right now there’s only one minion spawning at a time for each team. In traditional MOBAs there tends to be a set of minions walking together. Something to consider for later, but this will have to come once we can balance the gameplay a bit anyway, otherwise we’re just guessing what works at this point.
The minions have a continuous enemy detection scan going that’s basically a simple visibility and distance check for player and AI actors. When an actor tagged as the opposing team is within range, the minion stops walking and starts shooting at that actor. The attack loop fires off three shots with a 0.5s delay between each, then a 1.5s delay, and repeat. The timing will likely need tweaking at some point once we start looking at damage values.
You might also have noticed in the screenshot above how the red and blue waypoints diverge around our thingamajig centerpiece. The red AI takes one path and the blue AI takes the other. When the minions from the two teams are circling around this area, they are actually within each other’s attack range. The cone however blocks their line of sight, which causes them to continue walking towards their next waypoint as if nothing happened.
Technically that’s correct, they don’t see each other. This is purely an accident due to the minimal effort I put into creating the cone that serves as the centerpiece. If we replace it with a smaller object (or remove it), the minions would see each other and engage in combat.
I quite like the outcome of the minions not seeing each other. It means by default they bypass the encounter in the center and reach all the way to the enemy base. Unless, of course, one or both of the players interject. One option is to sprint (which we support through ALS) to reach the enemy minion and engage them in combat, causing them to stop and allow your own minion to advance farther. I hope to find additional ways to indirectly influence the AI behavior, but again this would be something for later.
A second unintended “feature” noticeable in the video above is the collision between minion projectiles. They don’t pass through each other so you get cases where they explode in mid-air. The minion aim is randomized a touch at the moment (see this blog post for implementation details), so they don’t always collide. However, the projectile bounding sphere is fairly large and collisions do happen somewhat regularly. I love this result. As the great Mr Ross would say, we don’t make mistakes, just happy little accidents.