Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

World origin shifting for large open world games #6737

Closed
HeadClot opened this issue Oct 7, 2016 · 11 comments
Closed

World origin shifting for large open world games #6737

HeadClot opened this issue Oct 7, 2016 · 11 comments

Comments

@HeadClot
Copy link

HeadClot commented Oct 7, 2016

Hey Godot Developers,

I have a bit of a feature request for Godot engine. Currently I am working on a large scale multiplayer space sim with the Godot engine. I wont go into much detail about my game other than say it covers a very large area.

That said - I need the ability to shift the world origin on the X, Y and Z axis as needed. Currently as it stands Unreal Engine 4 is the only engine that can do this out of the box. This feature would also need to work with the new High level networking API.

Would it be possible to implement this feature? I want to make something that is amazing with Godot but I just need some help with some core features of the engine.

Thank you for your time,
HeadClot

@Zylann
Copy link
Contributor

Zylann commented Oct 8, 2016

Is this required because floats are not precise enough when walking far away from the origin?
Would compiling Godot with typedef real double; instead of float improve this?

Also, I wonder how Unreal would do this without confusing all things in the world that depend on absolute positions (physics, AI, interpolations...). Also, how to make it fast? Without common parent, this will shift every single thing in the world, it can be expensive. If you have a World Spatial node at the root of everything, you could probably move just this one, and all children would follow? Also, adding hysteresis so the player won't be able to spam world-shifting just because of walking on and off the boundary.

@Zylann
Copy link
Contributor

Zylann commented Oct 8, 2016

I think what is shown in the video could actually work without world-shifting. Did you tried to do it?

If however you plan to do something like Star Citizen's interplanetary trips, you would have to rely on some tricks that are beyond world shifting, such as epic advanced level-of-detail. Also the nice thing about space is that it's empty, so you could do all shifting you want by hand in between, so Godot just has to be precise enough for the size of one planet. But it depends again how large you plan.

@Griefchief
Copy link
Contributor

Griefchief commented Oct 8, 2016

I am not 100% sure what exatcly Unreal's floating point origin thing does, but... I am inclined to believe it might not do what you think it does...

