Post Mortem: CreatureFeature

Published November 07, 2018
Advertisement

Creature Feature

 

As part of our first project for Studio 2, we had to create a creature-based AI. Conditions for this being:

  • Must be able to path find within the world. The pathfinding algorithms must be implemented individually. Built in pathfinding or third-party solutions are not permitted to be used.
  • A procedurally generated map or terrain for the AI operate in.

  • Have individual behaviours where the individual behaviours attempt to achieve some goal (eg. collecting food). Have a higher level AI that decides which behaviours to run.

 

My Creature Feature

Instead of a creature, I decided to use Taxi's in a procedurally generated city fighting over fares. Each taxi will have their own set of Trust logic and Behaviour logic systems with which they will be able to decide on whether they should help their fellow AI or not.

 

 

What went right

1.   Design / planning process

From the beginning it was important to me to layout everything in a manner I could visualise. This started with just writing down and setting the goals that needed to be achieved over the life time of the project:

  • Node based Movement and generation

  • Procedurally generated cities using Perlin Noise
  • A* pathfinding logic
  • Navigation system

  • Behaviour Logic
  • Trust Logic

Then from here working out which I needed to do first and start writing and planning the technical design. Even from early on I was creating images of the process I wanted to achieve, this is important for two reasons;

1: Visualising helps you think about how you want the thing to look and operate

2: Making these in a step by step process helps you find all the bits needed and possible issues early

 

Remembering as well that none of this is concrete and mostly likely your first plan will be your worst plan. Don’t feel tied to your first process.

This was one of the step processes I made for the map generation


1422754749_mapgenprocess.gif.d6489e7c8c5923a2632d089189e1199e.gif

 

The process I used here changed at least three times (and honestly even this process has changed slightly since release)

 

2.   A* creation

This was my first attempt at A*, it’s not perfect but I’m pretty without it came out. Once again (going to sound like a broken record here) I think I owe the success due to planning. By laying out the process in which you want to complete things it becomes easier to work out how that needs to be done.

This was the basis I worked A* off:

 

Need a list of all the node to process (Open list)

·         If the node has been processed (closed)

·         The cost to a node (G cost) and the estimated cost to a node (H cost)

·         The initial G cost for all nodes should be set to the max possible value

The starting nod is added to the open list, its G cost is set to 0 and its H cost is calculated
While we still have nodes in the open list:

·         Remove the node with the lowest total cost (F) from the open list. This is the current node

·         If the current node is our destination, then exit

·         Mark the current node as closed

·         Loop over all of the neighbours for the current node

                          Calculate the total cost (G) to the neighbour from the current node

                         In the new G cost is less than the stored G cost and the node is not closed

                                              Set the g cost of the neighbour node to the newly calculated g cost

                                              If the neighbour is not in the open list, then add it to the open list

                                         Set the current node as the parent of the neighbour

 

By following this process and taking time to plan out the technical design before touching code made for a much smoother project.

This was the results of me path finding from one seed point to another. 

 

Roadgen1.0.gif.2ee9b545c8c805fb93fdae6123df8660.gif


 

3.   Map generation  

As I mentioned before this went through multiple different design processes to try a create the best results and it showed. The first method used to create the maps and link the roads was actually the gif above. With each seed point connecting itself to every other seed point. However, this came out looking really messy and cluttered. So, after a conversation with a teacher I trailed a new process in which it was all split into sections (kind of like a city grid).
This came out looking pretty good and is the basis for my generation at the moment from here I made tweaks here and there and add new tiles to create more variation.

882975994_mapgencurrent.thumb.gif.ae2477410556807c0e5c0561c4bdf65e.gif


 

4.   UI

Considering this was a project exclusively based on coding this wasn’t exactly essential, but I feel like it having these “Creature comforts” (see what I did there?) made the sim feel a lot better while still being interactable.
The only issue that arose from this was involved with the mathematics for  generating the live table data. Which honestly wasn’t that big of a deal. Overall, I feel like the project came out looking the way I intended.

UI.png.bfaae839356f6aebad12848d1eec17a8.png

 

 

5.   Json Implementation
This was a core component of the project having state that could be saved out and loaded. Considering I’ve used json in the past it wasn’t much time to get this up and running, I just had to work out a few things with regenerating the map.
There were no issues here and it works great, it surprised me how fast it can write 50,000 lines to memory.

 

