• entries
    437
  • comments
    1182
  • views
    764831

Streaming

Sign in to follow this  

406 views

No shinies or screenies today, although I have some stuff in the pipe I'd like to show in the next few days. But today and yesterday I did implement something neat that I've been meaning to do for awhile: "infinite" world streaming.

I've always liked the idea of Dwarf Fortress-y large worlds, generated 'on the fly' as you travel them. I've done a lot of work with implicit functions, noise fractals, etc... for the purpose of creating randomized worlds, so of course the natural next step is to create a world that is infinite, or at least within the bounds of floating point precision.

I split the world into chunks of a set size. This size is tunable, so I can increase or decrease as I see fit. At any given time, only a certain neighborhood of chunks are loaded, centered on the player. This neighborhood is also tunable, with a minimum radius of 1, which will load a 3x3 block of chunks.

I wanted to skirt the limitations of single-precision floating point, so I implemented a system that incorporates 2 different coordinate systems. The current center chunk, occupied by the player, is always at offset (0,0) in the world for purposes of rendering. Each coordinate location in the world can be referenced in 2 ways: a coordinate x/y/z tuple relative to the Current Local frame, and a coordinate gridx/gridz/localx/y/localz tuple that is unique for every coordinate location in the world, expressed as double-precision floats. All of the implicit functions and generators that create world chunks operate on double precision, so I avoid the limitations of single precision, since single is only used for the current neighborhood for rendering, and I never even approach precision limits. And given the huge range available in double precision, my world is, for all intents and purposes, infinite.

Right now, it's not all that interesting though, and it is not persistent. As the camera moves and the "center" location changes, chunks are loaded and dumped as needed. Saving functionality is stubbed out, and loading simply defaults to generating on the fly from a generator module rather than loading previously instanced chunks from file. However, all of that functionality is stubbed out and tested, waiting to be fleshed out as I flesh out the world format and spec.

It works pretty neat. I worry a little bit about lag introduced by saving and loading, so I have introduced a system that uses a Lua co-routine that acts as a consumer, operating on a queue of saving and loading "tasks". Saving or loading or generating a chunk is broken up into smaller bite-sized tasks and queued up, with an optional priority system based on proximity to center so that chunks nearer to the center have their tasks processed first.

Currently there is no soft buffer zone to prevent "chunk thrashing" if the player quickly crosses and re-crosses the boundary of a chunk; chunks will be rapidly loaded and dumped, loaded and dumped. If this is a problem, I may soften the boundaries a bit to delay saving and loading tasks a bit, or try to spread them out more.

The coordinate plane extends "infinitely" in all directions. World generation is founded upon a chain of 2D fractals and other procedural methods, although this aspect also needs much fleshing out. Current terrain types are also very limited, pending further consolidation and development of assets.
Sign in to follow this  


0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now