Jump to content

  • Log In with Google      Sign In   
  • Create Account

Electronic Meteor

Back to Project SeedWorld

Posted by , 13 April 2015 - - - - - - · 1,227 views

My hobby programming plate was kind of full at one moment. In addition to the game idea I have for Project SeedWorld, I have started working on a Pong-based game for Mini LD 58, and I also have my open-source Bummerman game. Though not a serious project, I plan to hold on to it to learn multiplayer networking code. Mini LD is already over, so I can go back to work "full-time" on the voxel game. I already have it working in a MonoGame project now.

Posted Image

Putting all the Code Together
Between this and other small games I have worked on in the past I have seen a familiar codebase develop over time and started to see what others mean about deferring your plans on building a game engine. Most recently with the voxel game, and even before then, making pet projects I haven't shown in public.

Over time, I have developed a "Screen Element" system which works like Game State management, but there is no manager class, and I prefer to call them Game Screens or Screen Elements. With Bummerman, I also have a custom ECS framework that works for this particular game but I have copied the code over to start making the platformer.

So I have two sets of code that I notice I can copy to other projects, in two separate folders. One is for the ECS and the other for Screen Elements. I can then start with a Game class that loads the first Screen Element for the game and in the main gameplay logic use ECS.

Porting SeedWorld to MonoGame

Today I have started work on taking the important voxel engine code and updating it to run with a game using the ECS and MonoGame. It's a success so far! Project SeedWorld can now go multi-platform.

I am not using procedural noise functions this time around. This game will be made using custom tiles, which are represented as 16x16x16 chunks. Right now I am still using voxel streaming to load and unload chunks, but that may change soon as it's not completely necessary now. As before, it loops through all the possible chunk areas to see if any need updating.

Tile information will be handled in the ECS framework. First, a Level object will read tile data, which is just a series of number IDs that point to voxel object files. A Tile component will store the tile position, tile ID and rotation. It will also be accompanied with a Collision component. I may not want voxel-perfect precision but instead have hit areas represented with simpler shapes.


By the way, MonoGame has one big annoyance: It has no built in SMAA support! You'll have fix it the hard way by adding this feature to the source, get around it with a post-process shader, or be more gutsy like I was and use a super-sampled render target at 2x the native resolution (in other words, 4k resolution!)

Posted Image

If you compare it to the first screenshot, it actually did not drop the framerate much at all. This is at 3840x2160 dowsampled to 1920x1080, running on a GTX 750Ti. But it becomes more GPU bound when I started rendering a lot more chunks.

Posted Image

This is because of the number of draw calls of one per chunk, just the way it was when using XNA. But I think this time I will combine several chunks into one mesh to reduce the draw calls. In the meantime, I will be working on a voxel tile loader so it can generate pre-made chunks from voxel sprites. It will basically be a tile editor but in 3D. I want to give the players the ability to customize and make their own maps with the game.

Hopefully next time I will be able to show the process of making a map with the tile editor and show some of the game features with it.

Bummerman source code released, still an ongoing project

Posted by , 20 March 2015 - - - - - - · 1,287 views

I have released my first open source game code to GitHub for my Bomberman clone, Bummerman. Here is the project link:

This game uses MonoGame 3.2 for the build, and the Lidgren network library. The solution is set up for a Windows/Windows 8 build- I'm not yet able to try to build it for Linux of Mac OS X.

What started out as a small side project seems to be turning into a full-fledged game with many details. As you may know, it began with a custom ECS framework and then adding game logic to test it out with. Then I got interested in adding networked multiplayer. So I'm making this a longer term project and as a stepping stone to build other games from.

Current features are, one power-up, support for keyboard and controller buttons/D-pad (no joystick input yet), up to 4 players, and rudimentary Game Screen states. I plan to finish this game with added polish, and more features.

There is just enough to show the gameplay interaction and flow of game states. Upon starting the game, you are greeted with a message on the screen telling you to choose between hosting a game server or connecting to one as a client. After making your choice, the game starts and you can control your character.

What's left to do

The game is very much a work in progress so there are a lot of bugs and things missing from the game currently. I'm a noob to networking code here, and this is the first time I've tried it on a game. Networking is nothing more than a check to send test messages, as they have no impact on the gameplay whatsoever. But it works at least!

There needs to be more power-ups, input controls can only handle one unique set of inputs per player, so there's still the issue of one set of inputs controlling all characters on the screen. I might need to add the ability to deep-copy components that have reference type variables. I didn't include sprite assets because I am using copyrighted sprites as placeholders currently. I will add free placeholders later.

Next Mini Ludum Dare is around the corner has just begun and I hope it is my first one to participate and try this codebase out for other things. Probably not the network code, though, since that is still very basic. The theme was just announced as "Pong" so it shouldn't be too hard to make something out of that.

Feedback and comments are welcome. I hope this code could be of use to someone wanting to see yet another approach to coding a game.

Bomberman running on the updated ECS framework

Posted by , 17 March 2015 - - - - - - · 1,318 views

I've been going back to work on my Entity-Component-System framework. Aside from being a side project, I will also plan to use it for my voxel platform game. I've already created a Minimum Viable Product using it, which is the Bomberman clone game I mentioned a few posts back. Animations are still very buggy, and there is no AI implemented, but a barebones 2-4 player version is working.

Previously I initialized all the Components, Systems, and Entity templates in the framework code. While I did this for testing out the game, it's not good for portability, so I had to remove all that initialization code out and update the framework so that it can accept new Components, Systems and templates from outside.

Finally, I isolated the code into its own assembly, so it would be possible to just link it as a DLL. This also meant I had to remove any XNA/MonoGame specific classes and all the rendering will have to do be done from outside. In short, it's really is meant for game logic only, and your game will have to handle the rendering separately.

The framework itself is lightweight (and I hope it stays that way), and only consists of 5 files/classes: Component, EntityManager, EntitySystem, EntityTemplate, and SystemManager. The SystemManager handles all the high level control and flow of the EntitySystems, which you make custom systems from. EntityTemplate is a simple class used as a blueprint to add Components that define an Entity, and is deep-cloneable. EntityManager handles the creation of Entities from these templates, and also the organization of its components. Despite its name, there is no Entity class. I think I wil rename this manager to "ComponentManager" in another revision.

The Bomberman game has the following components:
  • Bomb
  • Collision
  • InputContext
  • PlayerInfo
  • PowerUp
  • ScreenPosition
  • Spread
  • Sprite
  • TilePosition
  • TimedEffect
They are used by the following systems:
  • BombSystem
  • CollisionSystem
  • ExplosionSystem
  • InputSystem
  • MovementSystem
  • PlayerSystem
  • PowerUpSystem
  • TileSystem
Some of the systems are more generic than others. There are a couple of systems like the Bomb system or Power-up system that have very specific logic pertaining to the game, while others like the Input system are pretty abstract and can be adapted to other game types with little or no change. Some are Drawable systems so they have an extra Draw() function that is called in a separate part of the game loop.

The funny thing is that I was going to talk about using Messages in this update, but in the time between, I did away with them completely. Messages were a static list of Message objects that was in the base System class. They were mostly used for one-time player triggered events (like setting a bomb) and every system had access to them, but I decided to just pass along the InputContext component into the systems that will be dependent on player input.

Setup and Gameplay

The game is started by initializing all the components and systems and then creating the entire set of Entities using a Level class. This class has only one job- to lay out the level. Specifically, it adds the components needed to make the tiles, sprites and players. My implementation of the game pre-allocates 9 Bomb entities (the maximum a player can have) for each player.

Each player can be custom controlled but right now that's facing issues now that I moved from invoking methods to instantiate new Entities, to deep-cloning them. This works as well as long as none of the component have reference types.

The only Component that has reference types is the InputContext component as it needs to keep a Dictionary of the available control mappings. This breaks with deep-cloning and thus with multiple players, they all share the same control scheme. Other than that, it makes the component too bloated, especially with helper functions to initialize the mappings. So I am figuring out how to use value types only to represent an arbitrary group of control mappings.

The game starts immediately after setup, and every InputContext that is tied in with a PlayerInfo controls a player. Movement around the level is handled with the Movement System, while placing and remote-detonating bombs is handled with the Bomb System.

The Input System detects key and button presses from an InputContext's available control mappings, and changes two integers, "current action" and "current state", based on it. It is up to other systems to determine what it should do with these values, if needed.

The Tile System is responsible for keeping sprites aligned to a tile grid, or giving them their closest "tile coordinates" which is important in knowing where a bomb should be placed, for example.

Collision System is self-explanatory. It handles different collision types varying by enum, to differentiate solid objects, destructible objects or damaging objects, as well as the response (it pushes players off walls, for example). If a player walks into an explosion, the Collision System knows.

An Explosion System is used to propagate the explosions in pre-set directions. By default it's in all 4 cardinal directions with a bomb's Power attribute copied to a Spread component, subtracting one with each tile. It keeps creating more explosions until this attribute reaches 0 or it hits a wall.

The Powerup System handles tracking tile locations with the players' own tile locations so if two identical locations are found, we know a player is over a power-up and it can be applied.

There used to be a system for drawing sprites, but I decided to remove it and have the rendering be done outside the ECS scope. This makes the code more portable and you can use your own renderer.

Now that the game is now done (with minimal specs), I am now ready to extend its use to produce one of the games I have wanted to make for a while, a top-down arena style shooter. This game will have similarities with components and systems for player movement, tile collision, and power-ups (which will be changed simply to items). I plan to make it in 2D at first but eventually switch the renderer to 3D and also offer customizable maps.

More fun with shaders, and a new direction for SeedWorld

Posted by , 10 March 2015 - - - - - - · 1,488 views
Here's what I have been working on for the past week:

Posted Image

Just a 3D scene of space. But all programmed in HLSL! I have been inspired by Iñigo Quílez's work and also his other website, ShaderToy with the impressive technical approaches to computer art, and wanted to learn a new way to put my shader coding abilities to the test. I still don't know how to do most of the techniques for all the most popular effects, but ray marching is no longer the intimidating dark magic I once took it to be, and I think I did well for the first week. It could come in handy in games, maybe like using the shader that made this particular image as a background for a space shooter/sim.

Also, I got the program to compile successfully with MonoGame. I finally got around the problems with compiling custom shaders and corrupt MGFX files, and figured out the build configuration needed to run them with Windows 7/8 on the SharpDX API. I mean, it's about time. Vulkan was just announced in detail to the public, and up until last week I was still using Shader Model 3.0. I think I needed to step beyond the limits of older graphics APIs and try at least learning something new.

Here's the project configuration I used for MonoGame on Win7, in case someone else is trying to figure it out:

Posted Image

This compiles the entire project perfectly and you don't need to use any external tools to build the shader content.

Going in a New Direction

And now back to Project SeedWorld.

This project, which I also talk about exclusively on my own blog, has been put on the side for a couple of weeks. What really happened is that I needed to reconsider the scope of my project. I felt out of my depth. See, what I really wanted to make all along is something like Cube World but with a different set of game features and more focused questing, and the added perk of being regularly updated by yours truly. But that didn't end up going the smooth trail I wanted it to be.

For most of the project I was working on getting the voxel generation and rendering engine to work well and mostly bug-free. It can now render large procedural landscapes. Physics is all custom made and I can make a player avatar walk and jump around in the world. I finished fixing the last major graphical bug that it had and then- well I have a large world. That I can run and jump in. Suddenly I felt overwhelmed with how much more I still had to do.

I started adding some GUI code to test rendering and controls, but I needed to add something that resembles gameplay, even if it were the most vague. I could throw in a bunch of objects into the world, what they are isn't important, but just to make the player pick them up. But I needed to add an inventory menu to track those objects. I felt that it wasn't interesting enough.

A Change of Genre

I have also been taking a look at other games (completed and in-progress) to inspire me, and in particular voxel games such as Staxel and The Deer God has been so influential for making the decision to scale down my game. So as of now Project SeedWorld will be a platform game in the vein of the 2D Super Mario games. It might still have item management and RPG-like progress elements, but most of the focus will be on run-and-jump platforming action. I think I would have more fun making a game of this genre, and also stand a greater chance of making the game fun.

But the voxels will stay. I am gonna keep most of my voxel engine as it is, just with changes necessary to fulfill the needs of making a platform game. Voxels will be reduced in size, so it will be like Staxel. I will probably restrict the movement to mostly 2D, but graphics will still be full 3D. Just now with the added benefit of being portable with MonoGame (possibly the next big challenge).