What went wrong

1.   Rewriting logic system
This was an interesting case, so previously I had divided up the logic of each taxi into two sections, the behaviour logic and the trust logic. The behaviour logic taking the grunt of the workload by being a giant state machine.
However because I was far ahead of schedule, my teacher suggested I tested myself and rewrite it to a different approach. That approach being GOAP (Goal Oriented Action Planning). I struggled quite a bit with this, new versions were vastly two complicated for my needs and older versions (such as Tyrion) were extremely hard to find information on (can you guess why with a name like that).
With a lack of understanding, I tried implementing a far more complicated system and ended up buggering myself spending much longer than I needed on this.

     585624793_goapbrain.gif.47a11b815ddf8738c88d6738e21219e1.gif
     With some planning help from my teacher though and some visualisation I created, I was able to finish it and I have to say its pretty sweet seeing in action. 

 

1641783795_goaptaxibrain.gif.c17c432a2502e93d959920b379648a69.gif

 

2.   Debugging logic

Oh boy, debugging AI logic, this was and still is (with some current logic bugs I have) a nightmare to deal with. Finding something that only happens at very ambiguous times and only happens on a Sunday (ok, I’m joking about that part) can be super difficult. Breaking up the logic into separate goals and actions for GOAP did help narrow down that process but I spent far too many hours attaching visual studio in debug mode to very little avail. 

 

What can I learn from this?

1.   Rewriting logic system

Using expandable and modular systems like GOAP are a great way to improve the quality of a project but it is important before making a start on it to know how complicated of a system is required for your needs and then planning the logic from there.

 

2.   Debugging logic

A couple of things here;

·         Create separate and well defined systems:

          So that it is easier to read and track

·         Take breaks from debugging:

           Go outside gets some air and give yourself some time to mull things over. This can save a lot of stress in the end

·         Ask for help / get a pair of fresh eyes:

          Similar to the above, you can be so focused on a particular thing that I can be hard to narrow something down. Getting another opinion can be really useful

 

 

Conclusion

For the most part I am super happy with how this project turned out, it has been one of my favourites so far during my time at SAE. Not only have a learned interesting and new practice methods but I also had fun while doing it and that’s the best you can really ask for.

 

 

 

Thanks for reading!

 

 

 

 

Development stats

·        Developer: Ben Walker

·        Link to project blog: https://blog248708493.wordpress.com/2018/09/27/studio-2-creature-feature/

·        Link to Sim: https://walkies3.itch.io/creaturefeaturetaxis

·        Length of development: 7 weeks

·        Development tools: Unity, visual studio, MagicaVoxel  

1 likes 3 comments

Comments

supermikhail

Interesting. My personal takeaway from coding AI is that it never goes according to plan. And yeah, I approve of going outside.

I'm wondering if the square grid was a requirement. I don't know if something different would have been possible, but the world's shape doesn't really seem to match what it's supposed to represent. I mean, those diagonal streets are looking pretty jaggy, aren't they?

Yeah, pretty cool in-progress animations too, of course.

November 07, 2018 06:35 PM
Ben Walker
19 minutes ago, supermikhail said:

Interesting. My personal takeaway from coding AI is that it never goes according to plan. And yeah, I approve of going outside.

I'm wondering if the square grid was a requirement. I don't know if something different would have been possible, but the world's shape doesn't really seem to match what it's supposed to represent. I mean, those diagonal streets are looking pretty jaggy, aren't they?

Yeah, pretty cool in-progress animations too, of course.

The square grid wasnt a requirement it was just how i built it. Felt it kinda worked with the voxel graphics. I could close the spacing on the nodes to remove the grid look of it.

You're right though some of the roads do come out looking pretty jaggered, i probably could do with changing the method to better reflect a city

November 07, 2018 07:02 PM
supermikhail

Hey, if you come across a good algorithm, don't forget to write an update! I'm kind of notorious for miserably failing to implement more and more desperate ideas for generating... non-rectangular mazes, I suppose one could say. Well, usually it just comes down to trying to connect random spots in the world. Which rarely produces anything suitable to navigation.

November 08, 2018 11:06 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement