Wednesday, July 16, 2014

Architect Game July Update

So as you may know some time around the middle of May I stopped work on the Architect game and started experimenting with the Unity engine.  I didn't really particularly have a goal in mind other than to learn something new which in itself can be a very admirable goal.  I ended up learning a lot about the engine through 2 small projects and I decided I knew just enough to get started on the project again but this time using Unity instead of my custom engine.  Using Unity was actually a pretty easy choice, it's a very strong engine that also powers the game RimWorld which has a lot of similarities to my game.



Tools


When starting over I made a decision to actually start the project over from scratch, which meant re-examining everything from the scope to implementation.  I decided that although my custom engine was data-driven it wasn't data-driven enough.  I was relying on scripting to create my data which worked but wasn't going to be sustainable long-term, especially when we started reaching dozens, if not hundreds of objects.  I needed a better system and so I started working on a data compiler.  The compiler turns the data I was putting by hand into scripts into intermediate data which then gets compiled into a resource file by the Unity engine's resource compiler.

For now the tool is fairly basic but it can and will become much more complex over the course of the project.  For one thing I'm able to use the same exact data structures in both the game and the tool,  so the code to save and load the data is the same in both places.  This means that when I need to add a property to objects I only need to make a change in one place, which is very welcome versus the effort required to making the same change in a script based system.

The tool is divided up by a tabbed notebook, each tab corresponding to a different type of data that gets compiled for the game.  Currently we have tabs for Sprites, Floors, Walls, Objects, and GameActions. The flow is probably not incredibly user friendly yet but since I'm the only user so far that's ok for now :).

Users are able to drag and drop in png files to the Sprites tab to add a new SpriteCollection to the data.  A SpriteCollection consists of the png file itself and a .meta data file created by the Unity engine which allows you to slice up the sheet into named sub-images.  Consequently when the user creates a new game object they can then choose from the SpriteCollections which have been previously added to the data.  This makes it very easy to update an existing object to use new images without touching any code.

Creating new game objects is a pretty straight forward process as tabs for each of the types that we have so far exist in the tool.  Adding or modifying existing data uses the same process.  The user can choose to add a new blank item and then modify its values individually or they can enter in all the values in one go and select an "Apply as New" option which then creates a new object using the given values.  When choosing to apply data in addition to writing to the active memory it also performs the file compile process so that you can be sure you won't lose any work.  Of course all my game data is saved in a git version control repository in case of disaster :).

AI and GameActions

GameActions are what drive the objects and people (Patron) inside of the simulation.  The concept of the design is based around the SmartObject system which was utilized by Maxis when developing The Sims.  A GameAction comes with lots of different configurable data to it, the important data being tied to a system of Action and Consequences.  Generally Consequences are defined into the system as a Reward for the Patron.  Objects themselves will hold the GameActions and "publish" them publicly for Patrons to listen to.  A Patron will then make a (hopefully) logical decision between available actions based on their given promised reward scenarios.  A Patron's action logic component (quite literally named: Brain) has needs which fluctuate based on several factors: the passage of time, their surroundings, and the results from performing GameActions.  For example one component of the Brain is it's need for energy.  When energy becomes it's primary need the Patron will seek out an action which promises a reward of energy revival.  Actions can promise varying degrees of rewards, for example a Buy Coffee action can reward a Drink Coffee action which gives +15 energy where a Sit Down action can reward just +3 energy.  Criteria can also be applied to the Actions, for example the Buy Coffee action might require $5 where the Sit Down action simply requires the Patron to walk to an available seat.  These criteria are used as a secondary driver to steer the Patron's logical decision making.  Optionally, diminishing returns can be applied to the actions as well, for example drinking the first coffee may provide 15 energy but immediately drinking another coffee will only provide 10 energy, and reduce from there.  An action's Diminishing Returns can slowly restore with the passage of time. This gives Patrons logical incentive to make other choices concerning how to attend to their needs.  Thresholds can also be applied to the Needs as well, at a certain point when energy level drops below a threshold that Patron will need to seek out a Sleep action which can award a fully refreshed energy bar.

One interesting part of the Actions system is that actions can publish fake rewards and forcefully chain the Patron into follow-up actions.  In the previous coffee example the "Buy Coffee" action can publish that it is rewarding 15 energy but upon completion it will actually reward 0 energy and force the Patron into a "Drink Coffee" action which will truly reward the energy.  With this system you can create some interesting chains of events and even get Patrons to do some pretty ridiculous things all in the name of fun of course.

Currently I have implemented the bare bones of the GameActions system into the game code itself.  Objects are able to publish events and Patrons can listen for them and choose their next action randomly without regard for their actual needs.  The next step is to integrate the creation of Actions into the editor, allow the user to link specific actions to objects, while also fleshing out the Patron's logical consideration for available actions.

All in all a lot of progress has been made but there is still a ton of work to be done.  I hope to make a demonstration video of the current state of the game available soon.

No comments:

Post a Comment