Will the worlds/levels be procedurally made? That depends on how easy it is to making procedural levels. I've researched a bit and read an article or two, and it's not like throwing a bunch of noise functions and tweak their parameters till you get something that looks nice. The world generation will depend greatly on the actions of the player and this could mean many, MANY hours of play testing.

So there you have it, and now begins my work with a new type of game. Guess I just needed a break again from the project to think more clearly on what I should do. Also, because I already have most of the voxel engine already made, hopefully the start will be a lot easier.

Generic Planning Post #1

Posted by , 02 March 2015 - - - - - - · 1,077 views

This post is just to spill my general thoughts out there on what I am doing in the gamedev world, since now I have several things that I'd like to do.

Project SeedWorld is still ongoing as a voxel engine but I am not yet sure on what direction the game should be heading. It is meant to be an RPG, but some similar games such as Forge Quest look a lot like my goal and are leaps and bounds ahead of mine in development. I could possibly just keep the voxel engine and use it to make another type of game.

My Twitter account has been booming in activity ever since I started posting gamedev stuff. This has been my most successful attempt at using social media to promote my own projects. Not to mention I have traded comments and follows with other programmers doing similar things. It's very motivating to say the least.

Let's not also forget my older dev blog, which is also the basis for this journal. Over a year ago this blog was mainly about the development of my own graphics engine. A couple of people have wanted to use it, and although its source is available on CodePlex, there are no samples or documentation. I am planning to distribute it on GitHub and touch up the code a bit to get more support.

Finally, my Bomberman game on the custom ECS framework is approaching playable status. I've stomped a couple of bugs related to power-ups and resetting of entities. Next features to add are supporting multiple players with different controls, settings menu, and AI players, in that order. I have been at a standstill lately just for trying to come up with some nice visual assets. I'm not a great 2D artist and am not really feeling a lot of the free sprites I've ran across. Maybe I should just wing it and use the original Bomberman sprites as placeholders and then worry about what the game should look like.

If that wasn't enough stuff to keep me busy, Unreal Engine 4 just became completely free and I am now wanting to give it a try. My last experience with Unreal Engine has been UE2 making some practice maps with UT2004. But I don't expect to make anything significant with it soon.

(Edit) This editor also randomly eats up carriage returns.

ECS is officially the bomb!

Posted by , 24 February 2015 - - - - - - · 1,751 views
ECS, Entity Framework
Over the last week and a half, I have been working on my own ECS framework. This is a side project away from my main voxel game, but it is something I wanted to do in order to be able to improve my productivity with making games more quickly. Inspired by Phil's Bomberman tutorial, I have implemented my own Bomberman clone with my own made-from-scratch ECS framework (though some conventions and names were adapted).

Posted Image

Bomberman-like (brand new genre) game in progress. Using open source sprites but will change eventually.

My own framework has less code than Phil's but as long as the whole game still works on top of it, I would prefer that. Because right now, I don't need two Entities to check if they are exactly the same, or don't need to serialize them for other purposes. And I certainly don't need scripts at the moment.This framework has gone through two main iterations. They differed mostly in how Components are stored in the game.

As you may know in an Entity-Component-System framework Components are just simple data containers, which don't have any game logic, but are mutable by the game logic code, which resides in the Systems. Entities in my framework do not exist at all as classes, but are rather just numbers implied in Components as you'll soon see.

Framework Structure

The ECS framework in its current state consists of your typical Component and System base classes, which you can build specific Systems and Components from. Here are the important data structures:
  • A Dictionary of Component arrays indexed by enum. Usually a small amount of different types.
  • Component arrays which are accessed by index, so constant time here.
  • Systems take references of important Component arrays. Iterating them takes linear time.
  • List of Systems which are always executed in the order that they were added.
  • Static array of Messages in Systems. For now, they are just being created by the Input System. Could possibly be made non-static.
The main point of setup and entity processing comes from the SystemManager class, which stores a list of all the different Systems, and calls their Draw and Process function in the game loop.

