Dev Log
Resources and Resource Systems
Progress on Game #2 marches slowly towards the goal of have a "releasable" product. Not a Steam ready product, but a product ready to tested by others. So much work to do...
In my first game I made the mistake of implementing "feature X" and then "feature Y" only to have to go back and hack the code for "feature Z" into the code base. I had no idea how to make my code easy to use or easy to extend. Simply adding a new building to a menu took hours... Oh the mistakes I made!
In my current project adding a new building to the UI takes approximately 45 seconds.
With game #2 I am trying to build the systems before adding any significant content. I don't expect flawless execution of this, but when I find myself writing code that will only work in one situation or copying code and only changing the value of a string I'm trying to step back and generalize or abstract the code. I'm making better use of getters and setters to keep behavior consistent and spaghetti code to a minimum, more of my variables are private and I'm making (some) use of the delightful world of static classes and static methods.
I have a bit of a man crush going with static methods at the moment.
One of those static classes is a "Helper Function" class that contains static (naturally) methods for things such as finding the nearest gameObject with a given component (good for snapping functionality), or finding the distance to a player or rounding a vector3. Not methods that every class needs, but methods that are needed frequently and all over the code base. I'm learning to do things better. Slowly.
Static lists are doing good things too especially when it comes to searching for components in a scene. Several of my more common classes add their instance to a static list when they are initialized (and remove themselves when they are disabled). This allows for the quick searching of a list of components rather than a more time intensive "Find Objects of Type" situation.
I don't think the extra memory usage a concern, at least not for now.
All of this is helping to create a more manageable code base.
So what is the result of all this work?
Energy Mechanics
The focus has been to get the basic resource mechanics working. As mentioned in an earlier post Energy is Everything, so getting the "generation" and delivery of energy working was a major goal. At the moment energy is broken down into two categories, mechanical and electrical. Steam engines, wind turbines (not yet implemented), maybe solar (these aren't functional yet either) and even hand cranks will generate energy. While generators and motors will convert between the two types of energy.
The current design vision is that energy sources can be attached directly to objects that need energy or that energy can be converted to electrical energy - at a cost - and transmitted via power lines or some other transmission mechanic.
The energy mechanics are largely functional and the parts that still need work should be easily created by extending the code that already exists. Getting this all working took several iterations and several bouts of refactoring with careful choices on script inheritance. There is, of course, plenty of tweaks and balancing that will need to be done, but the basic framework is in place and working well. Check!
Resource Gathering
I want to keep the resource gathering simple. I also want to make it easy to extend or add new resources. Can you sense a theme? So once again the focus was on building the base mechanics - which certainly needs some tidying and refactoring, but by in large the mechanics are functional and I'm happy with the product at the moment. Inventory Pro has gone a long way in helping structure much of the resource code - both in good ways and bad - the built-in item types and categories provide a natural structure for the resource content.
Currently, I'm focusing on wood/lumber gathering and basic mining. These should provide several resource loops as well as the basic building materials for all (most) structures. Or in other words, hopefully enough content for alpha build.
Logging
With the logging I started working to get the visuals right before tackling the coding or player side mechanics. Maybe this is backward, but if chopping down a tree didn't feel good it wouldn't matter how great the code was...
So, in Blender I took a basic tree model and added a loop cut to the trunk to allow it to split into two parts. I spent a few hours adding colliders, rigidbodies and tweaking physics settings until I arrived at something that felt decent. A particle based dust cloud finished off the chopping down of a tree and I was ready to implement the chopping mechanic.
I love physics. Both as a subject and as a game feature/tool. My trees use physics to fall. So why not use physics to chop the tree down? I added a trigger to my axe and a script to my tree. Hit the tree the right number of times and ... Timber!
I loved it. Until I had to line my character up with the tree. Ugh.
Trying to get a third person character lined up with a tree and get with in the range of the axe's trigger is doable, but that's not generally how you want to describe a commonly used game mechanic. "Oh yeah, it's 'doable.'" Cutting down a tree is not supposed to be the hard part. Did I mention the obvious fact the that axe is in front of the avatar so the player can't see it without rotating the camera.... Not awesome. So back to the drawing board.
I paused my work with logging and moved on to mining.
I often find when I'm stuck on a problem, big or small, moving on to another task often results in a more creative or at least better solution.
Mining Mechanic
I started with this Minecraft like vision where players would build an above ground mine and then be "transported" to a mine full of cubes. I wrote some code to generate the mines and place them below the game world. I added walls to limit player movement as well as block out the directional lights from the outside world.
Why not just have a new scene you might ask? I want/need the simulation in the outside world to continue and I also want NPCs to be able to visit a mine.
It was all looking good, I was feeling good about my mining solution. That is until I placed my player into the mine. Damn walling clipping! I immediately saw the huge flaw in my plan. It didn't take 3 seconds to know this approach wasn't going to work. Totally dead on arrival. The camera was clipping through everything. It looked horrible, especially when the camera was outside of the walls looking at the world above and the vast nothingness below.
Again, a new approach was needed. Something that will feel good and look good.
At times I wonder if I implement ideas from others because I'm lazy or maybe because they realized the issues and designed around it... Hmm. Good artists copy, great artists steal?
Click and Wait
With the tree chopping feeling lousy and the mining mechanic needing to be redone I decided to implement the classic "click and wait" (CAW) mechanic with mining just to see how it felt. And by CAW I mean that a player would walk up to an object, click the mouse and wait for an animation/action to finish. When the animation is finished the resource (or whatever) is ready to be collected. Add a progress bar to this and you've got nice, easy, and hopefully well understood feedback to the player.
It may be not be very creative. It may be fairly cliche. It may be a lot of things. But most importantly it feels good. The player walks up and clicks. The computer does a quick distance check and the progress bar starts doing it's thing. It's so much easier. Not only that but the previous method didn't really communicate to the player what was happening. Sure the old physics based approach had sound effects and particles when the pick axe hit the chunk of ore, but nothing much happened when you missed... Not good design. The progress bar, as cliche as it may be, teaches the player what to expect and gives near immediate feedback as to whether something is working or not. That's worth an awful lot in my mind.
The CAW mechanic felt so good I immediately added it to the chopping down of trees. While I miss the elegance of the physics based solution, as soon as I had the CAW working it was way more fun. I made a line of trees to just cut them down over and over... for testing purposes! I spent a little time appreciating the sounds, particles, motion and general goodness of how it felt. Hopefully the future players won't even notice - it'll just feel right and never get much attention.
Best of all with a little clever refactoring, the CAW mechanic can be applied quickly and easily to other game mechanics.
Freezing Player Input
When I was first coding up the farming scripts I made the decision to freeze input to the player and rotate the avatar towards the point of action. This did a couple things. First it helps the animations look better. It's pretty silly if your character is facing left and dirt is flying on the right... Second it solved the issue of the player interrupting an action part way through. While I like the idea of the player having control, breaking out of an action requires a good deal more code and bookkeeping then simply knowing the action will be complete.
As the only player tester, I thought it felt pretty natural and normal. I was more engaged with where I was clicking than the direction that my character is facing. Hmm. It would be interesting to get feedback on this. Maybe I'll implement hitting the "escape" key to break out of a CAW loop. So far it doesn't seem like a game where cutting down the wrong tree or planting a carrot in the wrong spot would impact game play much...We'll see.
Progress Bar
My progress bar at the moment is nothing fancy. Just a UGUI slider with the handle turned off. Maybe I'll make a dial or a circle or some thing with a little more style, but for now it works.
As of now I only foresee one (player) action happening at a time I added static methods (of course) to the script on the progress bar. This allows any script to call the progress bar and update it's value. No need to grab an instance via script or drop in a component in the inspector, simply call ProgressBar.UpdateValue(value) and the progress bar will toggle itself on and display the appropriate value. Have I mentioned how much I love static methods?
What's Next?
So what's coming next? I've been avoiding working on the AI side of things. Partially because I'm not 100% set on all the details of the game and also because, well, I know it's going to be hard. After watching "Less is More : Designing Awesome AI" I was encouraged to truly start simple. No need to plan out the entire AI, but rather start with basic functions and features, adding and tweaking until it behaves in a way that adds to the game.
I'm starting with farm animal AI. Why you might ask? I'm starting there as a way to learn and get familiar with Behavior Designer (my chosen AI solution for #2). Surely a behavior tree is over kill for a chicken, but I want or rather I need to start simple.
Â
State of the Game - Episode 1
I thought I'd give the good old video dev log a try. The video shows off some visuals in the first scene and then gets to more game mechanics in the second test scene. There will be a write up of the new mechanics coming soon as well.
Let me know what you think about the format or any questions you may have about the game.
Resources: Processing, Consumption and Inventory
As a solo developer (of an admittedly over scoped game) relying on outside assets is a key to building a game "quickly" and efficiently. I'm not the type of person to subscribe to the idea that I need to build everything from scratch. I have no desire to build my own game engine, but I do understand why folks often prefer to roll their own solution.
I've become very skeptical of assets that run with the game. I have learned that editor tools are more reliable and don't come with performance downsides that many runtime assets do. I've tried using several assets that are overly bloated or have turned out to have poor performance. My snow shader and graphing tool came out of such experiences. It's a tricky to find the balance between using pre-made tools and rolling your own. There are pro's and con's both ways.
Game #2 will allow players to collect and use items - this will in fact be a key mechanic. This means that I need some kind of inventory solution. I did a little research on how to do the basics, but decided to also look at solutions on the Unity Asset Store. If nothing else the Asset Store can be a good source of ideas.
As a Unity Plus subscriber I get discounts on a handful of assets. One of those assets is Inventory Pro. So I figured it was worth a look since I was shopping for a inventory solution and the reviews were nearly flawless.
I watched the tutorials and did as much research as I could. While not "cheap" it's an asset that would take me several days if not weeks to reproduce even in the most basic of forms. Plus it has a level of polish that would take even more work on my part. So why not give it a shot?
I made the purchase and spent some time playing around. My first impression was positive. It has a nice and easy to use editor. Out of the box it handles person inventory, vendors, looting, banks, a skill bar and two styles of crafting. It comes with a pretty decent default look too (but, I suspect almost any developer will want to modify it). What's not to like about it?
Inventory Pro also plays nice with several other popular third party add-ons. This includes Playmaker for those who don't want to dink around in C#.
It also has custom functions for Behavior Designer which is a major plus in my book as I intend to use Behavior Designer as my AI engine.
If you are intending on building game with a fairly typical or standard use of inventory then Inventory Pro should be on your short list of assets to check out. However, if your design has some non-standard uses you should keep reading.
The Other Side of the Coin
As I continued to explore and think more about the custom needs my game was going to have I was becoming discouraged. The code base is all open source, which is greatly appreciated, but it feels like a mess of inherited classes and prefabs. Ugh. The documentation is decent, but doesn't do a great job of describing how to truly customize the tools. The learning curve is moderately steep.
The odd blog post by the developer were very helpful and cut hours out of my work. The needed info is out there, but it can be a little hard to find.
When trying to setup a scene you can't simply drag and drop UI prefabs in the scene. They don't easily slide into a scene because there are too many connections that need to be made. Too many prefabs that need to be dropped into the inspector or combination of components that are required. It's certainly possible, but it's not easy. Adding the UI to a scene is best done by copying from a demo scene and then turning off the parts you don't need - a custom editor to add the parts you want and get them all connected correctly would be a major plus and make the product that much more user friendly.
There is a cost to using someone else's code base... That shouldn't be a real surprise. I got frustrated enough with Inventory Pro that I spent a few hours working to roll my own custom inventory code. It was all going well until I began to write a custom editor to create content. I went running back to Inventory Pro and I'm very glad I did.
Custom Windows
For Game #2 I need some custom windows for resource consumers and resource processors. A resource consumer could be something such as a steam engine from my previous post that may take in wood or coal and produce a more usable form of energy. While resource processors may be something such as a windmill that will process corn into corn meal that can be used to feed your chickens, i.e. turn items into other items.
Each of these custom windows is easy enough to create from a purely UI perspective, but coding them took a bit more especially as I was to digging through someone else's code.
A resource consumer is very similar to a vendor in that individual objects in a scene will have there own collection that is loaded into a common UI. The main differences being that the resource consumer needs to do something with the items even when the player is not currently using that object, i.e. a steam engine should continue to burn coal and produce energy when the player is busy elsewhere and I don't want to be selling coal to a steam engine...
Rather than inherit from the vendor classes, which would bring functionality I didn't want, I chose to essentially copy the vendor scripts (ItemCollection and Trigger) and modify the scripts once I had basic functionality working. The result was a custom trigger script, custom UI window (damned ugly at the moment), a custom collection script that controls what is shown in the UI as well as a base class resource consumer that is designed to be extended for a variety of resource consumer objects (steam engine, chicken feeder, etc).
The resource processor is a bit different. At its core resource processing is very similar to crafting. Items go in and products come out - all following a blueprint. Given that Inventory Pro has a built in crafting system it seemed worth the time to fight through the code to create a custom "crafting" window that would meet my design needs.
The idea here is a that a player (or NPC) drops off some items to be processed and it gets turned into a different item that can later be collected. This means that the UI needs to have an input and a output collection/inventory. It's also required that each individual scene object has it's own input and output collections to that get loaded to the UI when the player interacts with the object. A final two requirements is that the resource processor continues to work when the UI is closed and that the products get assigned to the correct scene object when the processing is done so the product doesn't get lost and the player can collect it later.
This last requirement was the biggest hurdles and required about an hour of hunting through code to follow the flow of the information. Inventory Pro has a "craft info" class that contains all the basic information which gets passed through about 8 different methods before an new inventory object is actually created.
I almost lost it at this point. Lots of deep breaths needed.
To get it all working required an addition to the CraftInfo class to track what object had ordered the product to be created. This allows a finished product to look up where it was supposed to go and assign it to the appropriate collection.
Custom Inventory Items
While I found the process of adding custom windows and functionality challenging and frustrating, adding custom inventory item types was easy and almost fun. Out of the box Inventory Pro comes with several default item types, but anything beyond the typical RPG will likely require custom item types.
Different types have different properties (oh, shocking). These properties are not particularly well documented or at least I haven't found the documentation. Thankfully most are self explanatory.
Game #2 is not the typical RPG with the collection, crafting or upgrading of gear playing a central role. Rather most inventory will have some use in creating something in the world. This might be a shovel that is used to prepare the ground to plant a crop or coal that will be used by a steam engine to power an industrial building. Inventory Pro's items all inherit from a parent class that calls a Use() function. This function can easily be overridden to perform any actions needed. The Use() function is called when the player uses the object. Which can be done from inside the inventory or from the skill bar.
The Use() function returns an integer that indicates whether the object can be used.
In the case shown using the tool will call an outside public function that toggles a mode of the game (i.e. use a shovel and you can dig to plant seeds).
The inventory item can also have public variables that will be displayed in the Inventory Pro editor. For example the Tool Type enum can be set for each inventory item of this type inside the editor which makes for easy and organized content creation.
The ease of creating custom inventory items was a stark contrast to making custom windows and triggers. Why can't the rest be this easy?
The Final Verdict - Inventory Pro
Inventory Pro caused me a good amount frustration, plenty of swearing but also gave me a much more functional inventory system than I could have created on my own.
If you are looking to build a game with non-standard use of inventory and aren't comfortable with C# then you should probably look else where or be willing to hire a programmer to code up some custom solutions.
But if you don't need custom functionality or if you are comfortable with C# and reading someone else's code then Inventory Pro can solve your inventory needs far quicker than you'll be able to roll your own solution. Mucking around with the custom windows wasn't particularly fun, but the end product was worth the time and money.
Older Posts
-
April 2024
- Apr 10, 2024 Ready for Steam Next Fest? - Polishing a Steam Page Apr 10, 2024
- Apr 1, 2024 Splitting Vertices - Hard Edges for Low Poly Procedural Generation Apr 1, 2024
-
November 2023
- Nov 18, 2023 Minute 5 to Minute 10 - Completing the Game Loop Nov 18, 2023
-
September 2023
- Sep 13, 2023 Visual Debugging with Gizmos Sep 13, 2023
-
July 2023
- Jul 4, 2023 Easy Mode - Unity's New Input System Jul 4, 2023
-
May 2023
- May 19, 2023 Level Builder - From Pixels to Playable Level May 19, 2023
-
April 2023
- Apr 11, 2023 Input Action in the Inspector - New Input System Apr 11, 2023
-
February 2023
- Feb 26, 2023 Tutorial Hell - Why You're There. How to Get Out. Feb 26, 2023
-
December 2022
- Dec 31, 2022 Upgrade System (Stats Part 2) Dec 31, 2022
-
November 2022
- Nov 10, 2022 Stats in Unity - The Way I Do it Nov 10, 2022
- Nov 5, 2022 State of UI in Unity - UI Toolkit Nov 5, 2022
-
August 2022
- Aug 17, 2022 Knowing When A Coroutine Finishes Aug 17, 2022
-
April 2022
- Apr 23, 2022 Unity Input Event Handlers - Or Adding Juice the Easy Way Apr 23, 2022
-
March 2022
- Mar 15, 2022 *Quitting a Job I Love Mar 15, 2022
-
February 2022
- Feb 8, 2022 Split Screen: New Input System & Cinemachine Feb 8, 2022
-
January 2022
- Jan 24, 2022 (Better) Object Pooling Jan 24, 2022
- Jan 19, 2022 Designing a New Game - My Process Jan 19, 2022
- Jan 16, 2022 Strategy Game Camera: Unity's New Input System Jan 16, 2022
-
December 2021
- Dec 16, 2021 Raycasting - It's mighty useful Dec 16, 2021
-
November 2021
- Nov 22, 2021 Cinemachine. If you’re not. You should. Nov 22, 2021
-
August 2021
- Aug 3, 2021 C# Extension Methods Aug 3, 2021
-
June 2021
- Jun 27, 2021 Changing Action Maps with Unity's "New" Input System Jun 27, 2021
-
May 2021
- May 28, 2021 Unity's New Input System May 28, 2021
- May 8, 2021 Bolt vs. C# - Thoughts with a dash of rant May 8, 2021
-
March 2021
- Mar 10, 2021 Coroutines - Unity & C# Mar 10, 2021
-
January 2021
- Jan 14, 2021 Where's My Lunch? - January Devlog Update Jan 14, 2021
-
December 2020
- Dec 27, 2020 C# Generics and Unity Dec 27, 2020
- Dec 7, 2020 Steam Workshop with Unity and Facepunch Steamworks Dec 7, 2020
-
November 2020
- Nov 27, 2020 Simple Level Save and Load System (Unity Editor) Nov 27, 2020
- Nov 9, 2020 Command Pattern - Encapsulation, Undo and Redo Nov 9, 2020
-
October 2020
- Oct 28, 2020 GJTS - Adding Steamworks API and Uploading Oct 28, 2020
- Oct 9, 2020 Game Jam... Now What? Oct 9, 2020
-
August 2020
- Aug 16, 2020 Strategy Pattern - Composition over Inheritance Aug 16, 2020
-
July 2020
- Jul 24, 2020 Observer Pattern - C# Events Jul 24, 2020
- Jul 15, 2020 Object Pooling Jul 15, 2020
- Jul 3, 2020 Cheat Codes with Unity and C# Jul 3, 2020
-
June 2020
- Jun 16, 2020 The State Pattern Jun 16, 2020
-
August 2019
- Aug 12, 2019 Easy UI Styles for Unity Aug 12, 2019
-
July 2019
- Jul 3, 2019 9th Grade Math to the Rescue Jul 3, 2019
-
June 2019
- Jun 12, 2019 Introducing My Next Game (Video DevLog) Jun 12, 2019
-
May 2019
- May 29, 2019 Programming Challenges May 29, 2019
-
March 2019
- Mar 2, 2019 Something New - Asking "What Can I Learn?" Mar 2, 2019
-
November 2018
- Nov 30, 2018 A Growing Channel and a New Tutorial Series Nov 30, 2018
-
October 2018
- Oct 11, 2018 Procedural Spaceship Generator Oct 11, 2018
-
July 2018
- Jul 11, 2018 Implementing SFX in Unity Jul 11, 2018
-
May 2018
- May 31, 2018 Prototyping Something New May 31, 2018
-
April 2018
- Apr 17, 2018 When to Shelve a Game Project? Apr 17, 2018
-
February 2018
- Feb 9, 2018 State of the Game - Episode 3 Feb 9, 2018
-
December 2017
- Dec 16, 2017 State of the Game - Episode 2 Dec 16, 2017
-
November 2017
- Nov 7, 2017 The Bump From A "Viral" Post Nov 7, 2017
-
October 2017
- Oct 30, 2017 NPC Job System Oct 30, 2017
-
September 2017
- Sep 1, 2017 Resources and Resource Systems Sep 1, 2017
-
August 2017
- Aug 3, 2017 State of the Game - Episode 1 Aug 3, 2017
-
June 2017
- Jun 20, 2017 Resources: Processing, Consumption and Inventory Jun 20, 2017
- Jun 15, 2017 Energy is Everything Jun 15, 2017
-
May 2017
- May 16, 2017 Graphing Script - It's not exciting, but it needed to be made May 16, 2017
- May 2, 2017 Tutorials: Low Poly Snow Shader May 2, 2017
-
April 2017
- Apr 28, 2017 Low Poly Snow Shader Apr 28, 2017
- Apr 21, 2017 Environmental Simulation Part 2 Apr 21, 2017
- Apr 11, 2017 Environmental Simulation Part 1 Apr 11, 2017
-
March 2017
- Mar 24, 2017 Building a Farming Game Loop and Troubles with Ground Water Mar 24, 2017
-
February 2017
- Feb 25, 2017 The Inevitable : FTF PostMortem Feb 25, 2017
-
December 2016
- Dec 7, 2016 Leaving Early Access Dec 7, 2016
-
November 2016
- Nov 28, 2016 Low Poly Renders Nov 28, 2016
- Nov 1, 2016 FTF: Testing New Features Nov 1, 2016
-
October 2016
- Oct 27, 2016 Watchtowers - Predictive Targeting Oct 27, 2016
- Oct 21, 2016 Click to Color Oct 21, 2016
- Oct 19, 2016 Unity Object Swapper Oct 19, 2016
-
September 2016
- Sep 18, 2016 Testing Single Player Combat Sep 18, 2016
-
May 2016
- May 25, 2016 Release Date and First Video Review May 25, 2016
-
March 2016
- Mar 26, 2016 Getting Greenlit on Steam Mar 26, 2016