Index

Showing posts with label game. Show all posts
Showing posts with label game. Show all posts

7.05.2017

Long See no Time


It's been 5-months since my last blog post! In all actuality I simply burned out there for a while. I did manage to finally upgrade my CPU from a dual-core to a quad-core, allowing much better testing and enhancement of Bitphoria's multi-threading system. Many things have been added to Bitphoria since my last blog post.

I finally decided to add in a world-wide fluid dynamics simulation system with LOD to minimize computation. This effectively serves as a sort of 'windmap' for the world - and allows objects to either drag the 'air' around, pulling other objects, dynamic meshes, and particles around. Entities can also cause a momentary change in pressure at their location, for blast or black-hole vortex style effects that actually affect smoke and entities surrounding them. Rockets can now leave swirling trails of smoke, and cause particles to wisp around as they zoom through a cloud of them. It's pretty neato, but purely a superficial effect. It's something I've wanted to implement into Bitphoria since I first sat down and sketched out some ideas I wanted to see before I even started writing the engine.




I've also added signed distance function primitives to the procedural modeling stuff for easily constructing polygonal, wireframe, and point cloud geometries for entities - CSG style. This has made it much easier to model more interesting entity appearances, and now scripters aren't forced to plot individual vertices to create triangles.

Instead of explaining it much further I'll just show you a bunch of development screenshots from when I was working on the SDF modeling stuffs:

When things were first starting to work: plotting points for individual SDF voxels - sized according to the 'density' of the voxel they represent.

Generating a point-cloud only on the surface where the voxels are zero distance from the surface of the final distance field as produced from a cube added, a ring of spheres subtracted, and a single green sphere added to the top.

Utilizing the same voxel triangulation code to yield triangle mesh geometry from a SDF model.

In my attempt to add the ability to smooth an isomesh per the distance field, a lot of things were going wrong (these are supposed to just be smooth spheres).

A sphere that hasn't been smoothed, showing the base isomesh.

Some different tests: a smoothed cone (with crooked tip, this has since been fixed), a purple sphere with a pink capsule merged/added to it, as well as a green sphere with an orange capsule 'blended' into it (note the smooth transition between surfaces) while also being smoothed properly. You can smoothly blend/merge primitives while still producing a coarse isomesh with 45 degree angles.

A ring of spheres blend-merged and the result smoothed over.

Testing a different player appearance, using various things, while having the shield powerup - a set of overlapping point cloud spheres that all spin independently by rolling around against the surrounding world surfaces while the player moves.

A screenshot of the last of the testing/development game before I started scripting a new base game from scratch.

A bunch of other things have been added to Bitphoria as well, but I haven't touched it in at least 2 months and it's currently not something I'm particularly motivated to pursue. After making all the progress that I did on Bitphoria a few months ago I began scripting a base/default game that I would then use as a template for creating various game modes to release with the next version.

The base game is a sort of deathmatch game with simple AI drones and obstacles and hazards for players to negotiate while battling it out with one-another, which always seemed more interesting to me than just raw PvP deathmatch gameplay. Anyway, I just didn't find working on it rewarding anymore. I can come up with hundreds of little ideas and mechanics, knowing how to go about implementing them by exploiting the capabilities of Bitphoria's scripting system, but it just doesn't excite me like it did when I was younger. Back then I was working with the Quake engine. I'm sure scripting stuff in Bitphoria would be a blast for many other young spry minds out there, but I'm not of a mind to seek those kids out, even though they were what I was thinking of when I designed the whole thing.


Showing the effectiveness of Bitphoria's new FXAA post-processing shader at smoothing out super-jaggy aliasing on stair-step edge pixels. One of the many new things added to Bitphoria over the last while.

My goal has always been to make enough interesting stuff to show off Bitphoria's capabilities as a platform for creating, sharing, and playing custom games with other people - and hopefully have it be inspiring enough to motivate people to engage their own creative minds within the paradigm Bitphoria's scripting system provides. Well, as it stands, this probably won't be happening any time soon. I've had to make my peace with this fact over the last few months. I've been struggling to allow myself to work on anything else or pursue any of my other passions, not berating myself for letting Bitphoria development go idle. My resolve has been to look at this situation knowing that I owe it to myself to do what I must to take care of my own mental well-being and *let myself* pursue other projects and passions because nothing good comes about from sitting around not working on anything else purely out of guilt.

Yes, I wish that I could knock out Bitphoria in "record-manic-stay-up-all-night-not-caring-about-anything-else-in-life" time, which was naively my plan from the beginning, but it's just not in the stars. Am I lazy? Eh.. But if that were the case I don't think that I'd be feeling like there's not enough time in the day to work on what I *do* want to work on, especially after having overcome the self-inflicted shame I'd been enduring. I was tempted to release Bitphoria completely FOSS, just dump the code on the interwebs, and abandon any and all aspirations of trying to monetize it. I'd just be giving all of my work away for free. Alas, me lady talked me out of it, and explained that I should just let it sit until I was ready to come back to it. So that's what the plan is.


Bitphoria in its current form.

I've always been excellent at arcane technical pursuits and hacking away at them into the night, even now at thirty years old. But as far as actually designing a fun game or dealing with PR and promotion are concerned I am seriously lacking in drive and/or spirit. With recent developments I've become more inclined to focus on keeping my creative spirits high and working on what I love to work on: tackling difficult algorithmic problems. I've pretty much resigned to being the Wozniak to someone else's Jobs. I haven't met my 'Jobs' yet, and I hope I do someday, because I think that I have a lot to offer to and share with the world, and lack the ability to really get it out there.


The good old days.

In my relative slump I did manage to muster the gumption to start playing around on my CNC once again - the product of yet another 'abandoned' project that I had begun feeling guilty about for allowing to sit untouched and unloved for so long. It's really nice to have something to work on with my hands though :D

I've since explored a few ideas and have somehow finally convinced my wife that it's a financially worthwhile pursuit - making stuff on the CNC - which doesn't require dealing with nearly as many customers as our current crafting products do with our online business. We could be selling fewer big-ticket top-dollar high-end CNC-milled items rather than many cheaper smaller decorative items. In other words we could be making more money for less work, and deal with less customers, if we both transitioned our business toward producing large quality works as a team.

It would definitely be nice if we could spend more time together again like the old days, and I see CNC projects as being the nearest of several keys to unlocking that future for us, but it must be as a team. I don't believe she's the Jobs to my Woz, but I do believe we have the potential to achieve great things together. It has worked thus far with our online business, and I feel that she's fully capable of meeting me half-way while we engage a new medium together.

