Steady Progress

It has been a while since the last post, but don’t worry, we are still making steady progress. Bugs have been fixed, code has been rewritten, and even a few new features have been added. And the game continues to feel more like a game.

The first major change – almost every model is now an original model. Only the villager and iguana models are taken from the asset store. The world now looks consistent.

One of the major behind the scenes efforts was a change to support loading definitions from json files. The types of structures, the different items and the various plants. Almost everything in the game is defined in a json format now. We’ve also added the ability to reload these definitions at run time, which allows us to experiment with gameplay without being forced to reload the game. It also simplified a lot of the code, and will pave the way for modding.

  {
    "Type": "ItemDefinition",
    "Name": "IronPickaxe",
    "WeightPerUnit": 100,
    "ItemTypes": [ "Pickaxe" ],
    "Recipe": {
      "Type": "BasicTools",
      "WorkToComplete": 200,
      "RequiredItemTypes": [],
      "Ingredients": [
        {
          "ItemDefinition": "IronOre",
          "Quantity": 1
        },
        {
          "ItemDefinition": "WoodShaft",
          "Quantity": 1
        }
      ]
    }
  },

We also needed a system for displaying alerts to the user. “You are running low on food.” “You need more wood to build that house.” “Frank is on fire.” The alert system is in place, but only has placeholder alerts for now that allow us to test the functionally. A real user isn’t going to care if the hour is odd or even.

Growing and harvesting crops is one of the features we’ve added. A tiled area can be designed as a crop field. The field can be rotated and doesn’t have to align to the world. Your villagers will till the soil, plant and water the crops, and then harvest them when they are ready.

There is now a main menu that looks passable, and allows you to load an existing game or start a new one.

The basic versions of save/load in the game are also added.

In the from the ford universe we want summer to have long days and the winter nights to be long. The original approach to accomplish tried to model the real world, and use tilt on a rotational axis. This was way too much work. Instead we went with the flat earth model with a sun that orbits the flat earth and changes speed based on the time of year and time of day/night. Just a little bit of math.

Most of our testing originally involved a single villager. As soon as we added more to the mix, all kinds of problems came up. A reservation system was built to allow villagers to reserve a tree, a structure, an item they want to pick up. This ensures that two villagers aren’t trying to do the same thing at the same time.

IcoMoon in Unity

I’d like to start off by saying I don’t know how this approach compares to other possible approaches to icons. For now it works and isn’t that annoying to deal with when I have to add/change icons. After watching this amazing talk recently I don’t see any reason to change my approach at this point.

Recently I spent some time cleaning up the UI in From The Ford and as part of this effort I needed some proper icons. What wasn’t proper about the old icons? Would you recognize this as a play icon?

I first started down the path of creating images for each icon that was needed. At some point while looking for icons I decided to check out the icomoon icon set. Some of them weren’t bad and I proceeded to go through a painful process of trying to convert screenshots of the icons into images. This worked but it wasn’t ideal. At this point I got to thinking.
Why can’t I just use icomoon as it was intended?
If icon fonts work on the web, shouldn’t they also work in Unity?

Icon Fonts

For those of you that aren’t familiar with icon fonts – The general idea is to create a set of font files with icons instead of regular characters. When used on the web this allows you to fairly easily change sizes, colors, and even add shadows to icons. The icons will scale well compared to traditional image tag icons. The web does seem to be moving to svg tags for icons, but that isn’t really relevant to this post.

Creating your icon font

Navigate to https://icomoon.io/app/#/select to get started with the icomoon app. The icomoon app allows you to select which icons you want in your icon font. There are a number of different icon libraries available. The licenses on them vary, so pay attention if you are planning on using them for more than just placeholders.

First select any icons that you want to include.

Click “Generate Font”, this will show you any icons that you have selected. For now click download

Extract this zip into a location inside of your Unity project.

At this point Unity won’t be very happy. The zip contains a .js file which Unity tries to treat as a UnityScript file. It may be possible to have Unity ignore this file but I didn’t spend much time looking into it. Instead copy the contents out of demo-files/demo.js and add them into the demo.html file. Next remove demo.js.

