Showing posts with label block. Show all posts
Showing posts with label block. Show all posts

Tuesday, September 9, 2014

Cutting Corners

Couple of things. First, I've officially started my new job! I've never had to clarify this before, but this blog is strictly for side projects and personal ramblings. I will never make posts about anything I do professionally. While I'm happy and excited to be working again, it does mean I'll have significantly less time to work on side projects. Thus, the already infrequent updates are likely to become even less frequent. I'll also be moving this week, cutting down on my free time further.

Second, I don't think I've ever put out this disclaimer: I did not make the textures currently in use. I took them from the Dokucraft texture pack for Minecraft. The skybox I found with a Google search. These are obviously not the final textures, and I fully intend to make my own some day.

Now to reveal what I was working on last week. I've modified the game to support more block shapes!

Before
After
The new scheme includes all the old shapes, plus some new ones like like half-blocks and half-slopes, as well as many more complex shapes. This change forced me to rework how textures are applied, which is why everything is dirt rather than grass. I had already planned on switching to decals for grace, but that'll require me to modify some art assets.

Tuesday, August 26, 2014

Water is Fancier Than You Think


Progress? On my project? It's more likely than you think. As you can probably see from the above picture, I've been working on water. While it may not look that impressive, this actually involved several significant changes. To get to this pretty scene, I had to do the following:
  1. Deal with having two blocks in the same spot (for water intersecting the shore).
  2. Add support for transparency.
  3. Remove internal faces from between world chunks.
  4. Add support for non-solid blocks (so that the player could walk through the water).
  5. Add support for animated textures.
Lets cover each of these in detail:

1. Deal with having two blocks in the same spot (for water intersecting the shore).

Allowing each cell to hold two different blocks would double the memory I'm using, so that wasn't a feasible solution. And if I ever needed three in the same spot, I'd be back where I started. 

The obvious answer was to use extensions (the same technique I'm using for vegetation and decals). However, I wanted the water to look like one large body, rather than a bunch of cubes. This meant eliminating internal faces. Unfortunately, extensions don't take adjacent cells into consideration during the mesh building phase.

So I introduced a new extension type for blocks. The meshing algorithm was modified to handle these the same way it handles normal blocks.

2. Add support for transparency.

For those unfamiliar with game programming, properly handling transparency is actually quite difficult. To get it looking right, you have to render the faces from back to front. Unfortunately, the most optimal way to render non-transparent things is front to back (and with blending turned off). Thus, the best solution was to create two meshes, one opaque, and one transparent. The opaque meshes are rendered first, front to back. Then blending is turned on, and the transparent faces are rendered back to front.

I also had to modify the meshing algorithm to account for the fact that transparent faces don't hide opaque ones. There are also still some problems that can arise from having multiple layers of water in the same chunk that I have yet to fix.

3. Remove internal faces from between world chunks.
Until I made this change, the meshing algorithm only took into account blocks in the same chunk. Unfortunately, this lead to underwater walls being generated between chunks. I had to modify the algorithm to take neighboring chunks into account. This also meant waiting until all those neighbors were loaded before running the meshing algorithm in the first place.

4. Add support for non-solid blocks (so that the player could walk through the water).

This was relatively easy. I simply added a flag to each material indicating whether it was solid or not (likewise with transparency). This flag could then simply be checked in physics, and non-solid blocks could be ignored.

5. Add support for animated textures.

I spent a long time thinking about ways to accomplish this. The solution I settled on ended up being stupidly simple. I simply built a table of animation info. that corresponded to each texture. This info is passed to the shader, which does some simple math to figure out which texture to draw each frame.

This did force me to start using array textures, but that also got rid of some aliasing, so it was a good move all around.



I also did a few other miscellaneous things, including some minor optimizations and bug fixes. All in all, it was a very productive week!


Tuesday, April 1, 2014

Reaching Hidden Depths

Still feeling kinda stuck. I decided to play around with normal and parallax mapping a bit as a change of pace. I took the lazy approach with parallax mapping so it looks pretty bad at extreme angles. I'll implement a better method if I decide to revisit these things more seriously later on.

I also started cleaning up my makefiles. Hopefully my workflow will be a little more streamlined when I'm done.

I would really like to add some actual gameplay to this project. I had a lot of plans for how I was going to use information from the large scale terrain generation to create gameplay, but putting that on the back-burner also blocked my gameplay plans. I might just have to force myself to hack in new things for now and revise things later.

Tuesday, February 25, 2014

Please Save This For Me

I'll come back for you, love, I promise to.

This week I've been working on saving and loading the world as you move through it. Until now, the world has been procedurally generated as needed. You could make changes to the world, but if you left and came back, the terrain would be re-generated.

A simplest way to handle saving and loading is to divide the world into parts and save/load each part to a file. However, this can incur a lot of hidden overhead. File reads/writes are very expensive. They're pretty much the most expensive thing a computer program can do short of accessing the internet.

So I decided to (once again) take a lesson from Minecraft. I originally implemented a format that was more or less identical to the Region file format used by Minecraft. After doing all that work, I suddenly realized that the Region format wouldn't work for me, and there's one important difference between my project and Minecraft that makes this a problem: Minecraft has a fixed height limit.

My project, on the other hand, does not. The game world extends infinitely in all directions, including up and down. The reason this is a problem is because the Region file format stores world chunks in vertical columns. This is fine in Minecraft since moving up or down can never trigger loading/saving. This is not the case in my project. If I used the Region format, I would have to store twice as much data when the player is straddling a vertical boundary.

So I decided to modify the format to suite my needs. Instead of working with columns of the world, I'm working with large cubes. I chose a size that was large enough to take advantage of compression (using run length encoding), but small enough not to incur a huge memory overhead. I ended up settling on 64 x 64 x 64 block areas.

Unfortunately, this change created a problem. In the Region format you're unlikely to get an entire column compressed down to significantly less than 4096 bytes. This number is significant because most modern computers read from hard drives 4096 bytes at a time (it's more efficient to have a few large reads than a lot of small ones). Region stores its data in a way that minimizes the number of reads/writes.

