Dev Log

Jeremy Wolf Jeremy Wolf

NPC Job System

I needed a picture at the BEGINNING... At least it's a place of work?

My day job is at full speed with my weekends being controlled by bike races (head coach) so development is coming in spurts. It's disappointing to watch the slow crawl of progress, but at least the bike team is placing first in the conference! 

Ok, that's not why you came here... But while your distracted, if you didn't notice I've added a discord channel. It's quiet atm but feel free to stop by if you have questions or comments.

The big focus for the past month or two has been the job system. It is designed to the allow the player to hire NPCs to do basic jobs. These jobs are created from tasks which contain specific actions. These jobs are then "posted" and the NPC uses a simple  value system to determine what job they want to accept. The goal is that these jobs are superimposed on top of the NPC's other needs or desires and that jobs provide money for the NPC to provide for itself. The jobs also intended to speed up the progress of the player - rather spend time to chop wood they can pay an NPC to do it allowing the player to become more efficient and do more. 

The job system has developed in three major chunks. Code backbone. User interface. Creation of actions. 

Code Backbone

The base Actions class

The job system needed a generic framework that could be expanded and extended upon. To do this I broke the design into three main classes; jobs, tasks and actions. 

The job class is the boss of the whole deal. It controls the flow of tasks that the NPC will do and is also the communication link between the rest of the game and the job as a whole.

Task scripts are pretty similar to jobs in that they control the flow of what actions the NPC will do. Having a second container with no real effect made sense in that a task can fail and if the job contains more than one task the NPC would still be able to accomplish something... There is also the option (not fully implemented) that each task can have a time limit. The thought is that a NPC shouldn't spend 3 days looking for kindling if they could also be mining for coal. I'm not 100% sold on the need for tasks, but will likely leave them in for now. 

Actions are where, well, all the action happens. Actions are pretty specific and an individual job or task will likely have several actions. New actions can be added fairly easily due to the base class that is easily extended. Actions will include searching for items, dropping them off for processing or selling them to a vendor and whatever else seems useful.

The three classes largely communicate and interact by checking the status of their "subordinate." That is the job checks and reacts to the status of each task contained in the job and each task checks and reacts to the status of each action contained in the task. When all the actions in a task are complete the task is complete. When all tasks in a job are complete the job is complete and checks to see if it should repeat. Jobs can be done once, daily, continuously or a set number of times. For simplicity the status of jobs, tasks and actions all use the same enum - not started, running, complete, failed or paused. 

User Interface

The ugly current state of the Job Menu

There's a lot going on in the creation and the assignment of a job to an NPC. So the UI is probably the most complex I've made so far in my short dev career. Can I really call it that? I hesitate to even show it as it's so damn ugly, but it's easier to post a picture than describe it all. 

Essentially the left panel is where the job is constructed while the right panel contains posted jobs, saved jobs and inventory items that plug into actions. Not the most refined, but it's working (mostly). 

The job menu has already been through several iterations. With many more to come. I'm trying to hold off on the fancier bits until the full design is complete or at least closer to complete. Each new action makes me rethink the design of the UI or at least the action interface. Once the set of actions are more complete the design of the UI should come together.

Creation of Actions

The first action created was a rather useless one in that it was a random wander. Not something you'd likely want to pay some one to do, but served as a good testing grounds for the system as a whole. 

I would like to keep the number of actions fairly small, but still allow a wide range of jobs for the NPC to complete. Hunting for the system that allows emergent behavior! Currently actions are focused on the collection and delivery of resources. I hacked Inventory Pro to use the item database for the job actions. This greatly simplifies what I have to create and also helps keep a common interface and database.

At the moment I have one UI prefab for all actions and I am simply toggling on/off the needed parts. I'm not sure this is the best solution, but seems to be working fairly well. The toggling is controlled by a series of booleans in the actions themselves - the info in this communicated when the action UI element is created. 

So far the available options are an item, location, range from location, and a number of times to repeat the action. These options are holding up well with the exception of needing to show or indicate the location. At the moment the location is a vector3 which is pretty useless to the player... 

The Results?

The results of this work is a functional prototype of a job system. It's not complete, it's not ready to be added, but it was a proof of concept. The job system is likely to be left out of the first alpha build, but should make it's way in once the first couple rounds of bug fixing and balancing.

What's Next?

The job system was the last major piece of coding that needed to be completed in the prototype phase. So now the working goal is a fully playable alpha build. 

This leaves me focused on the visuals. In particular I begun the process of modeling buildings and working to refine my terrain creation process. I want to include rivers and waterfalls both as eye candy buy also as potential energy sources (hyrdo), but getting a low poly waterfall to look decent is tricky... but more on that in my next post.

I'll leave you with a WIP render of some market stalls.

A WIP render of market stalls - yes I know the lighting isn't awesome

 

 

Read More
Jeremy Wolf Jeremy Wolf

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...

A Chicken taking a stroll around a steam engine

A Chicken taking a stroll around a steam engine

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 my many static functions

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

Chopping down a tree with the CAW system

Chopping down a tree with the CAW system

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

Mining a cube... Can we all say "Place holder?"

Mining a cube... Can we all say "Place holder?"

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

Basic building using the Progress bar

Basic building using the Progress bar

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?

Chicken Cam! 

Chicken Cam! 

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. 

 

Read More
Jeremy Wolf Jeremy Wolf

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.

Read More

Older Posts