Showing posts with label game. Show all posts
Showing posts with label game. 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, February 4, 2014

Grounded

I've been making progress on my project! I finally got some basic physics implemented (after three days of debugging), so you can walk around the world now. I also did some optimization; things are running a lot faster now. Sections of the world are now generated on demand, so you can walk around indefinitely. I'm not saving or loading sections yet though. I also added in some variation in the terrain, so now there are patches of snow and snow capped mountain peaks.


This week I'm going to talk about how I'm generating the world.

Tuesday, January 28, 2014

All Aboard the Tangent Express

So, when I began working on adding 'simple physics' to last week's project, it got me thinking about rigid body dynamics (a.k.a. game physics) and how to apply geometric algebra to it. Not surprisingly, I ended up on a tangent. You'd think I'd know better by now.

Tuesday, January 14, 2014

What I Want in a Survival Game

A few weeks ago I found myself wishing for a first person survival game. So when I heard about Rust, I decided to give it a try. So far it's not exactly what I was hoping for, but it is definitely fun. It's also early in development, so it's likely to get better with time. In any case, playing it got me thinking about what I want in a 'survival game'. I'm using that term loosely; my ideal survival game would have a lot of elements that aren't strictly about survival. Two of my favorite games that I would group into this category are Minecraft and Dwarf Fortress (again, using the term loosely). Throughout this post I'm going to compare and contrast what I like and dislike from Rust, Minecraft, and Dwarf Fortress. I might also mention few other games that I have less experience with.

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.

Tuesday, November 5, 2013

Back to Regular Expressions

So way back when I wrote this post, I mentioned I was working on a regular expression parser. I put that on the back burner for a while, but decided to revisit it this last week. I based my implementation on this article. I felt pretty pleased with myself once I got it working, though I'm still working on submatch tracking. Once that's done, I'll be able to use it to parse text based files like OBJ and PLY.

I feel like I should address why I'm not using any 3rd party engines or libraries. It's not exactly a wise choice for a game developer, especially for an indie. I don't really have a good reason beyond that I don't want to. I want to use this time as much for learning as for game development, and I enjoy tackling these sorts of problems. I like doing things my own way, and I get a certain kind of foolish pride out of knowing that all the code was written by me. Good choice or not, I'm going to stick to that.

Tuesday, October 29, 2013

Updated Concept Sketch

Well, I didn't end up spending much time sketching, but I did manage to whip up some better concept art for the basic robots. Considering all the dust on Mars, I'm pretty sure that this sort of robot would do really poorly on the planet. Fortunately, I'm much more concerned with making the robot adorable.

Considering how often I have little to nothing to write about in these posts, I've decided to try switching to weekly updates rather than daily. Hopefully this will mean longer, more interesting posts. So from now on, I'll be doing a post every Tuesday.

Thursday, October 17, 2013

The Job Process

Finished up the revisions to pathfinding. I've been thinking about how to get the robots to automatically pick up and finish jobs, and this is the process I'm going to use.

  1. Create job at location. Jobs have required resources and required labor.
  2. Find the nearest available resources and create a hauling job for each one.
  3. Find the nearest and most qualified robot to complete the job.
  4. Once all resources have been gathered, signal the robot to come complete the task. 

In general, jobs may depend on other jobs being completed. Most will require at least one hauling job to move something from one place to another. The only part of that process I'm still shaky on is finding the best robot for a given job. For example, how far away does a well qualified robot have to be before it's better to just pick a nearby under qualified robot?

Wednesday, October 16, 2013

Variation

Still refactoring code, but making good progress. For one thing, there can now be multiple terrain types. The grid is now fully 3 dimensional. Pathfinding will now consider not only the tiles the bot is moving through, but the tiles it has to move over as well. Objects and units have been consolidated into a common type, and there can now be multiple objects on a single tile. Basically, all changes under the hood. It's not much, but here's a screenshot showing off multiple terrain types.

Monday, October 14, 2013

And On the Seventh Day, He Had a Hangover