When you store the world as large cubes, you end up having cubes of solid air or rock. After compression, these only take up a few bytes. Basically, this would mean using 4096 bytes for something that requires less than 10. This wouldn't be so bad if these sort of regions were few and far between, but they actually make up the majority of the game world. My solution to this problem was to store multiple small chunks in a single 4096 byte area. Large chunks are still stored the original way. The end result isn't quite as elegant as the Region format, but it did, inadvertently, result is a larger maximum chunk size (255 MiB vs Minecraft's 1).

I finished all the code for this, but I still have to fix a few bugs before I can say it's done.

Tuesday, February 18, 2014

Vegetation


Another short post this week. I added some vegetation! Importantly, I can use the same code to create other objects. Although, for the time being, I have to hand write object meshes, so I probably won't add many more until I have a way to import them. I added a minimap. This is just for testing purposes and will eventually be taken out. I also did some more optimization that allowed me to increase the render distance quite a bit.

Tuesday, February 11, 2014

Snow Stickers


Gonna be a short update today. You can now create and destroy blocks (look, I made a castle!). Additionally, I added decals. This lets me slap additional textures on blocks. I could even layer several on a single block. In the above screenshot you can see me experimenting with snow decals. This will cut down on a lot of work that I would otherwise have to do by hand, and opens up a lot of possibilities. I was pleasantly surprised to find that the decals didn't impact performance, even without any optimizations. There's also some water visible, but this is purely for looks.

Tuesday, January 21, 2014

Perlin Hills

This week has been unusually productive. I've been working on terrain generation. Already the results are much better than previous attempts of mine. Thanks to researching the topic, I've finally come to decently understand Perlin noise. For generating and storing pieces of a massive world, I plan to adopt some of the methods used by Minecraft. Specifically, I'll be using a file format similar to the Anvil file format, which Minecraft currently uses.

I've spent some time reconsidering the previous block shape scheme I planned on implementing. For the time being, I've largely given up on finding the 'perfect scheme'. Every system I've considered has drawbacks of some kind, and all would have been a huge headache to implement. So, for now, I'm using a simplified scheme. The shape of a block is simply defined by which of the eight corners are present (256 total block shapes). In the future, I will likely consider more complex schemes, but until I find a better one, I'm just going to move forward with what I have now.

As an optimization, no hidden faces are included when the meshes are generated. This is done simply by checking if two adjacent blocks have matching corners on the touching sides.

Here are the next few things I'm going to be working on:
  • Adding textures to give the world some color.
  • Saving and loading sections of the world dynamically so you can move around.
  • Some simple physics so that you can walk around.



Tuesday, November 26, 2013

Playing with Blocks

To be honest, I mostly just played Skyrim this week. And I regret nothing!

How do I say this? Basically, I wanted to make Minecraft before Minecraft was a thing. Or, more accurately, I wanted to make a game like Dwarf Fortress that was played from a first-person perspective. It annoys me now that making such a game would immediately be taken as a Minecraft knock off, when it'd really be a Dwarf Fort knock off. Truthfully, the Terraforming game is actually this same idea, but with a different theme.

I started on such a project during my senior year of college. This is as far as I got before schoolwork and prepping for graduation started monopolizing my time.


What I learned from the experience is that Minecraft is much more technologically impressive than one might think. My project ran at about 15-30 frames per second, where a comparable Minecraft world easily did 60 on the same computer.

Recently I've been thinking of starting up the project again and working on it. For now, I want to stick with a fantasy theme, rather than working on the Terraforming game. The reason for this is that I have a much clearer idea of how I'd want to carry out the design in a fantasy setting. Fortunately, most of the work should carry over to a game set on Mars.

Before I left the project, I had only accounted for square blocks. In an effort to make things look a little less blocky than Minecraft, I'm going to include other block types. These are the three basic shapes. Each of these can be rotated and scaled to produce many different shape types. Additionally, the shapes can be inverted (replacing empty space with filled space, and filled space with empty space) to produce more even more shapes.
Hopefully, by next week, I'll have something more to show. However, given that both Thanksgiving and my Anniversary are coming up, I'm not anticipating getting a lot done.