You don't need "engine support" to achieve this in Godot. Kerbal folks didn't need it in Unity... Depending on bugs you encounter (you won't on a 2x2km/units scale), you might not even want to roll your own version of floating point operations like Kerbal folks did.

Have fun watching this in order to learn what you would need to roll with in order to create a kerbal space program like game (position everything relative to the player):

https://www.youtube.com/watch?v=mXTxQko-JH0

You won't need to do all this in the video, based on what you described. Standard game development practices would suffice most probably.

Implementing what you want into the engine would probably require the same kind of recomputation that Kerbal folks do and would clog the speed for more typical use (unless it was a compile time switch).

Not only that, but, while 64 bit floats (in transforms, i suppose) are not officially supported... there is a way to compile 64 bit floats in Godot (rather manually, replacing all floats with doubles with a sed substitute command (or any string substitution program)... but devs seem to have done it before, they didn't say it doesn't work. So... with a bit of luck, 64bit floats will be officially supported soon... we'll see.

@reduz
Copy link
Member

reduz commented Oct 8, 2016

you can make the world in sections, and shift the sections every once in a
while when you walk around. It should work..

On Sat, Oct 8, 2016 at 4:16 PM, Griefchief notifications@github.com wrote:

I am not 100% sure what exatcly Unreal's floating point origin thing does,
but... I am inclined to believe it might not do what you think it does...

You don't need "engine support" to achieve this in Godot. Kerbal folks
didn't need it in Unity... Depending on bugs you encounter (you won't on a
2x2km/units scale), you might not even to roll your own version of floating
point operations like Kerbal folks did.

Have fun watching this in order to learn what you would need to roll with
in order to create a kerbal space program like game (position everything
relative to the player):

https://www.youtube.com/watch?v=mXTxQko-JH0

You won't need to do all this in the video, based on what you described.
Standard game development practices would suffice most probably.

Implementing what you want into the engine would probably require the same
kind of recomputation that Kerbal folks do and would clog the speed for
more typical use (unless it was a compile time switch).

Not only that, but, while 64 bit floats (in transforms, i suppose) are not
officially supported... there is a way to compile 64 bit floats in Godot
(rather manually, replacing all floats with doubles with a sed substitute
command (or any string substitution program)... but devs seem to have done
it before, they didn't say it doesn't work. So... with a bit of luck, 64bit
floats will be officially supported soon... we'll see.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
#6737 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AF-Z2-akPIfeZZtA9dJhKkAhbFXZZgRiks5qx-whgaJpZM4KQtOf
.

@HeadClot
Copy link
Author

HeadClot commented Oct 11, 2016

So - I misunderstood how the world origin shifting works. @Griefchief was right. Apparently it moves the origin and just the origin. It does not shift the level or anything like I previously thought. I have updated the issue to reflect this.

As for editor performance - If there was a tick box that we can tick if we wanted to enable or disable this feature. Would that work?

That said - I am not a C++ Programmer. Hence why I am asking for help.

@Griefchief
Copy link
Contributor

Griefchief commented Oct 11, 2016

You mentioned you updated the issue, but I can't recognize any new questions in it, so please repeat the question here in your next post if you have one...

"As for editor performance - If there was a tick box that we can tick if we wanted to enable or disable this feature. Would that work? "

What exatcly, Kerbal Space Program style recomputation? No.

UE4 like "world origin point"? Again no, if it's in the engine binary, then it's affecting performance of the engine. But that might not even be relevant, that "hard" on the performance, cause it seems that the World Origin does indeed "move" the world origin (read this as, probbaly moves every item in the game to a new location, cause if it didn't do this, it woudn't solve FP issues as far as i understand it...). So, probably, world origin exchanges the computation expense of calculating world origin every frame (taking it into account), and probably just moves every object in the world once (at the time of the origin change) and moves on as if everything's fine.

All of this said, I still don't see the point of this in the engine. The world origin thing is a strap on (I guess for new users, helper thing), it doesn't solve the actuall FP problem, it just solves jitter close to camera (the far away world still jitters, you just don't see it). Why a strap on? Cause it doesn't fix the big velocities issue like The Kracken bug KSP had (watch the video if you have not already).

Because of the Kraken bug, velocities and accelerations namely (they are subject to floating point issues as well), your origin shifting idea isn't going to work... on a galactic scale. The moment your ship goes to lightspeed. You're going to be in big trouble... Heisenberg levels of trouble. Quantum Kraken uncertainty in your hyperdrive :)

Anyway.

You could immitate what this world origin point does with a few lines of code in GDSCript.

Get a world going with xxx objects in it. Create a new empty Spatial and attach it to the scene tree, to the root node. Atach every child(object) of the root node to the Spatial node you created.

Move the spatial node XYZ in a direction. Reatach every child of the Spatial node back to the world node. Everything recalculated, and you didn't need to do any math :)

Or you could just do all this with Math, it's not a biggie. Just save the location of the spatial somewhere, so that you know where your "real world origin" is.

There you go, "Origin point support". If it causes a slowdown/stutter when you actually move the whole world via GDSCript (either via reparenting or via calculation, i guess you could always move it into C++).

There is no need for support of this in the Networking code, cause the networking example doesn't actually "automatically" position your items in the world. All the high level networking code does is call a function on the client and give it data (server(master) calls code on a client(slave), RPC style, remote procedure call, imagine it like a http update request of the browser to the server to update something, not to send a page back).

What you do in that function and what you send to it via function is not the concern of the high level networking code in Godot, all it is concerned about is actually sending the data to the client.

And this is actually great design (thanks reduz, thanks dev team!). Cause i took a fps singleplayer demo from Calinou, took the bomberman multiplayer demo scripts related to multiplayer, changes 3 lines in the bomberman scripts so that it updates positions of items from 2d to 3d, and wrote a grant total of 10 lines of "networking code", 2 functions that look like this.

remote func set_player_position(g_transform):
    self.set_global_transform(g_transform)
    pass

sync func set_player_rotation(yaw, pitch):
    get_node("Yaw").set_rotation(Vector3(0, deg2rad(yaw), 0))
    get_node("Yaw/Camera").set_rotation(Vector3(deg2rad(pitch), 0, 0))
    pass

And I have a multiplayer demo where black boxes with assault riffles run around...

Anyway, this is getting to long. :)

The point is, stop worrying the World Origin point, cause you probably don't need it. You probably don't need it for your project, the way you explained it, and even if you did, we (probably) woudn't put it in (this is subject to research of course, but I think it's probably just a new people helper, whish is cool, i guess), we'd either help you compile a 64bit float transform version of godot, or we'd make the support official. And fix the actuall problem... not the world origin thing (that only solves jitter if i understand how it works). Which is OK i guess, solves jitter, but it's probably simpler, better and more correct to officially support 64 bit floats.

