Closing out MVP2
It has been three years since my last milestone completion. Over this time I got some work done, but ultimately had to put this work on hold. I took a detour to write a book on project management. If you want to check it out you can find it here (Is That Agile? book). Over the last several months I’ve gotten back to work and since it was a long time from the last milestone I figured it was time to ‘cut’ the release, review my progress, adjust my processes, and kickoff the next milestone.
The big items for MVP2 (that made it in) are:
- Performance Updates: Behind the scenes I made some major performance updates. Mainly the switch from Hazelcast to Redis and using Protobuf serialization give a great boost to performance. To compliment it I added a new micro-service who’s sole job is to calculate unit sight (which units can see which) with the help of 2d KVtrees (look up nodes based on x,y values pairs). This pulled heavy calculations off the unit AI processing to speed everything up.
- Pathfinding: An entire post was made about the flowfield pathfinding for this release All About Flowfields. It was an important thing.
- Purchasing Units: Purchasing units is the combination of making several UI pages, sending updated player info to the client, sending purchasing information to the server, anti-cheating mechanisms on the server, and updating player information correctly. The biggest benefits from this work is the unit details popup and the client updater micro-service, which is a better (centralized) place to update the player’s information so that we don’t end up in a race condition where updates are squashing each other.
- Carts: The cart is a unit to allow workers to deposit resources in a centralized place before taking it to the deposit buildings. The idea is that workers can hold a little bit but can harvest the resources, while the cart can hold a lot (and of multiple types) but not harvest. Future updates will have the workers automatically deposit and go back to harvesting if there is a cart nearby.
- Healers & Healing: This feature added assisting, healing, and updated seeking. Seeking is a unit looking for a target whenever it doesn’t have a current command it is working towards. Future updates will add stances (aggressive, defensive, and hold) that modifies how the seek behavior works (sight range, attack range, no seek, respectively). For healing specifically, I added the seek of friendly units and assisting. Assisting is like attacking but for friendly units, which heals if able a better way to deposit resources. Future updates will have assisting also check the assisted unit for being attacked and jump in to defend.
- Towers (Defensive structures): Adding attacking to buildings ended up being an odd feature to implement as I had to rewrite some of the code that turns units towards their targets, moves the unit if not close enough, and update the seek behavior to not work with attack range instead of sight range. Getting this done made the code a bit more complex, but sets everything up nicely for future work.
- Fog of War: I followed tutorials for this one. Extra cameras, projections, shaders…annoying things to program as I prefer server work.
- Threat Processing: I loved this feature and will be making an entire post on it for the future. It is a way to coordinate NPC units on a larger scale. That is non-player units (e.g. ‘creep’ or ‘NPCs’) don’t just exist on their own, they are spawned by a hierarchy of objects: Faction -> Keep -> Squad. Each Faction capable of being on the map exists in the background. They control squads of roaming units and Keeps. Keeps are the central structures of cities and a faction having the Keep under its control ‘owns’ the area. Keeps directly control other buildings and squads. Squads are controllers for groups of NPC units. If an NPC unit has an event (e.g. gets attacked, sees an enemy, etc.) it calls up to its owner (often a squad) with the event. That owner determins what to do and sends back a command to the unit and other units under its control. The owner may also forward the message up to its owner who can send down pass-through commands. For example, if a unit sees an army approaching it can tell its squad (“Hey, I need y’alls help here”), forward the message to the Keep (“This is too big for the squad to handle, send reinforcements.”), and possibly even to the faction (“AHH we are all going to die!”) for each level to send back overriding commands to help.
As tradition, I put together some demos of MVP2’s work. Enjoy!
A lot of great work. A bonus item was when I got back to the project with a new dev machine and a new raspberry pi and found all of the zone building things that I had manually adjusted but never fixed in the code. So fixing that up and containerizing everything with Docker helped me get back into the project.
MVP3: More MMO!
Onto MVP3, and this one will be huge! My goals for MVP3 is to add the ‘MMO’ aspects in beyond the persistent world. I’m doing this with 4 main parts of this MVP: Player, Units, Buildings, Map
For players this milestone will introduce player experience, levels, and specialization points. As players use their units in the world (harvesting, killing, healing) both the unit and player will get experience. Unit experience goes towards unit veterancy (small buff to the unit), while player experience goes towards levels. A player’s level affects the number of units they can have deployed, which units they can purchase, and how many specialization points they can spend. Specialization points are spent on unit upgrades and will allow players to specialize their army’s builds. For example, a player may want tougher & stronger workers to gather faster, or they prefer archers units and want to buff their range and sight, etc. The idea is to give players a path of progression and specialization
Second, for the units I want special abilities to be introduced. These are attacks or buffs that are triggered by the player, have cooldown, and are meant for situational use. While I have energy/mana in the code (it was added along side of health originally), I’m not sure I want to use it. It is an extra mechanic that has its uses, but also a burden. Will likely be saved for future milestones.
For buildings, I would like towns and cities to have meaning and a purpose for attacking and defending. This means two things: 1) higher ‘tier’ units can only be purchased at cities in higher ‘tier’ areas, and 2) buildings that aren’t used to purchase units need a purpose. For the first part think about the scenario where you have a ‘safe’ city where new players start. In this city you can purchase the lowest tier of units. Once you are at the level to mine the higher tier resources, you need to get to a higher tier towns, which have the resource nodes near them. Also in these towns may be high tiered unit stores (Barracks, Stables, Mage towers, etc.). If those towns happen to be under control of the enemy, you (and your faction teammates) need to take that town back!
At this point all cities and towns are populated by buildings that allow you to purchase units, resurrect the dead, or deposit resources. I would like these towns fleshed out a bit more. My biggest desire is to have houses and villagers to ‘liven’ up things, but this gives a unique design choice: “Why would an army care to defend villager’s houses?” I want players to care about houses being attacked, even if it is a minor concern. This milestone will see the introduction to areas owned by Keeps, and houses conveying an area buff. Unlike other buildings, houses will respawn over time without the player rebuilding. As more are respawned (meaning the area is more peaceful), units of that faction will receive bonuses like movement speed buffs, extra health, etc.
This housing & area control stuff brings us to the last set of features planned for MVP3: new maps & map display! Chiefly I want a new test map that is larger, can host multiple poeple, and has that tier progression. With this I’ll be adding a zone map where players can see the area borders, which faction owns which area, and ally troop movement. This is not a mini-map (which I do not want in the game on purpose), but more of a strategic overview.
The end goal is to have a playable demo. Since everything is still hosted on a raspberry pi it won’t be a large demo, but I’m hoping to have a nice multiplayer demo.