I've also been sketching out and outlining some ideas for an old project my late father had proposed and actively tried to encourage me to pursue. I'll save the details on that for a later blog post.



9.02.2016

v1.00 Public Beta Testing


The biggest Bitphoria game in history.

Looks like some people have started taking interest in Bitphoria. There are a lot of kinks to work out, some people are having issues starting a game and having their friends join. I'm looking into it. Lots of little things are being figured out: players can be hard to see, chat messages disappear too quickly, the server I'm running crashed in the middle of the night while two people were playing, AI guys are more aggressive than they need to be, etc.

The end result is inevitably a new release, v1.01, which will have a new network protocol version. The master server will only relay game servers to your version of Bitphoria that are running with the same network protocol. I will be updating my game server to v1.01 when it's released, so people who are still playing with v1.00 will not be able to see it or play on it. An auto-update feature will be implemented down the road, for now my focus is on the engine.

It was also suggested that an automated installer would make it easier for some people to start playing Bitphoria. I already have a process in place for achieving this and wasn't planning on utilizing it until Bitphoria was out of beta, but I have decided to include an automated installer with the next release.

I estimate v1.01 to be released some time next week, maybe sooner.

Thanks to everybody who downloaded the current version and has been playing with it. This has been more fun that I could have imagined :)

8.30.2016

Bitphoria v1.00 Beta Released

Pre-release early screenshot of Bitphoria.
Bitphoria has been released. It's in public beta, and this is the very first (aka 'worst') version ever. Start games (don't forget to forward your UDP port if behind a router) and play with others. Dive into the scripting system and make whatever your heart desires. Let's see what Bitphoria can do.

An engine guide is in the works now, to help users better understand the various console variables and how to make full use of them as a sort of 'power user'. I'm sure anybody with their wits about them could figure out most of them just by surfing the console typing a few characters and pressing 'tab'. The confusion, by comparison to most engines with a console, will lie in the fact that the vast majority of console commands are for scripting, and not intended to be executed while in a game, or while just idling in the main menu system.

If you're the type of person who likes to get into new things, unafraid, and share your findings with others, then by all means download Bitphoria, start screwing around, and Youtube your experiences. Share this thing with the world. If you could notify me of your intentions to release a video of your time with Bitphoria that would be great, just so I could follow along and gain some insight as to what I should work on or do differently.


8.29.2016

Final Day Thoughts


I started Bitphoria in April of 2014, focusing solely on how the world was generated, represented, rendered, etc.. I had a pretty clear vision of what I wanted the engine to be capable of, and I feel I have achieved that.

Yesterday I finally reached the 20k lines of actual code that I predicted Bitphoria would have by its release date. The scripting manual for making games out of Bitphoria is complete. I'll be uploading the game tonight for release. It's a public beta version that has all of the features I wanted but are not fully polished and probably have some bugs. The goal is to see what kind of feedback comes from releasing it in the state it is in. I haven't been actively promoting Bitphoria very much at all, and figure that if it's any good it will sell itself by spreading via word of mouth. People will post screenshots, youtubes, start making games, playing against eachother online, etc..

Only time will tell.


Bitphoria's source code folder, comprised of 20k actual lines of code.


Tomorrow I will be sharing its release on Reddit and other various online communities, so we'll see what sort of response develops. This blog itself has just been a place for me to share my thoughts, and it does get a few dozen hits a day now, but nothing I would consider a great internet success, not by a long shot. I hope some people have found enjoyment and value in my blog, and perhaps if more people knew about it there would be more people that did find value in it.


I developed Bitphoria on my own time, while being a full-time stay-at-home Dad and running an Etsy business with my wife Heidi. It's a project I've always wanted to do, that I've attempted many times for the past 20 years, and life always seemed to get in the way. It was a matter of time before I finally made something.

Bitphoria's future is in the hands of the people after today. Once it's out there I'll probably stop working on it altogether unless it starts developing some kind of following or fanbase and I begin receiving feedback. At this point, it will serve as a great portfolio piece that demonstrates how well-rehearsed I am with all aspects of game development, from graphics programming, to networking programming, procedural techniques, and everything else in-between. This is just what I could do by myself in a limited amount of time, and I could do a lot, because I always dreamed to.

Bitphoria avoids issues like asset management and art pipelines, because I didn't plan on having artists, I planned on the players being the artists, almost in the same way that Quake and Half-Life were made popular by Team Fortress and Counter-Strike respectively. It wasn't the base game that made the game famous so much as it was the creativity of the masses. I'm counting on this, somewhat, with Bitphoria, and the fact that people like to make stuff. Bitphoria is meant to serve as a platform for people to create and share their creations, by abstracting things in a highly simple fashion that is easily accessible through a simple script-based construct.


Bitphoria's initialization function.


My goal was to have three separate games for players to play that were somewhat fleshed out. I will probably flesh them out in time, but I spent more time in the engine code than I had thought I would, so this first release will only really feature the deathmatch game, and the two barely-started CTF and instakill games that are far from complete. Fortunately every functionality of the scripting system is utilized by these games, for I had to test each one while developing it, so they appear somewhere in at least one of the three games' scripts. Hopefully this, in combination with the scripting manual I toiled to produce, will allow someone to start making something more inspired than the default games. The capabilities required to make a great game is there, that's a promise.

The master server will be running once I upload and link the release. I haven't fully tested it yet, so if you're one of the first people to download and playtest with a friend, please let me know if you encounter any issues immediately, so I can rectify them as quickly as possible and get something that people can fully dive into without having to worry about being able to connect with other players.

This is going to be a sort of Wild-West time if Bitphoria picks up and people start taking interest. There will probably be bugs and simple tricks to take advantage of the game, perhaps malicious server-crashing bugs, etc. that will be discovered and exploited. If these are found I will solve them just like everything else throughout the game's development, and they will only be found if people are actively trying to enjoy it. If people want more from Bitphoria, I will work to provide it, and it will be a process but we can get it there. I've been developing Bitphoria in a virtual vacuum, without much outside influence or suggestion, aside from the few comments coming from my long-time friend Paul Hindt. Other than that, this is the first time Bitphoria will see the light of day. This is going to be the worst Bitphoria release yet, and better ones are to come if enough people are interested.

If the game is DOA and nobody takes interest, I will eventually release the engine's source code as well, because I feel it is important for people to have resources to gain inspiration, insight, and ideas from. I took a lot of inspiration from the Quake engine, and the original Cube engine, insofar as some of the conventions for game logic are concerned.