So, basically, If you like Godot enough to work in it, and your game, go right ahead. You're optimizing prematurely :)

You don't need it (from what you explained), the origin point thing can be immitated in 10 minutes in GDScript without mucking up the engine, and the actuall fix is 64 bit floats, not origin point. But you won't need the fix. Cause what you explained is most probably easily doable in the current official builds of godot.

Have fun. :)

If i ended up sounding rude, sorry, didn't mean to, just trying to help. :) Read the post twice but I'm just gonna press "send" and hope i didn't sound rude. :) I didn't mean to.

Have fun, and if you happen to have additional questions, go right ahead. That said, from my perspective, based on what you're shared so far, which sounds like enough info, this is premature optimization.

@HeadClot
Copy link
Author

HeadClot commented Nov 3, 2016

Hey I have been out of town the past while and just got back.

@reduz - Is there any way we can call or set this up via visual script? The team I am working with has a bunch of artists and no in-house programmers. We are making our world in sections so we should be good there.

Hey @Griefchief -
Nah you did not sound rude at all. It is not really pre-mature optimization than we are running into floating point issues and we want to get these hammered out to continue work on our project.

Any advice would be appreciated.

@Griefchief
Copy link
Contributor

Griefchief commented Nov 4, 2016

"Is there any way we can call or set this up via visual script? The team I am working with has a bunch of artists and no in-house programmers. We are making our world in sections so we should be good there."

Yes, obviously. Make The world parts a node and move all the (world nodes) nodes around when it's time to move them.

"Any advice would be appreciated."

Everything you need to know has been said (and been linked to) above. Start with making everything either relative to the player or to that world part menitoned above by reduz (making it relative to the world part makes the price of switching happen once every x seconds or units instead of on every frame).

If you still happen to need doubles, try to have fun compiling a "double" (instead of floats) version of godot, also explained above.

Artists/rookie devs shoudn't care about the world/node switching code (visual script) (other then maybe putting a part of the world into the correct "world parts" holder node... maybe not even that. If people that don't understand how it works need to mess with it, you failed to code it right. Almost of all of this is doable from GDSCript, othen then compiling godot with all floats replaced to doubles...

@Griefchief
Copy link
Contributor

Ah, right, one thing i forgot to mention is that the current Visual Scripts will break once 3.0 goes out because a more advanced version of visual scripting has already been made or is being made.

I'm not sure if the latest scripting (that will not break too much) is in current master or not, somebody else needs to advise on that.

@aaronfranke
Copy link
Member

For anyone who comes across this issue (it's the number 1 result in the Google search results for "open world shifting origin"):

Godot now has a compile-time option float=64 which allows you to compile the engine with double-precision floats. As of writing this feature is still experimental but it is mostly working. See godotengine/godot-proposals#892 for further discussion.

@tavurth
Copy link
Contributor

tavurth commented Sep 30, 2024

Godot now has a compile-time option float=64 which allows you to compile the engine with double-precision floats.

Range: The maximum value a float64 can represent is about 1.8 × 10^308, and the minimum positive value is about 2.2 × 10^-308.

Comparison to float32: Float64 provides significantly more range and precision compared to float32 (single precision). With float32, you might start seeing issues at around 1,000-10,000 units from the origin.

While float64 can take you quite far (the exact limit depends on the precision requirements of the specific application).

For truly massive open worlds or simulations, you may still need to implement origin rebasing techniques to maintain precision over larger distances.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants