Up until now the UI programming for Mercury Fallen was relatively per interface/object. I have some top level classes that I made to inherit from that define a window panel consistently, but the UI for the different interactive objects in the game were all individually crafted which meant a lot of work if I’m creating a new object with a new type of functionality. This isn’t a problem with some games, but I wanted a system that would grow and adapt as i continue to add more content without having to re-write a lot of the same code over and over again.
The other concern were certain UI elements that are just naturally consistent across different types of objects. For instance the ability to deconstruct or if the object needs and is receiving power. What I needed was one window to rule them all. So to speak.
I had been thinking about a unified UI window for a while, but wasn’t sure how I wanted to structure it. The underlying data, however, already implies how it should be visualized.
The custom component infrastructure that I wrote already shows nicely how an object is represented and I just needed to reflect that in a user interface. Each entity in the game is mostly just a container for components which means each component can simply be a section within the UI, where applicable.
Not all components need a UI, but it could be good for debugging.
So now that I had an idea on the direction I just needed to visualize it. I figured the best way was sections and elements. Each component could define it’s own section in the interface and create the UI elements it needed to handle user input or just display information.
So as we can see in the above image we can visualize the components of the selected entity and we don’t really worry specifically about what it is we selected. Each section has it’s own controller which handles the logic and data binding to the component. The main window itself is just one master script/prefab for every object in the game. The master window determines which sections to add based on what components the entity has.
I spent this week connecting in various components in to the new UI system and so far it’s all going pretty well. It means more work now, but the trade off is that it makes adding new objects and UI functionality easier later as I continue to add new machines/furniture to the game. This new system also more flexibly allows me to add additional relevant information for the player to see when they click on various objects in the game.
Just finished up the first developer preview for Mercury Fallen which shows the game in action for the first time. The video doesn’t cover everything in there at the moment, but gives a good overview of the core mechanics of the game.
I welcome any and all feedback. 🙂
Building a flexible attribute system can be a challenging task, but the first step is always understanding what it is that you want the system to accomplish. I had already cobbled together a system for health, hunger, energy and mood, but it lacked ability for colonist attribute effects.
I wanted to be able to tack on effects like sickness that might temporarily effect health and mood temporarily until the effect goes away. I wanted a flexible system that would allow me to quickly tack on new effects without having to tie it in to the underlying values each time. I often confuse design problems for programming problems, but I think I have a good infrastructure for colonist attributes.
This really depends on the project, but I originally thought things like health, hunger and energy were attributes. This was true in a general sense, but lacked the detail I needed for adding attribute effects. Hunger, for instance, is actually three different attributes relating to its current value, max value and rate of change over time. Dealing with these values separately allows for them to be effected separately as well. An attribute is simply just a means of storing and manipulating a value via attached effects.
Health, hunger and energy become containers for attributes and each attribute has a list of effects that manipulate the underlying value. The colonist, via the component system, has Attribute Controller components attached. Each controller has a list of attributes that it monitors and each attribute has a list of attribute effectors that effect the final output value of the given attribute.
The attribute controller monitors its attributes and can make decisions about what to do under different circumstances. For instance health is simply current and maximum attributes and the health controller can let the colonist know that when the current value is 0 then the colonist should be dead. The attribute controller is both the container and what gives the attributes meaning.
Each attribute has a unique identifier and a list of attribute effects. We can get the final value of the attribute by adding/multiplying the effect values to the base value of the attribute. The attribute controller can then get this final value and never needs to know about what effects are currently being applied to it.
Attribute effects have a single attribute that it effects and can be permanent or temporary.
The above image illustrates the HungerController and its attributes. The HungerController uses the attributes to clamp the hunger_current to the hunger_max and allow hunger_rate to effect the hunger_current value. The hunger_rate, by default, is a negative value which decreases hunger at a fixed rate over time.
In this example I’ve attached an attribute effect which temporarily turns hunger_rate in to a positive number which will refill hunger_current. This attribute effect would get applied when the colonist eats some food.
I’m pretty happy, so far, with the result of the attribute system as it allows the easy creation of new attributes and effects. As with most everything else attributes and attribute effects are created in external XML files so that I can add new content without touching the code base. The only thing I can see adding at this point would be some sort of attribute effect group that would allow multiple attribute effects to be applied all at once.