top of page
Search

Log 17: You Know I'm All About that Base, No Treble!

  • Writer: Kassandra McCormack
    Kassandra McCormack
  • Jun 23, 2024
  • 5 min read

One staple aspect of Musou game design that I do not have yet are bases. These are special areas of the map that spawn basic units for the team that controls them, and if enough of the controlling units are killed inside them the control transfers to the team that killed the most units (most levels/maps only have 2 factions fighting, but some ambitious levels will have a third faction). Usually this means that the game starts with all or most of the bases on the map controlled by the enemy AI, and the player's objective is to capture most, if not all, of them. Even in games where it doesn't really make much sense to have them and they are mostly an afterthought, or the stated objective isn't so much to capture the bases as defeat the enemy commander, bases make an appearance. They make useful waypoints to serve as objectives for the player, as well as provide a concrete, tangible reference for how well they are doing. Some games even have bonuses if you capture certain bases, or offer buffs/debuffs for fighting inside them (I've mostly only seen this in Dynasty Warriors: Gundam, but I really enjoyed that game, so I'm including it in my considerations and design), which offers more avenues for tactical planning on the part of the player.

ree
Mini-map showing bases in the level; Icons denote bonuses for capture. Image from Dynasty Warriors: Gundam 3; posted by Etokapa at https://github.com/xenia-project/game-compatibility/issues/1080

But how does capturing bases work? Bases serve as spawning points for the grunts/mooks of the two sides. In order to capture one to your side, you (the player) must defeat some number of enemy mooks inside the base to drain its health, and then (depending on the base) defeat some form of captain/tougher enemy to finally claim the base for your side. But beware! This can work in reverse too! If the enemy team kills enough of your allied units inside a friendly base and defeats its potential captain they can capture a base as well. This provides the impetus for the player to hurry: left to their own devices, generally the enemy side is programmed to overtake your side. Very rarely bases can start out neutral (not owned by any side, the grey bases in the previous picture) and all a side needs to do to claim it is be the first to get to it.


All that being said, it should be relatively easy to implement, right? As should not be surprising: no. It took me 2 weeks to get them functioning as I wanted (plus another week where my computer had to be repaired). Apparently spawning characters is easy, but spawning them on the ground at a random point within an arbitrary space is remarkably difficult.

First up was finding that random point. My initial research lead me to find the function "Random Point in Bounding Box". Which was fine, except for a couple problems: 1) The function does not take rotation into account out-of-the-box, 2) It includes random points along the Z-axis, and 3) Most of my planned bases are not in anyway box shaped. The first two points could be easily addressed with some extra programmatic translation and hit detection, respectively. The third point was not something I could overcome with programming (not without some crazy/insanely complicated math).


So what I did is use "Random Point in Bounding Box" to generate a random point, but then I generated two more points above and below that point by a significant margin. I then did a line trace between those two points that only looked for WorldStatic objects. This gives me the point on the ground closest to the randomly chosen point. After that I needed to worry about the character's rotation when spawning.


For the rotation I determined there are two situations that I need to be aware of: when a unit on a different team is in the base and when they are not. No enemy infiltration was easier: just have them spawn looking at the center of the bounding box. There's more polished/juicier ideas I could have implemented but this is assuming the player is nowhere near and them seeing this is all that matters. That being said, if a high value enemy unit is in the base when it spawns new units, the new units will face the enemy unit (this is most important so that they notice and move towards the player rather than stand around looking for them like idiots).


Captains are stronger units that only spawn just as a base is about to be captured, and have to be defeated in order for the base to change hands. Not all bases have a captain, but most important ones do (especially the enemy's main base). Spawning one of those into the base was easy as I just had to copy the same spawning code, the hardest part was injecting the captain spawn and defeat into the base capturing code to arrest it. If the captain is not defeated and there are no other high priority enemy units I just have the base despawn the captain and begin regenerating health.


The final thing I worked on for bases is the game juice (the special effects that play when something happens to add more flair and pop to a game mechanic) for capturing them. For this I wanted to really draw the eye to the fact the base is changing hands without the player necessarily having to look at a bar change color and fill up. The reason I chose to work on this is that I wanted actual control of the base to come after the effects were complete (or partially complete as wound up being the case) and so I needed to figure out how to do that. I wound up making two halves to the effect, one is a color change of the actual field surrounding the base, and the other is a pulse of colored energy that flows out from the base's center.


First the color change:

ree

This proved particularly challenging as wanted to only change the color of the red parts into blue (or any given color into another given color), while keeping the same noise pattern. For the color itself I had to multiply the noise texture first by an alpha, which determines how far up the base the color change is, then by the color in order to have the color change follow the noise instead of being a boring flat line across the base. Fortunately I did most of the math and construction for this for the translucency of the material so I was able to re-use some of the graphing. That didn't stop me from having to do some wonky math in order to get the alpha working on a scale of 0 - 1 instead of something weird like 0.3 - 0.9, I wound up having to use multiply, subtract, add, and divide nodes at seemingly random values in order to get the alpha value range working properly. But, I eventually got it working satisfactorily.


Next post will be all kinds of catch up work, since life prevented me from posting here for a while.

 
 
 

Comments


bottom of page