This class also has an instance of an EntityManager class, which is passed to the System constructors. The EntityManager class is where all the Component arrays are stored (as the base Component class), and where the Systems get all the Components they need. Components are pooled at startup, setting each array to a fixed sized X for max number of entities (though in C# it's straightforward to resize an array if needed).

The arrays themselves are in a Dictionary, using a Enum for Component type as key. They are arrays of base classes, but they added in as derived classes.
public Dictionary<ComponentType, Component[]> components { get; private set; }

// Add Tile Position components
components.Add(ComponentType.TilePosition, new Components.TilePosition[maxEntities]);
This makes it possible to re-cast them back into their derived classes, but fortunately we would only have to do this on startup. Systems get the arrays of Components they need upon initialization, cast to the the proper type.
// Inside a System that uses Collision and TilePosition components

Components.Collision[] collision;
Components.TilePosition[] tilePosition;

public CollisionSystem(EntityManager entityManager)
    : base(entityManager) 
    // Load important components
    collision = components[ComponentType.Collision] as Components.Collision[];     
    tilePosition = components[ComponentType.TilePosition] as Components.TilePosition[];       
No further casting is needed for entire arrays after this point. The only casting that is done while the game is running is for getting certain Components at a given index.

When an ECS is more like a CS

Not dealing with Computer Science, but dealing with Components and Systems only. There are no entities in the framework, or at least not as objects. There is no Entity class, but instead entity IDs are stored in the components themselves and also referred to indirectly by the array indexes. The Components are access sequentially by the Systems and you can be sure that any Components in the same location of their respective array together make up an entity.

The EntityManager also has as an integer variable, TotalEntities, for the total amount of entities active in the game. It tells each System how far into the Component arrays it should iterate. An entity is "removed" by replacing the removed entity's components with the components of the last active entity in the array. TotalEntities is reduced by 1, and this is the new index marker to tell the EntityManager where it should add Components to make a new entity.

Since arrays are fixed size, the amount of entities should not exceed the size provided in the pool. You can usually easily test and find out what a suitable size is for simpler games. I want improve this in the future by making the EntityManager resize the arrays to a much larger size if it should reach the limit (which should generally be avoided anyways to maintain good performance).

Component Organization

In the first iteration, the framework had arrays of each Component type, as concrete classes. Each derives from a base Component class, but the arrays are set up as the derived Component classes. So you had arrays of different classes named spriteComponents, screenPositionComponents, etc. This was inflexible for two reasons. First, adding a new component type meant also adding code for it to do a type check in the function to "Add" an entity.
// Get proper EntityPrefab method
Type prefabsType = typeof(EntityPrefabs);
MethodInfo theMethod = prefabsType.GetMethod("Create" + templateName);

// Call method to create new template
newTemplate = (EntityTemplate)theMethod.Invoke(null, new object[] { nextEntity });

// Check every array for proper insertion 
foreach (Component component in newTemplate.componentList) 
    if (component is Components.Sprite) 
        components.components[ComponentType.Sprite][nextEntity] = (component as Components.Sprite); 
    if (component is Components.Bomb) 
        components.bomb[nextEntity] = (component as Components.Bomb); 
    if (component is Components.Collision) 
        components.collision[nextEntity] = (component as Components.Collision);

// Etc...
This has been improved since, and now adding Components to an array doesn't require manually going through every possible Component type.
// Check every array for insertion
foreach (Component component in newTemplate.componentList)
    components[component.type][nextEntity] = component;
Enity Prefabs

Every game using ECS benefits from having pre-assembled entities to use right off the bat. It's a logical way to plan the rules of your game and what kind of game objects it will have. I use a small class called EntityTemplate which stores a list of Components. A class called EntityPrefab contains different methods (CreatePlayer, CreateSolidBlock, etc.) to return a new copy of a template, and its Components are added to the pool.

You still have to invoke EntityPrefab methods since the methods are dynamically chosen with the "templateName" String parameter. I would like to replace it with just adding prefabs to a List of EntityTemplates, so you just select them from a list. In hindsight this should have been the more obvious approach but I was taking from Phil_T's approach to making entity prefabs.

Getting into the Game

I will talk about this in the next post, since I've probably gone long enough already! Then I'll be able to go into more detail on how the game uses the framework. But since the first draft of this post and now, I have also made some more improvements on the ECS code and ironed out some game bugs too. The game is getting closer to being playable!

Testing UI

Posted by , 20 February 2015 - - - - - - · 1,393 views

First, a late thanks to the staff at GDnet for featuring one of my entries. It was certainly not expected and I'm glad it was very insightful to a lot of people. Back to business on my game work, I am moving away from working on the voxel terrain engine so I can start adding relevant gameplay features. I needed a GUI to make certain things easier to test, especially user configuration for controls, voxel rendering and also debugging things that just make more sense to do in runtime than recompile the code many times.

With that said, I was browsing different open-source UI libraries that are made to work with XNA. Ones I have tried before or investigated are NeoForce, Squid, NuclearWinter and Ruminate. The NeoForce library looks too big for my needs and too dependent on external XML files. Squid looks nice and has enough documentation to get you started. Nuclear Winter has less documentation but the sample code makes a lot of sense to me, plus it has a nice default skin. Ruminate is actually made for MonoGame so a couple of extra dependencies are needed, and it doesn't support lists or tables. Out of these four, I chose NuclearWInter's UI.

While it lacks a lot of documentation, the samples are straightforward to see how they are put together. More significantly, it has been used by the same developers in an ambitious project of their own, CraftStudio, which is a GUI program that lets anyone build games without needing programming experience. I imagine that if it can be used for that it should certainly be robust and work well enough for my game. Within two days of downloading it, I managed to get a custom settings menu in my game, which is launched in a separate game screen.

Posted Image

The controls don't do anything yet, except for "Test" which closes the UI and returns control of the character. Also, since NuclearWinter is actually a collection of different libraries to handle other things like sound, game states and animation, I had to include all the code, for now at least. These systems compile into a single DLL. But my only interest is in the UI and the input library that it relies on.

Since I use my own Game Screen system, I modified the code to not create a Game State Manager class that was specific to that library, and not update it. It's not required for creating the screen area necessary for putting the UI into. The Audio code was easy to remove, as it relies on a separate DLL. I was also able to remove the custom Collections that it used. There's also a bunch of code files on the root that I haven't gotten around to checking yet.

When all modifications are done, I should just have the UI and Input code compiled into the library. Even then the input code is too Windows centric and I don't know how much work it will be making it platform independent. Maybe I should have forked this project and work on the changes from there. It would be easier to document the changes, plus I can provide people with the UI library as a standalone.

Voxel lighting problem solved

Posted by , 15 February 2015 - - - - - - · 1,341 views
voxels, graphics

I have fixed a problem that has bugged me for quite some time. For most of the development of SeedWorld, up until last week, every chunk was not able to access voxels from immediate neighbors. This shortcoming was avoided with the code for voxel collisions, which worked by finding the right

chunk from the group of chunks to test whether a block is solid or empty, given world coordinates as input. But sometimes you needed to find out based on local coordinates, relative to a chunk's location. This was evident in the mesh building process, as it did ray casting from each visible voxel to determine if a voxel needs to be shaded darker, and by how much.

The edge voxels were a problem for raycasting since it could not raycast further out from the edges of the chunk. Any rays that reached the edge were considered "not blocked" and the voxel received full light. This created a seam of lighter colored voxels around the edges.

Posted Image

Now since each chunk now has access to its eight neighbors surrounding the sides, you can simply make the ray "step into" these chunks and continue traveling the distance it's supposed to instead of ending prematurely. My first attempt to fix this didn't go well. I was modifying the starting coordinates of each ray and using that to find the neighbor chunk. It ended up looking worse:

Posted Image

These seams appeared because the ray was checking against the solid voxel it started from. So it always subtracted contribution from the light, making the edges dark. This was fixed by updating the ray coordinates after each step, seeing if they go out of bounds (from 0 to 32) and then picking the correct neighbor chunk to continue and reset the local coordinates. Now the seams are gone and the shading is correct.

Posted Image

Now the chunks don't look as obvious. This was pretty satisfying to fix, and probably so much that I will move on to work on other parts of the game. There are still visible seams at height intervals (because rays don't have neighbors to check on the Y axis) but this is still a lot better than seeing an entire grid of lines going across the landscape. So it's not something I am focused on improving at the moment.