The changes to demo.html will look something like this

Using your icon font

Now you are ready to create some icon buttons. We will assume that you already have a button in your scene.

For the text element underneath your button, modify the font to be icomoon. Then copy the unicode character (the empty box shape, it should select when you click it) into the the Text value.

That’s it. From here you can modify the color and size of your icon as if it were regular text.

If you need to modify the icon of a button in code, you’ll need to use the hexadecimal value for the unicode character. In this example the play icon has a hexadecimal value of ea1c (find this value in demo.html). This means that the code to set the text to the play icon will be

iconButtonText.text = "\uea1c";

If you need to modify your icon font you can import the selection.json file from the extracted zip back into the icomoon app. The Read Me.txt file included in the zip also speaks to this.

Some thoughts

Having to paste invisible characters into the unity inspector is kind of a pain, but no more painful than some of the other annoyances I have in Unity.
If I was using this heavily in code, I’d probably abstract out the unicode hexidecimal values into some string constants. This is much easier to understand.

iconButtonText.text = Icons.PlayButton;

Otherwise I have no issues with this approach. Long term we may create our own nicer looking icons and at that point I assume they’d probably get switched to images.

Goodbye Awful UI

One of the most obvious things that has changed in the last couple weeks is that I did away with the awful UI. It served a purpose, but it was time to go.

Here is the new improved placeholder UI.

The icon set right now is not final. These are all taken from the Icomoon icon font. The harvesting icon (spoon & fork) was the only icon that kind of sort of might be mistaken for an icon that could possibly indicate harvesting.

The action menu’s are set up so they can be dynamic and support child panels. Making these menu’s support a large number of items should be as easy as allowing them to scroll when they get too large.

Here is the new action menu (the red structure indicates you aren’t allowed to build it there. The visuals for placing structures need a little love)

Along with the UI changes I did a lot of work around placing structures. Previously you were able to place structures on top of each other, resources weren’t harvested before building a structure in a location, and the indicator for where a building was going to be placed looked horrible. These things are all taken care of now. There is proper collision detection to make sure you don’t overlap structures. When you place a structure you get a decent looking indicator for where it is going, and any items in the way of your structure will be flagged for harvesting and removal. Items that are going to be harvesting or removed also now get a visual indicator.

Next up is terraforming and ensuring you can only build on level terrain! And at some point I should probably make sure the generated resources don’t overlap the starting structures….

For those of you that are curious (and so I can be reminded later of how bad it was), here is the old UI.

Now in 3D

For anyone that saw the initial screenshot of the game, it was a little….. boring. To keep things simple the terrain in the game was just a simple plane. This allowed me to focus on other systems in the game. Finally a couple weeks ago I started down the path of switching the terrain over to be 3d, and man I wish I would have done this sooner.

Here is what the game looks like now.

And zooming out as far as the game currently lets you.

And the entire map at a size of 300×300. This is our current target for the largest map size.

This is all procedurally generated, and getting here took some work.
I started by going through this youtube tutorial series. I recommend it for anyone getting started on procedurally generating terrain. It gave me a very solid foundation to build on.
One important thing I took away from the videos is that I needed a way to test out the terrain generation without having to recompile and play the game. Modifying fields in the inspector and seeing the terrain update immediately will save you a ton of time. I generated almost all of the screenshots for this post without having to stop the game and change any code.

The first step was using what I learned from those videos to generate some basic terrain that I was happy with. This uses a couple octaves of perlin noise and flat shades the result.

The look we are going for is low poly, and this didn’t quite feel right. My next step was adding a way to constrain the height of each vertex. This is done with something I called HeightsPerUnit. This defines the number of steps allowed between each full height unit. With a value of 10 for HeightsPerUnit the height of a vertex can be 3.0, 2.1, 5.2…. with a value of 4, the height of the vertex could be 4.0, 1.25, 0.5…..
Generating a map with a constraint of 10 HeightsPerUnit results in this. The best way I can describe this is that it looks somewhat pixelated.

I found that the lower I set HeightsPerUnit, the less pixelated it looked. This is the result with a value of 2. It doesn’t look bad, but it isn’t quite the look we are going for.

My next idea was to vary each vertex so that it wasn’t perfectly on a grid. For each vertex, I modify both the x and y coordinates by a different random value between -VaryBy and VaryBy. Using HeightsPerUnit of 10 with a VaryBy of .25 gives the following result. This looks much better than the original HeightsPerUnit of 10.

The next step was figuring out how to ensure that the center of the generated map would include a flat area. Currently there are some buildings that spawn there and I wanted to make sure that they wouldn’t end up embedded in a hill.
The naive approach would be to set the height to 0 in a radius around the center. The problem with this approach is that you’d get a very unnatural looking center. Any hills near the center would be abruptly cut off. The solution is to use a curve to determine how much height is cut off.

This approach defines CenterRadius along with a FlattenAnimationCurve.
For a point x,y, determine the distance from the center.
If the distance <= CenterRadius then pass distance / CenterRadius through the FlattenAnimationCurve to determine how much height to chop off at this point.
Don’t allow the height to be set to less than zero.

The closer to the center, the more height is chopped off. As the distance approaches the value of CenterRadius less height will be chopped off. The curve helps ensure that the result looks more natural. The perfectly flat area in the exact center looks unnatural, but the transition away from the center looks good. Down the road this method will probably change to just make sure the center is “mostly flat”.

The animation curve

The resulting map with CenterRadius of 30

Seeing as the name of the game is currently FromTheFord, we definitely need to include a river and a ford in the map. For now the river is a straight line cut down the map a little off center. The result of this highlights the issue I mentioned above. This looks very unnatural.

Using the same approach I used for the center of the map, I defined a RiverFlattenDistance along with a RiverFlattenAnimationCurve and flattened out the terrain around the river. This has the side effect of making the river not be a uniform straight line. Currently any terrain below a specific height will be considered water.

The next step is getting some different terrain types into the map. The approach I used seeds the map with different terrain types at random locations. Then the map is iterated over, spreading the terrain one tile at a time to any neighboring unassigned tiles. This repeats until all tiles have a terrain type assigned. The result of this leaves a little to be desired. Most terrain areas intersect in clean lines and the result doesn’t look natural. To help things look a little more natural I modified the terrain spreading so I could assign a random chance to it.

The result without the random chance to spread.

And with only a 5% chance to spread

Next up I needed to fill the world with stuff. Without rocks, trees and bushes it looks very bare. The approach I’m using involves generating fractal noise and then determining the points where the noise is greater than nearby values. For placing trees in a forest tile, the radius used is very small. For placing trees in clay the radius will be much larger. The approach came from here. I’m not completely happy with this, but it works for now.

This is the world populated with trees

Along with all this work on generating the terrain I also implemented Unity’s NavMesh for path finding. This required constructing each terrain type’s mesh separately so that I could define the movement cost for each terrain type. Walking across the ford in the river should take more time than walking across a grass field. The map was already split into 9 regions, and now each region has a separate mesh for a terrain type that exists in it.

Here’s an example of the grass terrain in the center region.

With the introduction of several thousands of resources that can be harvested my code needed to be optimized. The foreach loops that were iterating across all of the resources on the map killed the framerate. I implemented a quadtree to handle locating resources and the difference in performance is amazing. While I was in that area I improved how the resource selection looks.

This is the current version of it

This was a ton of work, but man does it make the game feel better. Next up I am supposed to be working on fleshing out the crafting and production systems, but it seems like implementing the ability to modify the terrain would be so much more fun. Who wouldn’t want to level off a hill to build their village on top of it?

Two Weeks In

I just finished up my second week of part-time paying job, part-time building a game and the change is amazing. Gone are the days of laying in bed Sunday mornings and stressing about work, or trying to come up with a solution to a work related problem. With only three days of the week at the paying job, the majority of my week is no longer spent at the office. My random thoughts are now shifted to FromTheFord.

At this point I’ve already settled into a new typical weekly schedule.
Saturday is my day to relax, clean, and maybe work on the game if I feel like it.
Sunday is kind of like a half day. My goal is to put at least a few hours in, but I don’t stress if I have plans for the day and don’t find any time to work on the game.
Monday and Tuesday are game work days. I treat them just like regular work days.. I wake up early, get ready for the day, and get to “work” before 9am. The only difference is I’m spending 8 hours at home working on the game instead of going into an office.
Wednesday through Friday are regular work days.
Evenings throughout the week I will work on the game if I’m motivated, but I no longer try to force myself to after a stressful day at work.

One important change that I’ve made is creating a dedicated space that functions as my work area. Previously my desk was in my bedroom. My bed was on one side of me, the door into my bathroom on the other. It was kind of dark, carpeted and I never felt very productive there.
Now I’ve rearranged my dining room and have my desk in one corner of it. The area is more open, has plenty of natural light, laminate wood flooring, and is no where near my bed or my bathroom. It feels more like a work setting and I believe that has helped me be more productive.

I’m starting to make good progress on the game, and along the way I’ve learned quite a bit. My plan is to start sharing some of my progress as well as writing up some tutorials on the things that I’m learning. My first attempt at a post about how I am implemented saving/loading of game data made me realize how much time creating a good tutorial can take. That post will have to wait for another day. For now I’m going to share some simple changes I made to the games camera system.

The camera I built for the game has a large number of settings that can be tweaked. This allows us to play around with how the camera works without having to change code and recompile the game. While switching the game over to 3d terrain I started playing around with the angle of the camera. This lead me to an issue with how the camera was programmed.

One important thing to note is that the camera is contained within another gameobject. In game when the camera is rotated or panned the camera container is updated, but the camera itself stays at the same local position. Camera rotation is handled by rotating this container around the y axis.
Originally the camera had a height above the surface, a z position, and an angle. The problem with having those three settings is that if you change the angle, you then need to find the correct z position to make sure that the center of the camera view is pointing at the place where the y axis of the camera container intersects the terrain. If the camera view was not centered on that point, then when you rotate it the view would swing in a very disconcerting manner. The world view would be rotating around a point that was not in the center of the players screen.

The solution to this was pretty obvious once I decided to spend the time to correct it. The only two settings that are required now are the distance the camera is from the center of the game screen, and the angle that it is rotated at. The blue and red lines in this image.

Using trigonometry – given an acute angle and the hypotenuse of a right angle, you can find the opposite and adjacent lengths of the triangle.
In this case, the camera distance is the hypotenuse. This means we can calculate the camera height (opposite side) using Sin.
Then the depth (z position) can be calculated using the Pythagorean theorem. It could have also been calculated using Cos.

    var height = Mathf.Sin(Mathf.Deg2Rad * this.Angle) * this.Distance;
    var depth = Mathf.Sqrt((this.Distance * this.Distance) - (height * height));

    this.cameraGameObject.transform.localPosition = new Vector3(0, height, -depth);
    this.cameraGameObject.transform.localRotation = Quaternion.Euler(this.Angle, 0, 0);

With this change it is now simple to adjust the camera angle. No more messing around with multiple settings trying to get the camera to rotate properly.

The Next Step

About a year and a half ago, after being pestered on a regular basis by my brother to “code this game for me”, I cracked open Unity and started playing around. Since then we’ve spent some of our spare time designing and coding a game currently code named From the Ford. It’s gone on long enough that it’s time to take the next step. As of May 1st I’ll be dropping to part time at work and dedicating at least two full eight hour days every week to the game.

The game looks a little rough right now, but it feels like a decent foundation to build on. With all of our grand ideas we might actually make something that ends up kind of cool. The plan is for it to be a mix of village building, strategy and survival in a fantasy setting. But who knows how it will end up.

As it stands the game has

  • Villager AI
    • Eating
    • Drinking
    • Sleeping
    • Harvesting
    • Construction
    • Crafting
  • Iguana AI (hurray free 3d models!)
    • Wandering
    • Eating
  • A sun that rotates the earth
  • Saving/Loading (why didn’t I build this earlier?)
  • Game time with pause/speed up/slow down
  • Villager & building Inventory
  • Buildings & Resources are built in a moddable way (simple enough that Arthur can add new resource types)

 

In a couple years I hope to come back and think “man, look how crappy the game looked back then!”