Its been a frustrating 6months while I’ve been considering a particular problem; the use of floats to design an environment that needs to be very large.
I dont fully understand how this can be done, and would like some hints or tips to point me in the direction i need to go in order to see my project go somewhere.
This is the story so far;
I realise we are locked into using float variables with JME and some people on the forums have offered tiny amounts of advice on making large scale environments with these tiny 32bit variables, I hasten to add that its not a requirement for those people to help us design our worlds, but I would really appreciate it right now.
So far I ‘think’ the best way would be to split up my galaxy space sim into many sectors of space, and each sector may even need many sub-sectors (??) and each sub-sector would contain 1 solar system at most (Im sure you could appreciate most of them would be blank)
But even down to this level im not sure I see or understand… A Solar system is still massively large!
Should i be scaling the celestial bodies inside the solar system so they are tiny compared to the real deal? Is this truely the only way?
Could i use relative coordinates for everthing?
The sun is relative to a sub sector (could be measured in Astronomical Units)
A planet is relative to the sun (in AU)
A moon is relative to planet (in a fraction of AU)
The player is relative to the sun when far away from the solar system (in AU)
As the player gets closer to a planet, the player becomes relative to the planet (in AU)
As the player gets very close to the planet this becomes measured in kilometers or miles
Am i thinking about this correctly?
Looking for genuine comments, not the typical “its too big of an idea”
the way i have handled this before in 2d (my main experience) is that i have a container class for world objects, and world objects have a ‘true’ world position derived from their sectors position. and a ‘universe’ or ‘world’ is made of different sectors.
a design choice taken by a lot of AAA space sims is to take the sectors literally and to use the sectors effectively as arenas usually using some form of jumping mechanic to traverse between the sectors and all the sectors are generally far enough apart to allow this believably.
also ‘true’ 3d arena’s aren’t exactly common place and even though the levels are in a 3d space, the sector itself is kept to more or less a 2D plane.
i hope that helps
The scope of this is so huge and there are so many ways to implement that kind of thing. My game, which tackle the same thing, take a totally different approach. There are no bad ways of doing it.
For my part, I mostly wanted the player to have the possibility of seeing everything from a very different perspective… As I said, there are no wrong ways of doing it.
From your post I assume you want to make your “universe” as similar as possible to “scale”, with accurate distances etc. There are several projects that do that. Two of those are linked below. I suggest you read the dev diaries and see how they handle this. I’m sure you’ll find information to suit your project.
This one doesn’t have much as far as notes, but the sources are available iirc. It’s more of a “Space Simulator”. It’s very nice. http://en.spaceengine.org/
There’s a third one I wanted to link but it seems I don’t have it bookmarked. The first should give you a point of view.
Hopefully that’ll help.
How do you plan travelling around the map? Light speed?
I would just scale everything (including yourself) to make everything work. And somehow use fractals. Maybe make each sector an octree or something, and get the most common block of the octree when you’re x meters away so you don’t have to render as much. That way, you could make planets, etc. without having to render the whole thing at once. And when you’re far enough from, let’s say a star, it’ll end up just being one huge cube as opposed to lots of tiny cubes as a star.
I’ve just read over this and I don’t really get what I said, but I hope this helps.
I guess ive always thought that i need to scale things more or less correctly… because if i scale a planet down by half, am i not scaling the players spaceship down by the same factor? and so doesnt the same problem continue to exist?
I guess ultimately what im saying is, i dont want a comic style sim where things not proportionate to each other. Ie a Planet should be massive in comparssion to a spaceship. I guess things dont have to be perfect though… i just want something that will work!
I think the best way to travel around would be some stupidly fast engine that gets the pilot from A → B. Like something that literally folds space together to get to another place instantly. Im not interested in the understood realistic time taken to travel vast distances (ie i dont want players waiting 10 real earth years just to get to pluto! hehe).
In fact i dont even know if im thinking about this correctly, and maybe i need to re-word what i wrote above… Let me put it to you like this: If you wanted to represent a solar system with float variables, how would you do it?
I’ve browsed through code in a game called Pioneer (Frontier Elite 2 clone) and i see no evidence how they tackle this problem… it just ‘works’. I feel like im missing something… well actually i know that i am hehe. But am i making a mountain out of a mole hill maybe??
Do i instead make things smaller and just make the spaceship travel a lot slower, to create the belief the player is in a massive space environment?
I continue to be confused.
Just gonna thumb you up and say large space simulator seems very attractive
I would want to make one too if I didn’t have a project atm
It doesn’t matter if you make things smaller or larger if the proportions are the same… I mean float will still run out of precision either way. The issue with float is its range. In other words, you can have a teeny tiny value 0.000001f or a really big value 100000000f… the problem comes if you try to use them together.
You may find it easiest to represent your data with doubles. Spatial != game object, after all.
Then your only problem comes with how you convert your coordinates to work in the JME structures… and for that there are a few approaches. For a space simulator, you have the benefit that the stuff that’s close to you tends to be really close and the stuff that’s far tends to be really far. So you might be able to get away with rendering your scene as multiple layers each with a different scale.
For example, you could render the background galaxy/stars at a super reduced scale in one full screen viewport. The solar system at a less reduced scale in the next full screen viewport and then the local spaceship and nearby planet in the last viewport. Because the layers never overlap in distance, you can just have them clear the Z-buffer each time. This is sort of similar to rendering a sky that’s always in the background.
…not sure I explained that well but hopefully it makes sense.
Imo you should always “partition” your space or use relative coordinate systems as you suggested because really big vs really small values is always a drag. I think you will find no game out there that does it in a way where they really use absolute coordinates when its about scales like galaxy vs space ship. No matter if you use double or float precision, things like physics and other computations will always render slight to massively different results going to such extremes.
I get the idea of partitioning the galaxy into sectors, and i like the idea of using relative coordinates everywhere, i see the application of these things … but my concern is once i start flying around in a solar system, those relative coordiates of my space ship (and everything else as rendering takes place) gets converted to absolute coordinates by the lower level JME functions, and even OpenGL, right? And is the whole thing going to fall into a big heap?
I dont mean absolute coordinates to the whole galaxy
I mean inside a solar system…
If a space ship is 1 mile from a space station
and the space station is 100,000 miles from a planet
and the planet is 1 Astronomical Unit from its sun
And the sun is at the 0,0,0 position
Then when JME and OpenGL come to do whatever it does (hehe), wont the actual location of the spaceship become absolute to 0,0,0 to the rendering pipeline, and no longer be eactly 1 mile away from the space station? And in the values becoming absolute, this will destroy the precision i just had with relative coordinates…?
Or are you speaking in terms of even partitioning a solar system as well? Would this be the only way?
Thanks for your advice everyone, i appreciate it
Paul is not wrong here (when is he!? :P) but there might be a solution to use near real-scale values…
I just woke up and I sometimes have epiphanies like that which often times are crap in the end, so don’t take this too seriously.
Alright. One thing you could do is do things counter-intuitively. Instead of moving your ship forward going from X to Y, visiting Uncle Fred, have it the other way around. Have everyone visit you instead. Is that cryptic enough for you? Yeah, thought so. I haz so clevah.
What I mean here is that your ship has to be stationary and have everything else move toward you (if they’re in front of you, or away if behind, etc) but you ship has to remain at the origin of the scene.
Why is that good? Because as you move farther and farther from the origin, you will get to a point where that float distance will translate to being stationary because precision has disappeared entirely. So, as @pspeed suggested, even if the ship is stationary it “moves” at a certain speed, and when things get to a certain distance you can start scaling things to it real or real-enough values.
In my Solar System, into which I intended to use a similar system but I’m not for the moment, I’m starting to see weird behavior around 500 000 units. The object in the camera frustum shakes as you rotate around it. The farther away you go, the weirdest is it. I also have to say that my solar systems are at a scale of 1 to 1250. Scaling is only used to mitigate that effect, but it’s not always successful with systems with many planets (10+). By using a similar to the above, as you “move forward” you scale the closest object smaller by tiny increments and you’re also moving them away from you.
At a certain point, assuming you’d use a 1:1 ratio, “moving” to around 300 000 units (with the spatial scaling and moving away above) could be like being 10 times that distance while at the same time looking realist.
The next big hurdle after would be to properly represent the stars in that galaxy (if it’s the Milky Way, that would ease things by a large factor), from the point of view of the ship. I’d suggest to only draw objects based on luminosity. Passed a certain threshold, you simply discard them. For stars like type O, B and A are “few” compared to the rest. Stars of type M are mostly not drawn unless you get “very” close to them as they are pretty faint. You could also draw anything inside a certain distance if they’re visible enough.
Anyway. All this to say that, when an object gets to a certain closeness, then you start scaling it up.
Hopefully that makes some kind of sense.
That’s the theory anyway.
Yes, I agree with positioning everything relative to the ship when rendering… I still say use doubles for your data structures if you can.
You might even be able to get away without layering the scene as I suggested but really really really far objects might end up on top of each other or overlapping as they lose precision.
In Mythruna, the camera stays still and the world moves also. The geometry is always translates and drawn local to the camera from other data structures, ie: the stuff in tiles is always relative to the tile, etc. It lets me not worry about a lot of stuff.
Alright, i will now go forward with all these ideas in an attempt to get somewhere with this Thanks everyone for your contributions.
For what its worth, or for anyone that wants to do the same and is in the same confused state, I think i will still need to partition even a solar system, i cant see it working any other way… or kill my pride and scale the sun’s and planets down, and mess around with the speed of the player to make the player believe they’re in a massive world.
BTW keeping the player at 0,0,0 and having the world move around the player is actually the best answer to the question.
I recently read the opening summary of a thesis by someone called Chris Thorne on this very subject. Looks very interesting, but my mind isnt ready to tackle what i ‘think’ i would have to do to JME in order to make that work… not to mention how to make that multi player compatible… but again i might just be thinking about it wrong.
Thanks for your time
Also just wanted to post an idea i had today about this subject, and its probably not going to end up in my project, but it might find merit with someone else in their particular design.
If you need an environment that has the ability of continous flight through partitions without loading screens or you dont want some sort of pretend ‘jump’ mechanics to get a player to another partition. Have your space partitioned as already described, but for each partition (or sector), that partition has coordinates saved (or pointers to positon data) for all information contained within the partitions that are adjacent to a given partition.
This idea would purely be used for the sake of being able to render 2 players, both of which are close to the partition boundry and looking at eachother from different partitions, and they could also attack eachother other quite happily. If a missle, or a player crosses a partition boundry, that object then becomes owned by that other partition, but can still be seen from the old partition if needed.
Its a very hack way of doing it, and there would be many double ups of variables, however it would serve the purpose of keeping precision for small units, but also the ability to also extend out to large scale units. Your partition size would ultimately decide how nasty the misuse of memory would be though
I dont think this idea would be good for a MMOG. Too many players, and so too much of a misuse of memory as well.
hi i speedread this thread, and i didnt unsterstand 1 thing. Why do you think you need to store “coordinates of adjacent partitions” for “continous flight through partitions”. That is calculated data, you dont need to store them. You can easily convert coordinates of one coordinate system (partition) to another.
Or did i misunderstand something ?
Okay someone will have to correct me if im wrong about JME, but when we speak of partitioning or sectoring in the traditional sense we are logically cutting up a vast areas of ‘designed space’ into smaller managable sections (this can be for varied reasons, mine is the 32bit float variable).
And because of this the objects in adjacent partitions cannot be seen. They are in fact not known at all. So this in turn means the edge of a partition is literally like a wall, you cant move beyond it (without the programmer having developed a means), you also cant see through it to another partition, and you certainly cant just fly through it into the next one (again, without programmer designed means).
The idea (as memory hungry as it would be), would be a given partition stores location vectors of objects, and pointers to those objects that are in adjacent partitions. This would purely be for the purposes of rendering and interacting with what is in adjacent partitions from the current partition. An example is players shooting lasers at eachother across the boundry. Im not crash hot on maths at all, but this wouldn’t merely be a double up of location data, it would actually result in 6 fold increase in data given an environment of partitions in 3D space, or a 14 fold increase given diagonally adjacent partitions being taken into account as well. As i said, its going to be memory hungry!
Despite its flaws, the float issue wouldnt be a problem with this style of environment though. To give an example…
humanplayerX is in partition A, and is relative to his own partition (0,0,0) origin
humanplayerY is in partition B, and is relative to his own partition (0,0,0) origin as well.
PartitionA knows of playerY but the location vector information is relative to partitionA (not partitionB).
Likewise PartitionB knows about playerX and again has stored vector info for that player that is relative to partitionB.
You might say straight out, but isnt that just returning back to the problem with the float issue again? Hmmm depends if your a glass is half full or empty kinda person. Put it this way, to the players, no, they wouldnt ‘notice’ any jitter or incorrect values. But to the Partitions yes at some point they may end up having stored values that may become less friendly.
Hope that clears up any misunderstanding… its now clear in my mind how memory hungry it would be. So again, I need to say it would be only select cases you’d want to take this approach. Besides, it was just a random idea anyway…!
And because of this the objects in adjacent partitions cannot be seen
We have the assumption that a partition holds float from 0 until 64.
Goblin1 in :
Vector3f position ( 64, 64, 63 )
Goblin 2 in :
Vector3f position ( 0, 0, 0).
I can easily get the coordinates of goblin 1 to that of partition 2:
Vector3f position ( 0, 0 , -1)
1) Convert all creatures in adjacent partitions of the main actor into the same coordinate system.
Goblin 1 can see goblin 2 because they are in the same coordinate system now (after the transformation).
You wont have any inaccuracies because your floats containing the position information are small 0 until 64.
2) a naive person would be tempted to choose the world coordinates as his "coordinate rendering system" thus negating all his efforts. Because position( 99999999, 99999999, 99999999) wont be rendered correctly by jme.
What you do is translate all objects based on (0,0,0) position of jme.
Which means that the main actor is always in (0,0,0) in this system (normalised).
The enemy positions after being normalised will be from :
farthest south partision = (-64,-64,-64)
fearthest north partision =(128,128,128)
Anything outside of this, isnt rendered because as we said we render only adjacent partitions.
I don't see any reason why jme shouldn't do that automatically, it is jme's responsibility to reduce floating point errors.
I think that if the partition sizes are properly sized then you will be showing many at once and any partition you aren’t showing is because it is so far away that you wouldn’t see ships in there anyway.
I know it’s a different environment completely, but Mythruna world is chopped up in a 32x32 grid and objects are only drawn in the current and immediately surrounding grid tiles. Other players are drawn from further away, ie: farther adjacent grid tiles, and beyond a certain number of tiles out I don’t draw anything at all. And I don’t have to play with one tile knowing anything about the adjacent tile.
At some point, I intend to experiment with a similar layering scheme that I described before where even larger chunks of tiles from further out are drawn at a greatly reduced level of detail… potentially out to several kilometers. In this case, I could be drawing those at an entirely different scale since it’s an independent layer behind the normal scene. So I’m familiar with the concept. Setting up a view port behind the main scene is not difficult.
So if you really do run into a case where a player at 0,0,0 can see a ship far enough away that float is no longer accurate enough then you can always resort to a layering approach. But it may never come to that.
What you’ve both said, without spelling it out is I’ve been a little silly thinking i need to keep copies of all the adjacent partition data… and can still get the benifits without the memory cost. Yep i see it now hehe
Often when i come across an idea i run with it without thinking if there is a better way, or more effective solution. What you’ve both said is correct. Hmmm i have been humbled this day!
Which means that the main actor is always in (0,0,0) in this system (normalised).
The enemy positions after being normalised will be from :
farthest south partision = (-64,-64,-64)
fearthest north partision 128,128,128)
Tralala: I dont fully understand this part of your post, when you say 'main actor' are you speaking of the actual player, the partition or just a programming term to describe where the player currently is? And based on that, are you suggesting you normalize the enemy location vector, so the currently partition understand where the enemy is in relation to the player, right?
sorry for not making it more clear.
main Actor = cameraLocation
- you have the data of where each creature is located.
- at rendering step you keep only those adjacent to the main actor. We keep 5 partitions top,left,right,south,center.
- the “data space” is position of each creature in partitions, however data here is (x,y,z,partition), jme cant understand 4ples. You convert the “data space” into “rendering space”.
“Rendering space” will be a coordinate system where the camera is always at (0,0,0), and everything will be located based on that.
- You want to create a method that converts from local coordinates of an object into local coordinates of another object (cameraPosition in this case at (0,0,0)).
4ple ConvertToLocal( 4ple creaturePosition, 4ple cameraPosition )
Mainly the suggested design space finding process uses a ordered dividing method to help minimize the bane of dimensionality often associated with the research of large scale techniques.