As for what I will be working on next, I have been looking at some UI libraries to see which I will add into the game. I've already picked one to try for the moment, and if it is easy enough to use without having to break or re-code a large part of my game, I'll stick with it and start adding some game features.

Chunks are proper cubes now. Also, shooter game returns

Posted by , 04 February 2015 - - - - - - · 1,094 views
voxels, procedural generation
Another quick no-pic update. I've spent a lot of time in the voxel chunk rendering code, perhaps too much time, but part of it has to do with converting chunks to 32x32x32 size.

Previously every chunk was 32x256x32 in size (256 being the height). That seemed like a good idea at the time, so I could query only X and Z in world coordinates and not worry about height when it comes to lighting or neighbors. But it took too long to generate one chunk in my old laptop, which I want to use as a baseline spec for running games on older hardware. So I redid everything in the chunk management code.
It took a while but it was worth the trouble. Chunks are now cubic, and still queried individually for collision detection and rendering, but with more granularity in loading times. Making voxels from 3D noise is no longer prohibitively expensive which was also a very nice thing to discover.

Chunks with the same X and Z coordinates are grouped in a class called ChunkStack. For 256 units in height each ChunkStack contains 8 chunks. This class makes it easier to organize chunks by distance so I have 8 times less things to order, and also have it share the same 2-dimensional data for generating the chunk in each stack (so I don't have to redraw the same portion of a height map or a biome map 8 times, for the 8 chunks). With the height data, an average height can be computed in order to find a good max and minimum height for each ChunkStack. In theory this would permit for worlds with heights that can span thousands of units, despite the stacks themselves being limited in height.

Finally, I added the ability for a chunk to connect to its up to 26 neighbors (top and bottom chunks have less) and this is where loading and rendering meshes can get very flexible.

Continuing on an Old Game

In non-voxel related news, I'm thinking of going back to finish the top-down shooter game which I barely started, but talked about already. It was supposed to be simple and a way to get back into XNA, but ECS coding bogged me down so I'm gonna do away with it completely for this game. The most I have managed to do with it is move a 3D model around an empty room. But this game should be something I should be able to finish in a short time, so this will not be a big sidetrack from my voxel game. Just something I want to do quick and dirty, and still be enjoyable.

3D will not be requirement this time, but just a potential upgrade after finishing the game in 2D. The game will be, as originally planned, a twitch combat style shooter with multiplayer support. Graphics will be more pixelated/retro in style with grayscale colors.

Loading voxel models into the game

Posted by , 30 January 2015 - - - - - - · 1,975 views
voxels, 3d modeling
I didn't get as much time as I wanted to work on my game this week. Spent too much time with Skyrim (coming very late to the game, but nonetheless). Still there are some new updates to show. First I have re-opened my Twitter account for game dev related stuff, so follow me there. Also, I am now able to load models created with the MagicaVoxel editor, which will likely take a big part of my game development time in the future.

I discovered MagicaVoxel from Giawa's dev blog, and he already made some code models into his program, which is already available for use. After modifying the code a bit, I was able to get a model loading correctly into my game. I had to flip some coordinate values around, because Magica treats Z axis as vertical, while I use the Y axis for that. Also, I had trouble expanding the 16-bit color values back into a 32-bit integer. The colors were approximate but still looked off, especially with skin tones and lighter colors. So my importer code stores voxels with 24-bit color values. Here is a comparison with the model in Magica and in the game with my importer:

Posted Image

Models made with Magica use a palette of 256 colors which can be user-defined. My model format in the game uses the first 768 bytes to store the RGB values for the palette (alpha not supported yet), and the rest of the bytes are X, Y, Z and color index for each solid voxel. At the end I store two more X, Y, Z locations to get the bounding box of the model. This helps me center and position it for player movement.

The code for converting the voxels to meshes is a lot like the code for the chunk meshes. The process is split up into three steps - copy all voxels to a 3D array, cull visible voxels, and finally check neighbors to make the voxel cubes with the right combination of sides.

As with the chunks, each step is also thread-able to speed up loading of models. It now seems possible to condense a lot of this code into one generic class or set of functions that can work with any kind of voxel object. But the code still needs more cleaning up in order to make this happen.
One trick I use to make this code more readable is to pad the voxel array with a 1 unit "wall" of empty voxels on each side. For example, if I want to import a model 32x32x128 in size, I load it into a 34x34x130 array. Then instead of looping from 0 to 31 or 0 to 127, I loop from 1 to 32, 1 to 128, etc. This way I can guarantee that each voxel in the model doesn't have any neighbors that fall out of bounds in the array.

Posted Image

Now it's time for me to get a bit creative. Time to start making my own voxel models for the landscape, as I will be adding grass, bushes, etc. and coming up with items that can be picked up.

January 2017 »

1516 17 18192021