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.
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!)
If you compare it to the first screenshot, it actually did not drop the framerate much at all. This is at 3840×2160 downscaled to 1920×1080, running on a GTX 750Ti. But it becomes more GPU bound when I started rendering a lot more chunks. Below it is rendering at 720p downscaled from 1440p.
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 soon 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.