Following in the same vein, Linux and MacOS ports will not be hard to produce being that the game runs almost entirely ontop of SDL2, but I don't plan on doing the necessary steps to releasing ports unless a demand arises. The only platform-specific code involved in the engine, as a matter of fact, is the code that lists all of the games in the games folder. There is no platform-independent method for listing the files in a directory so I wrote a simple command-line that performs a 'dir' command and dumps the result into a temp file that is loaded and the names of the game files are then extracted from. Other than that everything is occurring through SDL, so it shouldn't take very much time to compile ports.

All-in-all this release could have happened sooner, but I didn't want to have an Alpha release that lacked many features from the final product. At least at this point they are present and accounted for. There are maybe two or three little things I'd still like to add in, but at this point the project needs to get into the hands of the public so we can see what happens with it and where it should go next, if it is something that's bound to go anywhere at all.

Ultimately, if Bitphoria becomes somewhat popular, I will be pushing for actually selling it. To mitigate piracy I will be selling online player accounts, following the Minecraft model, which will integrate with the master server and be required in order to play on servers that are listed on the master server. That's down the road, but is solidly the plan if, again, people show interest.

8.02.2016

Bitphoria's Release Date Announcement


 I have decided to make my 30th birthday the release date for Bitphoria, which happens to be August 30th 2016. There are several things I'd like to finish, among bug-fixes and networking improvements, before the first release and I thought I'd share that list here. Whatever state Bitphoria is in on that day it will be released.

It is obviously crunch time now (a great motivator for me) so the things on my list that I'd like to have done might be cut short, but I will continue working on it well into the future beyond the release. This will manifest itself in the form of new and updated releases. The initial release itself is meant to serve further development of Bitphoria by allowing other people to finally start messing around, playing games, scripting games, and providing me with bugs and feedback about everything.

I plan on releasing Bitphoria as a sort of public beta, for people to get to know it and see what I've dumped almost two years of my life into. Maybe down the road I will sell it for a few bucks on Steam/Itch.io. Maybe I should crowdfund polishing it, because I clearly have something that's worth something to someone, somewhere, out there, and I think it has a chance at being a crowdfunding success (after all the hard work is done already).

Hardware contributions/donations are always welcome! ;) I'm currently developing Bitphoria on four different machines: two low-end laptops from a few years ago, a low-end pre-built HP desktop from the same time, and a custom-built desktop - all with integrated graphics. I did manage to borrow an nVidia GTX 680 in the custom-built desktop system that allowed me to record some footage of Bitphoria earlier on, but have since been without and could definitely use a decent GPU just for the sake of tuning Bitphoria's graphics to where high-end systems can be fully taken advantage of for hardcore PC gamers, as well as allowing me to record updated videos of what Bitphoria looks and behaves like. Recording video is actually my primary goal insofar as GPU acquisition is concerned, because without it I will have a harder time demonstrating the game. Worst-case scenario hopefully fans out there will take it upon themselves to youtube videos of Bitphoria. If nobody does that then I've failed at making something that sells itself, obviously, and that's the goal of any project of mine!

If the case is that nobody ever cares about Bitphoria, and it just gathers cobwebs and dust in a dark corner of the web (on this blog, and in a few reddit posts), never amounting to anything more than just a "portfolio piece" for me to acquire a dead-end soul-crushing software engineer job, then at that point I will just release the code in its entirety for everyone to tinker with and learn from. At any rate, the code will ultimately be released eventually. The 'when' of that is still up in the air, and probably will be for at least another year. But if I can earn a living for my family via my lifetime hobby then I'm certainly going to try before giving it all away. Over two decades of programming experience has gone into this project, and there are even things that I learned along the way while developing it that I'd like to invest into a new game engine project, but those are things that I'm just going to hang onto until I feel that this project is 'done', through-and-through, which includes promoting it to a respectable degree that hopefully provides it with enough exposure to ascertain as to whether or not it is something that there is interest in.

As far as my pre-release todo-list is concerned I believe that setting up a master server for people to find each-others' games is imperative, otherwise the whole project is pretty pointless if people can only start a game server, run around by themselves, and then quit out and never play it again. Scripting features and functionality seem less consequential and could be added in along the way at a later time after the initial release, but the existing setup is rather competent. Finishing the scripting documentation also remains a top-priority issue due to the fact that I wish for people to be able to start playing around with the engine itself to see what they can come up with within the creative sandbox that it represents. It has its quirks and nuanced requirements insofar as game performance are concerned (graphically, physics-wise, and networking) which is the case with any game engine out there. However, I would like to point out that it takes no game-development know-how or modding experience to make something out of, or with Bitphoria. Anybody should be able to simply open up the script files that comprise the default games included with Bitphoria and start surfing the documentation to figure out how it all comes together.

Here's my list of things left to do for Bitphoria before releasing it that I'm currently focusing on for the next few weeks:


Master Server: Write and launch a master server to run here from my home to allow players to be able to start and find/join eachothers' games. Along with this I'd prefer to invest in a domain name that points to the master server (my house IP) for the in-game server browser to download the server list from. This would actually kill two birds with one stone. Firstly, it would eliminate the learning curve of PHP and MySQL that I'd need to traverse if I were to create an HTTP master server. I *do* have enough experience with both to make it happen but I'm not competent or well-rehearsed enough to simply knock it out within a day or two - and it would require that I implement HTTP request functionality into Bitphoria, be it by hand or integrating CURL/libCURL. Secondly, running a custom-coded master server from home would allow me to easily implement a NAT-punchthrough handshake protocol to allow anybody to start a game without being required to deal with their router/firewall and port-forward. Conversely, anyone else would also be able to join any game regardless of whether or not they themselves are also behind a router/firewall. This functionality requires that the master server notify game servers when someone is trying to join them, and from what IP/port, allowing the game server to go ahead and send a 'trailblazing' packet to the client player for the sake of tunneling through the NAT and have it route packets from that client player's address to the game server. To have a console application running in the background on my desktop, written in C, using winsock or SDL_net, that would be easy to manage would be much simpler and cheaper than any remote/online option I've come across so far. If at some point there's too much traffic for my home connection I'd then move the master server program to a dedicated virtual host and simply point the domain name at that, and everything will just continue working for everyone without any changes for end-users.


