Last week I did the following, in order:
- Finished the Family Tree UI
- Had a son IRL
- Opinion system
- Companies, Raids & Garrisons
If you consider that I mostly work on this a few hours at night (these posts get worked on during lunch breaks) this is quite a bit of stuff actually. Today I want to talk briefly about each of these, and then go into how I was able to add four significant systems in a short amount of time.
The family tree UI shows you three generations around a particular character: parents, siblings, and offspring. You will be able to open it for any character you know about, and can click through the characters in the family tree to explore other branches or generations. The work here was mostly creating the layout for the portrait widget I finished last week. I also added some decorations to the portrait widget to show if a character is a family leader or heir, or dead.
The opinion system tracks the relationship between two characters and is very simple. An opinion value can range from -100 to 100. At first I was going to create data that would track this value between every character in the game. This would do the trick, but offered no way to know more about the value. Instead I implemented a system that tracks the changes to opinion between characters and then calculate the opinion value dynamically.
The base opinion value between characters is zero. This is represented by there not being any OpinionModifiers. As actions unfold in the game simulation events can generate OpinionModifiers that specifies the characters involved, the value of the modifier, a reference to the action that generated it, and an expiration date. When and how significant these modifiers are is determined by the data the designers put into the game.
The vassal system operates very similarly to the opinion system in that a Vassal record is created when there is a relationship between two characters. I defined two types of vassals you can have:
- Personal - these are the folks you support financial who protect you, follow you around, and can act on your behalf
- Landed - these are other lords, with their own lands, who can owe you service of the following kinds:
- Harvest tax - a tax in kind on resources collected twice a year in the harvest
- Trade tax - a Coin tax the amount of trade in the vassal’s settlement
- War tax - a special Coin tax
- Military service - the vassal can show up in person, or send another commander, with a company of troops
At the moment you can offer and accept entering into a vassal relationship but the landed vassal interactions will come later.
In order to ask/threaten someone to become your vassal you need to be able to communicate with them, right? There are going to be other ways to do this later, but in 2.0 you are able to compose messages and then command a character to deliver it for you. The different messages in the game right now are:
- Gift (Coin)
- Bend the knee
- Offer vassalage
Its obvious what these are - the very basic things needed to modify opinions and start building your feudal empire! I am debating with wether messengers can/should get waylaid and messages read by others - but for now they are safe.
I also think a signal fire system that would support a few basic messages would be cool.
The military functions in Fealty fall into two camps broadly speaking - war and non-war. Things like armies (big groups of units), battles, sieges and conquest is coming later. For now the focus is on the non-war which is mostly focused on Raids.
Raids are low-scale actions performed by small number of troops that primarily performs economic damage. Raids are important because they are a way to both gain resources, deny resources to another character, and slow their economy by damaging their structures. Besides the economic impact, raiding is also a way to subdue another character who needs convincing to bend the knee. If you are able to impair a lord’s economy significantly it can have repercussions in your negotiations. Or they might just grow to hate you and never ever forget. In this way raids are as much a political tool as a strategic one.
The basic military unit in 2.0 is the Company. A company is a single group of soldiers under the command of a character. (You will be able to equip them later) A company can be of two types:
- Mercenaries - professionals recruited with coin and who “reward themselves” from plundering
- Levies - serfs conscripted into service for a specified duration of time
Mercenary companies cost money, while levies are free. But levies come from your working population and also can’t be kept under arms for very long.
Garrisons are military units idle in a settlement. Beside being idle in Garrison, and moving to a different friendly settlement, you can command a company to perform a raid - but thats it. Companies do not move around on their own (armies will - later). As a result of this I am removing the supply component from companies - they will eat from the food in the settlement, and they are only away from it briefly.
So, how was I able to jam all these things so quickly?
Firstly, the because architecture does a good job of keeping these systems separate I can add a lot of functionality in just a few classes. In the post about the architecture for the game, I described how the game loop works - briefly:
- Player (or AI - they are players too) does something pushes a button which creates a Command to the game
- The Command is sent to the server who validates it and tells the local game wether to apply it or not
- The Command is executed and it generates StateChanges that are applied to the game simulation
Everything in the game works this way. The key parts of the architecture is that the logic for Commands and StateChanges are contained within themselves and are referenced through polymorphic interfaces. The longest part about implementing a new command is figuring out what kinds of StateChanges it needs to kick off. Each type of StateChange is represented by a class in the code so I try to write them in a way that will enable them to be re-used from a design perspective it as much as possible.
The pseudo code for a character reading the insult you sent them would look like:
(Each item is a StateChange)
- Mark the message as READ
- Generate an OpinionModifier record from the insulted character to the insultee
- Possible generated a StateChange that triggers a message response being sent back
The second reason is that where a lot of these things do start to come together is the UI and I am saving that for when the major systems are in.
I am both not/looking forward to finishing up the tech and moving to UI. Like so many backend developers it is not my forte - but I know that it is important to get that right for people to be able to enjoy the game. For Alpha 2 I am going to drastically simply things while attempting to improve usability - but more on that later.
Thanks for reading. You can find more information about what I am working on on the Trello Roadmap.