Another long spaced post (???) about how things are going and are being built in the project. I’m doing this as a pause just so I can restructure my mind and verify if the code base foundation is solid enough for the next stage.
In the last two months I made progress towards having enemies fighting. I wanted to my heroes to be able to select that they wanted to hunt monsters among the other activities around the city. This forced me to carve a lot of code that wasn’t present on the last months:
- A small database with monster data, experience tables, skill descriptions, skill level unlock…
- A monster factory
- The agents needed to have some way to distribute the points as they level up
Most important I had to specialize some of the old classes that I build, majorly on the Action, Goals and Smart Objects.
I will start with the Actions classes and their structure:
-
IActionGOAP: Its a basic interface that holds the interface that are commonly used for all the actions, so the Goal Oriented Action Planning (GOAP) and other algorithms don’t need to know the type of action during the planning. All the other classes inherited from this one.
-
IndoorActionGOAP: Any action that is take inside a building, they are held by a Smart Object Building. The idea is that those are actions that will not need any special animation, but they need to have the agent directed to be inside the building. Think about the bathrooms on Roller Coaster Tycoon.
-
WorldTargetActionGOAP: Any action that can be taken in the map as long the agent is near enough to the action. Think about the scenery watching on Roller Coaster Tycoon.
-
SocialActionGOAP: Any actions that requires another agent to be performed. Now the reference is The Sims! This is the action that I’m using for initiate the combats. Its important to notice that those actions are generated dynamically. For now its just the combat considering “how many hits I need to win” for the hunt, but the idea is that the social aspect of the agents will be considered here. Again, The sims is the reference here and I want to add a small memory system and relationship between the agents.
-
InternalActionGOAP: Those are actions that the agent can take anywhere, like using a map, eating an apple from the inventory… The idea is that they don’t need to move anywhere to do this action.

From those basic actions now I can to do the specializations. I should be focusing on building the most generic actions like gossip in public, eat the apple, buy equipment and stuff, yet I’m starting to carve the other side of the coin on this AI engine: I’m building an Utility AI just for combat. This utility AI will be responsible to control the battle, pick the best skill for a combat for both agent and monster depending on the position of what they are seeing. Here my reference is Ragnarok Online, I can’t even deny it, visually will be appearing as an RTS, but internally this Utility IA will be working on turns, similar on how they did for Chrono Trigger where who finished the cooldown first was able to attack next.
Following the Actions, the Smart Objects also had to be specialized so now they can host those new specializations:
-
ISmartObject: Its a basic interface for all the Smart Objects, every Smart Object will be deriving from this one, so nobody needs to know the specifics and we use the polymorphisms to guarantee a unified interface.
-
WorldPointSmartObject: This smart objects will be holding only WorldTargetActions, they have a position in the world and a name. They probably will be having visuals in the final version of the game
-
SmartObjectBuilding: Smart Objects that are buildings that an hero can enter. They are circunded by a Flow Field, that when the hero steps into they are steered towards the door. My reference here is this article about Planet Coaster.
-
AgentOwnedSmartObject: Those smart objects are used by the agents for their Social and Internal Actions. A Basic Agent have a IInteractableAgent, which is an interface that all other agents can see, while agents that are running the planning also have a IIternalSmartObjectAgent that is an interface that holds all the internal actions. This way I guarantee that the external agents don’t even see the internal actions from other agents.

All of that means that I’m still on the black screen, reading code line by line. I had a conversation with a close friend who also does games and she is impressed on how much “I’m doing this right.”. The non visuals, no UI/UX, no sound, no nothing except code approach is very tiring for those who crave for progress, I can see that, but I’m enjoying a lot this “slow progress”. This “slow coding” is being very good for me to regain the notion of control around code that I lost by using third party engines over the years. As for documentation? Well, I didn’t to much of it, because I really don’t know how to keep this without being just a “look at the code and figure it out”, I don’t like the approach of describing the methods, the name should be enough. So if you see any comment inside it, read it, and that’s is being my approach to documentation. Future me will love or hate it.

The next steps are to start the Utility AI loop. I want this AI to control everything related with combat, but I still want to keep the agents autonomy just to abort the mission and run from the battle as soon as any other stats like the energy or hunger as too low. So the agents will keep their GOAP brain running considering the basic fight or flight while the fights runs.