Network Buffering: Implement a network buffering system to, for one, allow for the simulation of latency and its fluctuation for testing/tuning purposes. So far I've only been able to generate repulsive/gross/erratic network behavior when my daughter watches Youtube/Netflix on her machine while I have two machines sharing a Bitphoria game over our wireless LAN. Also, in spite of my efforts to fight network update jitter using extrapolation when an update packet arrives later than intended, it would seem that Gaffer's strategy (gafferongames.com) of simply buffering network updates long enough to encompass most network jitter and then subsequently emitting them to the engine internals at the interval they were intended to arrive at would be vastly more effective in its precision and lack of interpolated correction. Buffering network packets as such would also allow me to simulate internet conditions locally without having to track down willing testers (I'm not really a 'people-person', and I have no more computer friends left) and fine-tune everything for what I like to think of as the 'fringe-market' - people who don't have high-end gaming systems (a netbook) or fiber-optic connections. I'm of the mind to release a game that looks prettier the better the setup, but also is completely performant on less ideal setups. Why focus on one area of the market if you can focus on the entire market?

Scripting System Documentation: Finish the scripting system documentation, which would include indications as to where inside of the the sample/default games that are packaged with the initial release that users can find examples of each script command, along with tips/tricks. Also, early on I made it a point to document everything that I script for Bitphoria because I know that people out there should be encouraged to tinker around and pull everything apart.

Artificial Intelligence: Add in simple AI functionality that allows an entity to seek out other entities and designate them as its target, which it can then follow or aim at. This would make it possible for simple zombie-type enemies that just follow players and harass them while they try to carry out other things. I'd like to include some kind of simple navmesh generation that is derived from the distance field of the world but I am thinking I am just going to literally index the distance field and use that for obstacle avoidance while entities try to pursue other ones. If a target is unreachable then it could back out following the distance field outward until the target is visible again, or a new target is found.

World Generation Modes: Add options for the style of the world generation itself. Right now it's a fixed algorithm and starting a game server entails selecting a random seed and then a vertical-scale which is forwarded to clients so they can then generate the same world themselves and play. The world is generated as a 128^3 volume and there's a lot more that could be done with it than just leaving one algorithm in there for people to experience.

Physics Attachment: Entity attachment which allows for an entity to literally attach itself to another entity and inherit its position/motion, with or without an offset that is oriented with the entity being attached to. This could be used for CTF games or power-up modes that want to display some kind of visible effect.


These are more-or-less listed in order of priority. What actually happens by the release date is still completely variable, these are just my intentions and goals, and it's hard to say what exactly will occur as I pursue each bullet point.

6.19.2016

Bitphoria Screenshots


 I just felt compelled to post some new screenshots. Not much has changed as I've been working on underlying stuffs and writing the scripting manual, but it sure looks purdy.








Check back soon for more updates. I'm in the midst of designing the master server situation so players can start and find one-anothers' games easily without any port-forwarding nonsense. I'm also hammering out the Bitphoria Scripting Manual as a guide and reference for people who want to make their own games out of Bitphoria and share them with the world via the ingame server-browser. Players do not have to download anything externally to play custom Bitphoria games. It's a thing of beauty.

4.29.2016

2D Rectangle Overlap Algorithms


 While working (not so) diligently on the re-write of Holocraft I encountered a situation where the need for an age-old algorithm arose. The algorithm itself, and/or its implementation, has had many minds over the course of time to boil it down to a few bare-necessity lines of code.


Example of the problem and some possible conditions.
From: http://www.owenpellegrin.com/articles/vb-net/simple-collision-detection/

 Determining whether or not two rectangles overlap or intersect has been one of those problems that has found application in many a project. It's rather simple to implement, and most novice programmers take pride in discovering a solution to the problem, even including the case where the algorithm is extended into the 3rd dimension in the form of 'axis-aligned bounding-boxes', or 'AABBs'.


3D axis-aligned bounding boxes intersecting.
From: http://www.miguelcasillas.com/?p=30

 There have been many games which utilize either a 2D or 3D variant of this algorithm to determine if two objects in a game world are colliding with one-another. The original Quake game is an example of a game where entities had their collision volume defined by way of an axis-aligned bounding box. This caused players to axially slide off other objects as if they were a flat cubical shape. Personally, I prefer using a cylindrical or capsule collision volume for players and NPCs, because this gives a smoother collision resolution where the player just sort of slips and slides around other players and objects. Most modern games utilize this sort of collision volume for players nowadays for low-fidelity intersection tests, and sometimes as a pre-test to avoid the cost of doing more intricate intersection tests in the case of hitscan weapons and the like.

 At any rate, during my outset to re-write Holocraft it became clear that it was imperative that there be a way to detect where groove optics are overlapping, or otherwise intersecting one-another due to the fact that many of my trial-holograms thus far have been muddied in areas where the density of intersecting groove optics is too many. Too many intersections and too much overlap of grooves can completely annihilate the clarity of their reflectivity. The solution is to prevent the machining process from scribing over the same areas, allowing the fore-front optics of the hologram to take precedence over the background optics, optimizing the overall clarity of the hologram as a whole.


A screenshot of the new Holocraft showing the geometry and optics of a moderately detailed specular hologram. As you can see it is very easy to create many overlapping and intersecting optics (the curved colored lines) which will reflect light to depict the white dots along the edges of the model's geometry. Blue optics will appear nearest, red the furthest, and green will appear with mid-range depth.

 Now, per Matt Brand's whitepaper on Specular Holography, groove optics are hyperbolas that are calculated from the assumed incident light ray altitude angle that will be illuminating the hologram. I have chosen to calculate from the the hyperbola a cubic Bezier curve, which is defined by a starting and ending point, and two control points which dictate the curvature of the line that traverses the space between the endpoints. This curve then serves as the internal representation of the base shape from which all optics for the hologram are then derived, based on the 3D position of the point that is chosen from the source hologram geometry's vertices, edges, or surfaces that will be depicted by this reflective optic.

 These optic curves are segmentized by an occlusion-culling pass, which designates which spans of the curve should reflect light based on whether or not the hologram geometry should be 'blocking' their visibility, on a per-degree of viewing angle (or 'azimuth') basis.

 Once these segments of visibility are determined I then need to determine which ones are intersecting or otherwise overlapping one-another too closely to cause degradation in the final hologram. One way is to brute force compare the distance of every single point of each optic segment against every single point of every other optic segment to determine if the segment needs to be clipped or split/culled, etc..

 To speed this process up I have resorted to the use of a simple bounding rectangle overlap comparison. Effectively, this is a 2D axis-aligned bounding box intersection/overlap test. This is what I call an 'early out', where the core loop that is performing these comparisons and tests can quickly and cheaply pre-determine that there is no possible way for two given optic segments to be intersecting (because they are, for example, on opposite sides of the specular hologram).

 If there *is* an overlap detected between the two rectangles bounding two optic segments, then Holocraft proceeds with a more detailed comparison of the two segments, effectively comparing each point on each segment with each point on the segment in question. This is a simplified explanation of the actual process which determines overlap/intersection, as the actual algorithm uses a heuristic method to dynamically adjust the increment at which it 'steps' along each segment to the next point to compare with all the points of another segment to perform a distance check. This helps to accelerate the process, which is albeit fast enough without the heuristic method being as Holocraft only performs intersection detection when the user is saving the holographic output, currently as either an SVG vector image file or directly to CNC g-code.

 Now, the whole point of this blog post is to share the method by which I devised a rectangle intersection test that serves more utility for Holocraft's purposes. It would seem that with my growing years as a programmer I have been growing a rabid aversion to doing things the tried-and-true way, with a sort of desperation to find a novel way to go about doing things that people have already been doing another way for decades.

 A part of the heuristic method by which Holocraft accelerates optic intersection/overlap detection relies on knowing the rectangle of overlap itself in which two given segments are possibly intersecting. Knowing that their bounding rectangles is overlapping as a mere boolean piece of information is not sufficient for it would require that *every* point on each segment is compared against *every* other point on the opposing segment. To minimize this only the points on each segment that are within the overlapping area of the rectangles is considered.

Here's a copy-pasta of what Holocraft does:


//
typedef struct
{
 float x, y;
} vec2;
//

// 2d rectangle
typedef struct
{
 vec2 min, max;
} rect2d;
//

#define MAX(a, b)  ((a) > (b) ? (a) : (b))
#define MIN(a, b)  ((a) < (b) ? (a) : (b))

// returns zero if no overlap, otherwise returns
// area of overlap and optionally the rectangle of overlap via '*o'
float intersect_rects(rect2d a, rect2d b, rect2d *o)
{
 rect2d c;
 float dx, dy;

 // find horizontal overlap
 c.min.x = MAX(a.min.x, b.min.x);
 c.max.x = MIN(a.max.x, b.max.x);

 // not overlapping horizontally...
 if((dx = c.max.x - c.min.x) < 0)
  return 0;

 // find vertical overlap
 c.min.y = MAX(a.min.y, b.min.y);
 c.max.y = MIN(a.max.y, b.max.y);

 // not overlapping vertically...
 if((dy = c.max.y - c.min.y) < 0)
  return 0;

 // caller requires rectangle of overlap ?
 if(o)
  *o = c;

 // return area..
 return dx * dy;
}
//


 This is with the goal of quickly calculating the rectangle of overlap itself, while putting priority over the horizontal check over the vertical check (perhaps in Holocraft's case this should be reversed?) and will bail out if the horizontal overlap fails before bothering with the vertical overlap check.

 This is in contrast to most of the functions you will find on the internet, which perform a few simple greater-than/less-than checks against the min/max of the bounding rectangles/volumes and provide no other useful information.

 In the past, for game physics, I would just make everything a sphere and perform a simple pythagorean distance check against the combined radii of the two entities in question. I almost opted to use circles as early-out bounding volumes for optical segments until I actually sketched on paper how much extra space a circle would typically have over a simple bounding rectangle.

 Incidentally, the rectangle boundary calculated for each segment is derived from the convex hull of each curve, which is defined by both the endpoints of the curve and the control points that define the shape of the curve itself. It is said that the entirety of a cubic Bezier curve is contained within this area, and if there was a fast way to perform intersections against these convex hulls then that is what I would do, but there really isn't. This would require a series of line intersection tests and be quite a bit more complicated than it is worth.

Demonstrating the confinement of a cubic Bezier curve to its convex-hull, as defined by its endpoints and control points.
From: http://www.scratchapixel.com/lessons/advanced-rendering/bezier-curve-rendering-utah-teapot

 One of the advantages of using cubic Bezier curves as an intermediate representation is that outputting a vector image via the SVG file format allows for cubic Bezier curves to be defined as-is, without converting or transforming to any other form.

 This is in contrast with outputting CNC g-code, in which machine toolpaths can only be defined as either linear or circular motions, requiring an intermediate step in Holocraft which deduces a series of circular arcs chained together to form an optic curve. This is done within a user-supplied tolerance value, to give some degree of control over how large/complex the final CNC g-code output is, and the degree to which the machined grooves are faithful to the calculated optic hyperbola.

4.03.2016

NewbieTime is Live


 I made a game for my children called NewbieTime. It's an idea I had a few years back but didn't get around to working on until last summer in the middle of Bitphoria development. I had everything pretty much finished and polished and ready to release and somehow decided to move on to other things instead. Well, I stumbled across it and decided it was time that it saw the light of day and now it's live for download/sale at deftware.itch.io.



 Check it out and let me know what you think!

 Working on a re-write of Holocraft that is much cleaner. After much aluminum scoring and grooving I had come to the realization that I needed to mitigate the fact that groove optics were allowed to intersect with abandon. This allowed for spots on holograms that are densely populated with optics to appear 'dirty' and effectively ruin the holographic effect. In order to properly deal with this within the way that Holocraft was slapped together would be just more sloppy work, so I opted to re-write to allow for much better.... well... everything.

 Occlusion culling will be on-point, and the program itself will run much faster, and deal with larger and more complex geometry much better. More on this once it's finished.

 Also on the todo list is documenting Bitphoria's scripting system, which is the final step before an initial public release. I want people to be able to begin playing with the scripting system and see what they come up with. Multiplayer functionality is all there, and entire games can be made out of Bitphoria but I have not been so inclined to actually make a game as of the past year.

 I still need to figure a master-server setup that will allow players to easily start and join one-another's games. This will be included in a later release.

4.24.2015

BITPHORIA, The Game Itself


It occurred to me that most of what I write about on this blog has been the technical side of my thoughts and ideas while working on my game BITPHORIA. I haven't really been posting much in the way of actual progress on the game itself.

I thought I'd take a moment to share what is going on with BITPHORIA. As of now, by my estimation, the game engine is 80% done, and the game itself is roughly 15% completed. I am currently on the cusp of moving from working in the engine to working in the default game scripts.

I have spent a long while tweaking the visuals over the months, and trying out different little tricks, in an attempt to refine the overall appearance of the game into something that is stimulating and attention-grabbing. My entire philosophy on anything is to make it so visually appealing that anybody who sees a screenshot will automatically find themselves looking for a video, and anybody who sees a video will want to play the game.

If BITPHORIA doesn't captivate, visually, through a screenshot, then something needs to change. I don't want to make a product that isn't good enough to sell itself. 






I think that these screenshots portray the overall aesthetic and graphical design of what the final game will consist of. You'll probably notice the low frame-rates that my netbook achieves. It's playable on here, but you will want something with a half-way decent GPU to perform the raymarching on the 3D texture materials. There will be options to reduce the demand on the GPU so that it will be smoother for players with budget/older hardware.

The scripting system is mostly in place. There are a handful of features that I aim to implement to expand functionality further, but the majority of all the commands for scripting each system are present and operational. There is still a lot of validation and verbose warning/error stuff that I need to go back in and write in there, to help aspiring mod developers along.

Documenting the sets of commands for each system is another task that is needed. I am not sure about when this will happen, because I intend to do most of the scripting for the game myself, and so it isn't something I have a need for until the game is released. Until it's released, I am really the only person who will be using it, and I'd like to finish BITPHORIA as soon as possible.

Netcode is operational. Players can start a server and it can be joined from another machine, on a LAN, or over the internet. There is no server-browsing in the menu yet, but that is on the todo list, which goes along with other menu UI features I'd like to add in for various things. One in particular is a sort of holographic preview of the world-volume that would be generated from the current seed value. As a server admin adjusts a slider for the seed value it updates the preview of the world so the user can get an idea for the type of layout that their game will offer other players who join in.

I have a good number of sound effects already in there that I have produced on my own, some of which have yet to find a use. There are 23 different sound effects, and only about half of them have found a place in the current scripts. I feel that I will use up the leftovers and need to make some more sounds before all the sounds are done.

I have also produced several 2-minute looping music tracks, that suit the general low-fi 8-bit aesthetic that underlies the graphical style of BITPHORIA. I'm not sure if all of them will make the final cut, and I'm not sure if server admins who start a game will be able to choose one themselves or if one will be randomly chosen based on the seed value for their game.

Because of the way the scripting works, where a set of scripts defining one game 'mode' is kept in a folder with the name of that game mode, users will be able to duplicate a game script folder and use it as a base for their own modded game mode. The scripts are relatively simple script files, and all that is needed is the documentation for the various commands that each scripted system utilizes. Anybody will be able to edit their script files to customize their game modes, or just create their own new one from scratch.

When someone has produced a BITPHORIA mod, there is no need for other people to manually download and install anything to their BITPHORIA installation. You simply see what game mode servers are playing in the server browser, and automatically download and run the mod when you join in. Infact, no scripts are loaded when you join a server, you only execute whatever scripts the server executes. This allows complete modding freedom. Anybody with BITPHORIA can play your mod, instantly.

If someone wanted to run their own server using a specific mod, they would need to manually download and install the mod scripts. This could change, I may set it up to allow servers to have the option to 'allow mod copying' for clients, at which point the server would let clients download the actual script text files and save them to their game for later use.

All of this is working, the game is currently playable as a simple little deathmatch game. The UI is vastly incomplete, there are no options for setting up a game, or joining a game. The menu system is started, but not currently 'fleshed out'. It is merely a framework with some minor functionality to traverse menu hierarchies using buttons. There are also nice little editboxes for editing configuration strings :)

I started the code base for BITPHORIA exactly a year ago today. It has just over 16k lines of actual code (not counting comments or whitespacing). I have never written 16k lines for one project in my life, nor have I ever worked for a year straight on one project. I have high hopes for BITPHORIA, not as something that will make me rich and famous (although, one can hope), but as something that the gaming industry takes notice of. I figure, at the very least, it will serve as a good portfolio piece if I ever breakdown and decide to get a job working for someone else (ughh).

I feel I have something valuable to contribute to gaming, as a whole, as well as anybody who aspires to make games or learn programming. I just want to be as valuable a resource as I possibly can, whether that means as a provider of fun and interesting games, or creative inspiration.

I hope people find my ideas as intriguing and enjoyable as I do making them come to life.

11.12.2014

Procedural Modeling and Animation


I failed at maintaining at least one post per month, a lot of distractions are abound! I've been trudging away nonetheless. The project is at a point where I am leaping from one milestone to the next, some days being spent refactoring smaller support code and/or adding functionality to various support systems.

I have just added some code for dealing with quaternions for representing object orientations, as euler angles will just not suffice for the physics interactivity I am striving for. To represent rotational velocities I have also added code to handle axis-angle representations, because quaternions inherently limit rotation to 180 degrees, or in the case of rotational velocity 30 RPM.

One feature of the engine that I was looking to implement is procedural model scripting. The goal here is to allow a user to easily script a game 'model'. A model consists of vertices defined for the three basic primitives which are points, lines, and triangles. Each of these vertices have a RGBA value for rendering a color.

The primary advantage of having scripted models are that anybody can edit them, without learning modeling software. All you need is a text editor - which I aim to build into the engine in some capacity (after making a release) to eliminate the need for alt-tab madness. Scripting a model is a matter of cleverly putting together a series of commands that rotate and translate to reach the desired position of each vertex for the desired primitive type.

Another advantage of using procedurally scripted models is that game server admins can run games with their own custom models, which are quickly and easily transferred over the network to player clients. Clients can then generate the actual models by executing the procedures defined therein. This is huge because it is another goal to allow server admins to run entirely customized games without requiring players to download and install anything manually.


A script for a 'sprial tree' model, demonstrating the use of nested loops.

Scripts are also afforded the ability to 'randomize' various parameters. Things like translate, loop, rotate, etc. can all be randomized using a minimum value and a range value. Each time an entity requests a renderable model 'instance' the system checks if the model is invariant or not. If the model is not invariant, this means it uses randomized parameters in some way, and must be re-generated for each instance requested. This allows the system to take one model script, and generate many variations using different seed values to generate the randomized parameters for the operations that use them.

Another feature of the modeling system is the ability to push/pop the current matrix and loop counters. This allows for recursive modeling of hierarchical things like trees, plants, and other fractal shapes.


Some spiral trees, and dynamic mesh player model.

Along with scripting individual procedural models I have implemented an animation system that I devised a long while back. This was yet another chance to embark on a journey that strayed from the norm. I love skeletal animation, and inverse-kinematics for making a skeletal model interact seamlessly with the game world, but I do not love the mind-numbing rote-implementation of features that all the creative work has already been done around. To me, programming is about problem solving, the deeper and more abstract the problem, the more rewarding it is to me. Infact, making a game all by itself isn't that rewarding to me (earning a living is good, though). It's the process and the challenges of making something involved that I find rewarding, and I wish more programmers felt the same. At any rate...

Conventional animation systems involve manipulating a mesh model using a virtual skeleton with virtual joints. Keyframed animation is stored as angles for each joint, and is easily to interpolate for smooth animation between keyframes. Getting any keyframed animation to smoothly and seamlessly interact with the world and external forces like wind, inertia, gravity, collisions, etc.. is tricky in and of itself. It's a challenging problem. Some games only let the model/skeleton interact when the character is dead, allowing the body to flop around in response to external forces. This is known as 'rag-doll' physics. There are various solutions now for handling these sorts of things, both for animating and dead character models. There's even one solution that dynamically generates/modifies keyframed animations for things like walking, so that it looks as though the character is actually negotiating bumpy terrain with strategic footstep positions.

I did not want to plug in a solution, and I did not want to pursue a solution that was too involved. This is where the dynamesh comes in. Dynamesh is just a abbreviation of the term 'dynamic mesh'. A dynamic mesh is just a spring mesh, where vertices are referred to as 'nodes' and the edges connecting two 'nodes' are called 'links'. This is a simple system where each node is given a size (zero is valid) and a mass, and each link is given a rigidity value that dictates how will it retains it should retain its length.

This system is simple enough to simulate. It consists of two parts - a particle simulation for the nodes themselves, and an iterative link-constraint system that pushes and pulls the nodes of each link in an attempt to 'settle' the mesh.

So far, I have determined three uses for this system:

The first use is entity collision volume representation. Along with using spheres, capsules, axis-aligned bounding-boxes, and the like, it's nice to allow for more detailed collision hulls for bigger more complicated entities.

The second use of the dynamesh system, which operates in tandem with the first use, is rigid body physics. It is an automatic feature of this system to allow all the nodes to be in any orientation, with no real 'orientation' at any point in the code. Discerning anything like an 'orientation' involves examining the relationship between node positions, and comparing it to the original default orientation. This isn't too hard or expensive to do. Entities can use a dynamic mesh as not just their collision hull, but also to innately handle collision response and resolution. This enables highly interactive entity physics behaviors.

The third use is animation. Not only can you define a dynamesh that is rigid, but you can define one for a character, or a vehicle, or anything with moving parts. With one pair of nodes you can have a ball and socket type joint. With three nodes you can have a hinge. Through clever use of nodes and links you can create just about anything, and the neat thing is that simulating the nodes as particles that are affected by external forces and collisions allows for highly dynamic interactivity automatically, without any special-case code at all.

In this case I am using dynameshes for character animation, while allowing for an entity to have one scripted procedural model that is permanently attached to them, as well as one dynamesh, which can have models attached to its links. This makes it simple enough to define a character dynamesh.

Keyframed animation is a matter of storing node 'goals' for each keyframe, and pushing those nodes toward their goals when a specific animation is playing. In this case I am procedurally generating running animations through some simple manipulation of foot/knee nodes. Dynameshes must define anchor nodes, which are used to fix the mesh to the entity using them. Entities are essentially dragging the mesh around the world, unless the entity type specifies that it is to assume the physical state of the dynamesh, then the anchor nodes are used to dictate an entity's position/orientation.


Links:
Lightweight Procedural Animation ... by Ian Horswill
NeHe Productions: Rope Physics
QUELSOLAAR.COM: Confuce - Procedural Character Animator

9.21.2014

Collision Detection with Distance Fields


One of the great things about doing a Minecraft-style voxel engine, where the entire world is made of cubes, is collision detection. It's very cheap to detect which voxels one should compare a game entity's collision hull against, and the math is very simple.

Minecraft: The cubic-voxel world game of the century.


One of the lame things about doing a Minecraft-style voxel engine is that Notch did it already (not to mention Minecraft's inspiration: Infiniminer). I am not making a cubic Voxel world. I'm not really even making a voxel world. I'm using voxels as an intermediate representation in generating my world. I don't even plan on making it very big, or modifiable. I'm not using marching cubes to make smooth terrain, and I'm not using boxy voxels either.


my voxel game thus far

After all the generation and stuff, the end product is rendered as polygons (triangles). I could handle collision detection between objects and the world in terms of spheres and triangles, or cylinders and triangles, or any mathematically simple shape and triangles. But triangles are yucky, and I don't like dealing with them. I especially do not enjoy the thought of detecting *which* triangles to test intersections on. Back in the days when I was a big fan of BSP trees, this would have been fun, but not anymore. I've moved on to bigger and better things (or, whatever).

What's nice about cubic voxels is that you can pretty much just index an array using your object's position and see if there are any voxels intersecting. In a Wolfenstein 3D style raycaster this is great for collision detection, it's just so simple to do. That's great and all, but I'm not using cubes. I'm using octahedrons that behave like metaballs and 'merge' when neighboring eachother. This complicates things.


Collision primitives from Cryengine.


My first ideas consisted of first assuming every object to be a sphere, or pill shape, and do a quick (hah) spatial search for the closest voxels. Then detect which faces are facing the entity, which edges and planes it intersects, calculate where any 45 degree planes may be (corners/edges) and handle the collision accordingly by moving the position of the object, and calculating a new velocity based on elasticity and friction values. This method seemed ideal for handling collisions using the sparse volume representation in memory only, and the sparse volume structure doesn't store information about the shape of the voxels, they are all just cubes as far as it is concerned. It was important to me that a slope of voxels could be ran up/slid down/rolled across/etc smoothly, without any stair-stepping. I wanted a 45 degree plane to behave like one.

The most difficult part of this solution was handling large objects with multiple collision points with different groups of voxels around themselves. I quickly realized that a distance field representation of the whole scene would solve all of my problems - efficiently detecting collisions with all object sizes while behaving as though diagonal voxels were one continuous 45 degree surface.



In this video of a 2D prototype I did last week you can see the green 'voxels' and the distance field rendered as a blue/red gradient that is generated using a simple distance transform that propagates distances over the 'volume' in two passes. The circle is just a point in space which is used to index the distance field, which the value returned from is compared against the circle's radius. If the circle's radius is greater than the value at its center in the distance field then it is intersecting. Then it's a matter of checking the surrounding distance field values and calculating the gradient of area of intersection to determine a sufficient approximation of the 'normal' to properly de-intersect the circle and reflect its velocity with some amount of elasticity for a bounce effect.


As a bonus, there are other uses for distance field representations of a 3D scene. Distance representations are very handy for any line/path tracing, so it lends itself well to calculating lighting and shadowing. It is also useful for AI pathfinding and obstacle avoidance. Fluid dynamics can also benefit from a distance field representation for properly drifting particle effects around the scene realistically. I've already uploaded the same distance field to the GPU as a 3D texture to perform some ambient occlusion in the vertex shader, which has increased the visual depth of the game scene. It will also make the job of illuminating game entities much simpler.

The only downside to the distance field representation is memory usage. So far I'm just using a flat array, because I don't really see a very worthwhile means of compressing data as incoherent as a distance field. Conventional sparse structures, like octrees, will not be of much use. What would probably work best is a more continuous approach, like a cosine transform. Maybe dividing it up into 8x8x8 blocks and performing a discrete cosine transform (ala JPEG) would be a decent means of representing the data in memory? Each distance field query would then result in performing a bunch of cosine calls though, unless some quantization could negate most of them. Compression artifacts would yield bumpy surfaces, however.


Links of interest:
Wikipedia: Distance Transform
Gamasutra: Advanced Collision Detection Techniques

8.09.2014

World Representation


It's been a while since my last post, a lot of brain storming (as opposed to actual coding) has been going on. I've been exploring world generation and possible data structures for representing the world in memory. This all required that I make some important defining decisions about the world.


At the time of this writing, I have yet to decide on making the world dynamic (modifiable). This is primarily because of the cost of updating the world, finding a balance between CPU/GPU loads, and doing so over the network between the game server and clients. Another issue involves when a client joins a server, they must download the current state of the world from the server as it exists after any modification that has occurred. There are tricks and techniques for minimizing this data flow, so that the entire world volume doesn't need to be uploaded to each connecting client. Right now this is not a priority, or even a necessary feature for what I am trying to accomplish with this current project. This could change!


Being that the world is volumetric (voxels) it was clear that there needed to be a data structure to hold the volume in memory, not just for rendering, but also physical interactions with entities. Following with Revolude's original design - the world would be procedurally generated (as opposed to loaded) when a game was started, or joined. This data structure would require that it could perform efficient read/write access.


I examined the possibilities of a few different algorithms and data structures for dealing with volumetric data. A lot of algorithms for storing compressed volume data rely on the fact that the data represents direct visual data, like the pixels of an image, in the form of red/green/blue/alpha color channels. This allows for all sorts of neat 'lossy' image-compression style tricks to be used, which forsake exact reproduction of the original compressed data in exchange for smaller size. For applications where the volumetric data represents relatively finely detailed data, these algorithms are great.


For my project the worlds are not that large, or that finely detailed. Voxel size is on par with games like Minecraft and Infiniminer. The primary difference from these games is that voxels will not be cubes. Voxels are also represented using a single byte to store a material-type value, allowing for up to 255 different materials (material zero is empty space). Worlds are also not intended to be infinite. Instead of having worlds extend infinitely through procedural means, they will be a finite size, and wrap around seamlessly. There will be no edge to the map, nor will it go on forever into places that nobody will ever go.


I'm still settling on a specific world size. With the sizes I'm considering, storing the raw voxel data becomes feasible, without the use of any sort of sparse data structure. For example, with a world size of 1024x1024x256 the size of the world data is then 256 megabytes. Each horizontal slice of the world is one megabyte. The only qualm I have with just leaving the data sitting in memory, when virtually every machine capable of running the game has enough memory, is cache coherency. The larger the volume, the further apart in memory two neighboring voxels could lie. This is not good for performance!


It's arguable that using flat storage for a finite volume won't produce a significant slow-down when the volume is queried for things like collision detection and rendering. Personally, I just don't want to be using more memory than I need to, especially if a byproduct of reducing the size is gained speed. Above all else, I love the challenge implementing a sparse data structure ;)


The first obvious option on everyone's mind is a sparse voxel octree. This is a wonderful structure, but can become computationally expensive to iterate as it deepens. One strategy I had a while ago to 'enhance' the octree is to allow each node to have more than 8 children. Instead of 2x2x2, it could be 4x4x4, for 64 child nodes. This would allow an octree with a dimension of 1024 (gigavoxel) and 10 tree levels to only have 5 levels to iterate through from root to leaf. The issue here is that there would be excessive 'empty' child nodes all over a volume. This would be the price for faster iteration.


Another strategy, one which I became quite fond of since my last post, is to store volumes as run-length encoded columns. This is especially attractive because it effectively reduces a volume into a few 2D images, and would work extremely well where voxels represent a limited number of materials (as opposed to highly variable 32-bit RGBA values). Many areas of the volume would be one or two column 'segments'. This approach was almost the one that I finally settled with, but I was having implementation indecision issues, trying to find a 'sweet spot' balance between speed, size, and simplicity. My obsessiveness with finding the perfect solution became a hindrance to progress.


Ultimately, this lead me to fall back on an older idea, which is really an amalgam of a few ideas. At the coarsest level, I represent a volume using a sort of hash-table. This is just a flat array that divides the world up into fixed size 'chunks'. The trick here, then, is to use a sparse voxel octree to represent the contents of each chunk. Using some efficient design, a chunk that is entirely one material (including empty) is stored as four bytes. The rest of the chunks, which I call 'boundary' chunks, are stored using a variable number of octree nodes. Each one has its own pool of octree nodes from which it builds the sparse octree representing the organization of voxels and their material indices. This node pool starts out small, and is reallocated as needed by doubling its size each time it fills up.


Currently I am working with chunks of 32x32x32, which is 32768, or 32k, of voxels. This seems like a nice round number, because I can fit an octree node index into 15-bits (16th bit flags leaf-node status). Now, in an octree, if each voxel could be a different material (32k different materials) then there would be an overflow because inner nodes would require more address space for 4680 nodes, but I am willing to bet that with less than 256 possible voxel materials this 'special' case chunk will never occur. Most chunks will never even see 10k of nodes.


With chunks that are 32k voxels in size, this means that a 64-gigavoxel volume (4096^3) would consist of 32k chunks. The flat array of chunks for a 64-gigavoxel volume would be less than a megabyte. The total size of the chunks themselves could vary, but would average less than 100 megabytes. This is really great for 64 gigavoxels. Now, I'm not going to be representing a world that is 64 gigavoxels, I don't think. I'm thinking smaller, because the goal here is a game that is more of a multiplayer online battle arena than some sort of vast expanse for an MMORPG.


This is actually how all volumes will be represented in memory, in terms of materials, and out of chunks. Some game objects will be displayed using volumes, some using other graphical techniques. This is a global 'voxel' solution.


Links of interest:
Visualization of Large RLE-Encoded Voxel Volumes

An Analysis of Minecraft-like Engines
Ken Silverman's Voxlap Page