Well, it's a little late for a 'morning' post, but here it is. I had a great time at my friends party. So great in fact, that I spent all of Sunday recovering from it. I did, however, get a lot done before the party. Unfortunately, that mostly involved refactoring, so no new screenshots. Still working toward getting some AI and having a better rendering pipeline. Made some changes to the way pathfinding is set up, which I'm hoping will be more efficient and flexible. That's all for now!

Saturday, October 12, 2013

Architecting Robot Intelligences

TL;DL, it's going to take me a while to get real, interesting gameplay, so I'm putting last week's goal on hold. I'll still be working on it, but I'll focus on other things in my posts until I get a little further along.

Did some more work on fleshing out a rendering pipeline today. It's a little new for me. I'm familiar with graphics programming, but I've never had to set up a pipeline for it. The projects I've worked on either had someone else working on that or were too small to need a robust pipeline. It's an annoying problem because there is an absolute 'best' solution (fewest possible GL calls), but in practice, it's better just to settle for a 'good' solution.

As far as actual gameplay goes, I did a little work on that as well. You can use the menu to create build orders now, but I still have to write some AI to make the robots actually carry out those orders. And the more I think about it, the more I realize that that's going to take a while. Since orders can be scattered about the map arbitrarily, I need some way to determine which robot is closest and most qualified to carry out the order. In principle, there could be obstacles in the way (for example, a wall that you had built earlier), which means it's more complicated than just picking the closest robot.

I also need to somehow keep track of which robots are working on which jobs. The robot needs to know so it can work on the job, and the job has to somehow be marked as 'in progress' so that other robots don't take it. Additionally, resources are needed to complete jobs, so those have to be moved to the job site, meaning that I need to give the robots an inventory.

No post tomorrow, I'll be out with friends. And I think I'm going to start writing posts in the morning rather than before bed, so next post should be Sunday Monday morning.

Thursday, October 10, 2013

Debugging: Hours of Hard Work Just to Break Even

Today I fleshed out the GUI system and made it usable. I added in a sub-menu to test it out; it should be easy enough to fill out the items as I need them. Aside from that, I got sidetracked with a handful of annoying bugs that took a while to track down. One was in my bitmap importer. It was turning some of my textures red. There was another with a small change I made to the input system. Turns out I just wasn't calling the function. The goal for tomorrow is to be able to order robots to be built. Not sure how long it'll take me to write AI for the bots to actually carry out those orders. I've been playing a little Dwarf Fortress in my spare time hoping that I might pick up some ideas on how to implement it. Additionally, I headed into the city and had a few beers with some people I know, because it's important to leave the house occasionally.

Tuesday, October 8, 2013

Uneventful

I'm trying to put together some kind of event system for the menus. It's making me miss C#. I love C++, but its pretty much terrible when it comes to event driven systems. The whole thing's proving to be a bit more tricky than I anticipated. I've never really thought in depth about how to make a good GUI from a programming perspective. Will continue working on it and have another post tomorrow.

What's On the Menu

Today I renovated the text renderer. Once drawing text was no longer a huge hassle, I started working on the GUI and now I finally have one! The buttons don't do anything yet, but they're there and they're being drawn. Here's a break down of what each button is for:

  • Log - Opens up the mission log. This lists important events in the order they have occurred.
  • Construct - Choose robots and/or buildings that you want built.
  • Orders - Order your robots to perform certain tasks, like mining and paving roads.
  • Stockpiles - Designate where resources and other items are to be stored.
  • Mission - Checklist of mission goals.
  • Robots - A list of all your robots and what they're doing.
  • Jobs - A list of jobs in progress and which robots are working on them.
  • Priorities - Order the importance of various tasks.
  • Status - General status.
Obviously, those are all subject to change, as is the layout and sizing. Tomorrow I will work on getting the buttons to actually do things.


Saturday, October 5, 2013

Slow and Steady

Didn't get a whole lot done today. Some, but not a lot. Slowly dissecting a giant main function into proper classes. Did some thinking about how I want to do the GUI. Worked on improving text rendering a little to make working on the GUI easier. Been making slow progress these past few days, but progress nonetheless.