Wow using voxels as the close-up planetary terrain is a mad and brilliant idea! What scale were you thinking?
Not too huge more like “Freelancer” sort of sizes in terms of a planetary system/sector. I was also thinking in amongst a few planets could also go towards some mechanics from other games too. Though probably more strategy type games than a free roam space simulator with voxels possibly haha.
What I mean is, assuming that when you say “planetary landings with voxels” you mean zooming down into the planet until, when close enough, resolving the terrain into voxels, what scale would you be thinking? I guess another way to say it is how many theoretical voxels across would the diameter of the planet be? Naturally you’re not talking about literally making the entire planet out of voxels, just as much as you could see locally when the spaceship lands, right?
Yeah absolutely, I definitely can’t be rendering a whole planet as voxels at once as such. That would be a bit bonkers to try haha. Although it depends on Codeas abilities with its craft built in voxels/chunks, with considering Codea must be culling, geometry, voxels and possibly chunks too. My general though process was taking the same sort of approach of streaming, on the fly, like games such as GTA is a well known example, as well as also being how NMS accomplishes the same too. You only really need to worry about drawing what the player can “see”, although the hard part is working out what their view is precisely and what that means you draw and don’t draw.
For streaming asynchronously, this is where the Task classes functionality comes in, significantly with using coroutines to do background work, arbitrarily in terms of work function definition, which I am then using timing small amounts of work being processed before yielding / sleeping until completed. Which is all then driven from the draw/update function based hook calling Tasks.update().
While often in most games, and particularly in games with dynamic worlds. Streaming conditional and/or ‘viewport’ dependent drawing, as in a frustum hit detection algorithm for example, is based in approaches needing an efficient structure to “look up” your entities and drawables, collisions etc within the games logic. Then handle them conditionally as needed, e.g. to swap an entity to visible and being drawn by Codea or invisible not being drawn, saving Codea processing. If you can make it cheaper than just drawing everything to screen that is anyway.
Which then in circumstances like this is where structures, like a tree, come in. For example the quadtree implementation posted recently by @Kizik or the extra dimensioned / bucketed cousins octrees. That arrange and store entities in a similar structural approach to a binary tree, except by dimensions in terms of position vectors, if I recall correctly. So you have one bucket each for example for, +x,-x,+y,-y,+z,-z. So by inference here as you can kind of see from +x,-x and +y, -y dimensions, a quadtree is more optimised for handling 2D vectors. Where as in 3D typically being more complex, off the top of my head and again if I recall accurately. An octree becomes required as you effectively need a x/y/z position and a direction vector like vec3.forward to resolve a position / cast a ray along, a 3D line / effectively drawing an infinite tube out in a direction and angle. That is effectively ‘drawn’ in 3D space by a ray casting algorithm to see what it intersects with, in terms of hit boxes or geometry of entities.
Hope this helps explain my thought process a bit more, although I’m omitting a few particulars in order to keep some things hidden up my sleeve as it would be…until the time then comes to reveal them in a hopefully refined state
… eventually ![]()
wayyyyyy over my head I’m sorry to say. I may be having trouble asking the question simply enough. If I’m standing on the surface of the currently generated world, you could mark out an area roughly equivalent to the distance 1 in Craft xyz space. How many voxels do you see fitting in there?
I think the beauty of doing it with voxels is that everyone is used to voxel worlds having a limited render distance, making all the fov stuff moot. We show as much as Codea is comfortable with and use the voxel engine’s built-in fog past that.
That’s fair haha it’s a bit of a technical explanation. In short yes you imagine an area and “limits” around a player to constrain it for performance. View distance is a good example of this or LODs / level of detail. Really what I am saying is there will be more than one technique, most likely, each optimising different parts of the game/implementation to keep it smooth. Then you’re just doing a magic trick like holding a postcard in front of someone’s eyes. While they see the picture on the postcard, they are there, if they move their head, you move the postcard / window they are looking through accordingly. Another way to think about it, somewhat, is the player remains in a static position and you move the world around them. The effect is the same visually, similar to how for video you only actually need about 25fps for it to be imperceptible as a difference between 60fps
So although naturally in theory a game running at 60fps is “better” and more optimised possibly, you can get away with 25fps. Though dropping below towards 25fps becomes easier to see stutters and is less ideal, as at a certain point of low frame rates it does become perceived by the player. The objective therefore is to not break the illusion.
A basic approach is just draw a circle round the player, everything that touches the circle is shown, everything outside isn’t, although this could be like walking around in dark room with a torch as a visual analogy. Hope this helps make it a bit clearer from a different point of view. If it does, have another reread of the previous comment and hopefully it should also make sense.
A question to ask yourself is, if I was Rockstar, developing GTA5 or GTA6, would I draw the whole open world, as in every asset contained in about 100gb or so of models/textures/materials/shaders etc etc on every frame redraw in order to get it on to screen? If not how do you make it appear the whole world is there and always there, to the player, even though it can’t be. Considering hardware limits such as a typical amount of desktop RAM today is probably between 8-16gb on the low end, 32gb perhaps on more mid, then higher sizes are ‘premium’.
Desktop games minimum/recommended requirements end up being designed around what the the company expects users in their target market to have for their computer specs. So if you define minimum/recommended RAM as 8gb, the game has to run on less than 8gb, as other programs require RAM too. As another further point of view about handling game requirements and using constructive constraints and magic tricks / smoke and mirrors etc to pretend like it’s not a limited environment in terms of raw hardware power.
By streaming assets therefore I mean, games which do this quickly load things, then unload them when you can’t see them, then reload them again, just-in-time, before the player is about to “see” that object, building, character/npc, which you know by say tracking the players movements and directions they area facing, how far away you are and so forth. Combing them together into the one overall ‘effect’ that you see on screen / in game. Also like composition of a picture / painting perhaps too.
Yeah you’re thinking far ahead. What I’m asking is along the lines of, say there’s a little bump on the generated world on an otherwise flat plain. To me, I’d want the voxel landscape to mirror the actual planet’s terrain, so if someone landed near that bump, I’d want to see the bump. And how many voxels high would that bump be? Would it look like a slope, a hill, or a mountain?
I once had a long chat with ChatGPT about how to do a simulacrum of No Man’s Sky in Codea. There were some interesting ideas. I’d share the chat except I lost my temper at it and I’d be embarrassed to let people see that. ![]()
Hahaha yeah I do that sorry ![]()
![]()
I see what you mean, you can generate a voxel map from the texture that skins the planet, as this effectively determines, water heights etc, as it’s a colourful heighmap in actual fact. So when this is used for procedural generation in this sense you just use the bitmaps that you paint the “splats” I think the planet generator calls them. Then determine what block it I based on the value of a pixel, which may represent say a 10x10x10 chunk or something. How to process the orbit view into ground would need some “magic” somewhere however though to extrapolate/interpolate what the planets scenery as you get closer. While as you move towards or away from the planet then this is also adjusting LODs / as you can start culling things as they get further, blur them as they are going out of view and so fourth. No doubt will take just a little bit
of refinement to keep it from exploding from eating all the memory available though! ![]()
Here’s my intuition from a gameplay standpoint.
It’s a matter of realistic versus easy I think.
The realistic thing to do would demand that there be a vast number of voxels between the coasts of even the smallest continent. It would demand that walking around the planet take as long as it would take to walk around the earth at Minecraft speeds.
ChatGPT on how long that is: Minecraft Steve could theoretically walk all the way around Earth in about 3½ months without ever stopping.
So that means the realistic thing to do is to make the planet have enough voxels in diameter that it would take 3 1/2 months of constant walking for our player to walk all the way around.
The easy thing to do is transition to voxels purely based on some arbitrary voxels-per-cubic-coordinate ratio, like, say, 500 voxels per single length of a Craft coordinate?
Yeah exactly you’ve got it there! It’s a balancing act in most games really, and they are notorious pieces of software for doing hacky work arounds. Such as a train which is actually a hat for an npc that walks underneath the map in Fallout 3 if I recall correctly. You can only see the npc by looking under the map, if that makes sense. So yeah you could indeed just say a planet is a 500 square when it comes out in the wash. Or you could also generate planet sizes too, say between 300-600 voxels. Then some planets would be bigger some smaller. So then you just have to decide what the min/max are.
Okay okay okay.
What’s your call?
We’ve talked it out—you make the call.
We don’t have to stick to it, it’s not in stone, but just off the top of the head or the bottom of the gut—what’s the voxel radius we should pretend the planet has when we simulate the surface?
I’ve had good results with something like a radius of 2-3 chunks, which are then in the region of 16x16xdepth or maybe a bit bigger. I would experiment with what the voxels system can take, possibly try push it to breaking point before walking backwards. Then base my numbers in those sorts of more practical experiments. An arbitrary number I usually just pick some power of two out of preference. That has the nice benefit of shifting proportionally with a bit shift too. But that is just me perhaps ![]()