The last 2 weeks I worked on getting some of the core functionality of the game down. I also changed the tasks in the sprint about half way through so I’m moving a lot of those features into the next blog post because it would make this post really long.
The inventory requirements of Boppio are pretty simple so far:
- Players need to be able to store items in their inventory
- Players need to be able to move items into buildings from their inventory
- Players need to be able to take items from buildings and put them in their inventory
With this in mind its really easy to just make an Inventory script that you attach to both players and buildings. This means there is practically no functionality difference between a building holding items and a player holding items.
This UI is still extremely basic, but you can see the player’s inventory slots on the left and the “Basic Miner” inventory slot which it uses to hold the item that is being mined. When the progress bar is fully filled the building inventory slot receives an item (depending on what is being mined).
To make the UI implementation simple, I created a class called InventorySlotMapping which just takes an Inventory instance and an index into the inventory that the mapping should handle. This allows the UI elements to hold a mapping to an exact slot in an inventory, whether it be for the player’s inventory or a building’s inventory. This also makes it extremely easy to transfer items between slots because it allows you to do operations on the slots directly instead of messing with the inventory object. Here is how simple the code is for transferring items:
Instead of interfacing with the inventory as if it were a collection, here we’re just dealing with slots directly using the mapping objects. The “from” mapping maps to the inventory slot where the item is coming from and the “to” mapping maps to the inventory slot where the item is going to. The beauty of this function is that it doesn’t care if the “from” slot or the “to” slot is a player or building inventory slot. This simple abstraction will make pretty much all of the inventory operations much easier.
I implemented placing buildings on the terrain this week which was pretty simple because I had a good idea of the problems I was going to run into.
Basically buildings just have to line up with the heightmap of the unity terrain object and the heightmap needs to be a divisor of the resolution of the alphamaps. This is important because certain buildings interact with the texture map layer and I didn’t want 2 buildings to be able to sit on top of the same texture square. In my current implementation a 1×1 building will cover 4 texture squares, a 2×2 building will cover 16 texture squares, etc.
Placing buildings on the terrain is simple:
So as you can see, buildings must be snapped to the heightmap grid. I will add a visual grid when placing buildings later so that you can get an idea of how things line up and where buildings can be placed.
Originally I had a pretty complicated manager pattern that I was using where a script was in charge of spawning and managing all of the buildings on all of the chunks. This week I refactored this to make the buildings themselves in charge of spawning and updating their state which I should have done from the beginning. This makes it really easy to add new features to one type of building without affecting the others.
Terrain Generation Changes
The terrain generator got some pretty big updates this week. I abstracted the dirt generator to just be a “terrain texture generator” and instead of having hardcoded inputs like offset + scale those inputs are passed in at runtime. This allows me to reuse this generator and generate new types of terrain just by changing inputs.
Here is a comparison from 2 weeks ago to today:
I’ve also implemented some more advanced features, like when a generator runs it can see if its about to overwrite an existing value. This allows me to layer the generators on top of each other. You can see on the right that the grey-ish colored dirt looks like its behind or underneath the darker colored dirt. This is because the darker colored dirt is actually generated first and then the lighter colored dirt knows to not overlap values from the darker colored dirt. You can also see there is sand between the dirt and the grass now, this was just done by running the dirt generator, then running the “sand” generator with the same inputs except making the patch size slightly larger and enabling the “no overlap” function. At first I had sand in between the two dirt values but I decided I didn’t like that so I’m actually generating the sand last, which means the sand can see both the grey dirt and the darker dirt when it runs so it won’t generate on top of the grey or dark dirt.
(I’m using the Bolt plugin for unity to do visual scripting for the terrain generation) The updated terrain generator looks like this:
This is very similar to how it was before except the constant values have been swapped out by object values which can be passed in at runtime. This generator generates all of the textures you can see on the current terrain except for the grass, which uses a different type of generator.
The “no overlap” function is actually implemented in a post processing macro that I added, here is what that looks like:
The overall functionality of this script is basically this: if no overlap is disabled, pass through the input value, otherwise if no overlap is enabled then only allow us to output (1 – existingValue). So this doesn’t completely disable overlapping, it will cause layers to be blended. You can clearly see this behaviour with the sand generator where the sand is blended between the dirt and the grass. I think this is still a bit too complicated so what I think I will do is do post processing on all generated terrain and the order in which the generators run determines priority.
The last two week were really productive, and in fact there’s a lot of other stuff that I got done this week that I’ve pushed to the next blog post because I didn’t want this one to be too long. Also I’m think I’ll have a demo ready at the end of July for people to actually start playing and that way I can actually start building a userbase. Thanks for reading, I’ll post again in 2 weeks!