-
-
Notifications
You must be signed in to change notification settings - Fork 18.9k
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
Add PhysicsServer2/3D::space_step()
to step physics simulation manually
#76462
base: master
Are you sure you want to change the base?
Add PhysicsServer2/3D::space_step()
to step physics simulation manually
#76462
Conversation
PhysicsSrver2/3D::space_step()
to step physics simulation manually
b769061
to
2419c05
Compare
void GodotPhysicsServer3D::space_flush_queries(RID p_space) { | ||
// TODO:: | ||
// Like _update_shapes(), to provide controllability for developers, flushing_queries flag should active as a member of space and check it for each space. | ||
// But I'm not sure about that, I am not familiar with multi-threads and the architecture of GodotPhysics. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The second point which confuse me.
// TODO:: | ||
// May be let pending_shape_update_list as a member of GodotSpaces3D and update shapes by themselves. | ||
// To avoid effecting Spces which are handled by developer (for lockstep/rollback netcode, it is particularly sensitive). | ||
// If it is unecessary, call _update_shapes() directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first point which confuse me.
2419c05
to
48553ed
Compare
ffbacd8
to
e6573c3
Compare
Hello @Daylily-Zeleen, Saw your PR when making mine ; yours has more general usage but might need some tweaks. |
In my opinion, the PhysicsSpace which be stepped by Instead of call I need people, who familiar with godot physics and server design, to instruct me. |
PhysicsSrver2/3D::space_step()
to step physics simulation manuallyPhysicsServer2/3D::space_step()
to step physics simulation manually
When will this feature be merged? I need this functionality to assist me in implementing my network synchronization. |
@Az-qianchen it hasn't been reviewed yet, so there's no real timeframe for this being merged at the moment, the questions of the OP about some details would need to be resolved as well by someone experienced with the physics If you can test it and give your results and comments it would help the process |
2023-09-13.180402.mp4I am not sure if the way I use is correct, but when I simulation is positive, I can get the correct result. When the value is negative, the result seems to have an error. |
e6573c3
to
c9af63e
Compare
How to step a physics space is not this pr's work. I guess your purpose of passing a negative time to The right way to implement rollback feature is store your physics objects' state, and just restore them when you want to roll back. |
I encountered some obstacles when creating a physical space. Do I need to copy all PhysicsBody3D objects to the new physical space, and all objects must be StaticBody3D to perform space_step() on a single object and obtain the correct collision? |
If your physics object are created as a node (
There has not limit the type of physics objet. I uploaded a testing project for reference.
|
I may not be very clear. In fact, I hope to make a Step Physics Simulation in a certain object in the scene, but in order to get the correct interaction collision, I seem to need to copy a static scene in the simulation space. Or turn PhysicsBody into staticbody in the original scene to prevent being simulated together The following is the code that I tried to transfer the copy to the new physical space, but I still did not think about how to deal with the problem of retaining PhysicsBody and avoiding being simulated together.
|
@Az-qianchen Sorry, I don't think I can help you solve this specific application scenarios. After reading your code, I found that you set the |
This is mostly pending on a review by the @godotengine/physics team to assess whether this change is good conceptually, and will work well with the various physics backends (GodotPhysics, Jolt, Rapier, etc.). And we're in feature freeze for Godot 4.2 so at the earliest this would be merged for 4.3. |
I'm in the same boat. Currently I am sticking with the MR's source branch built locally. |
This comment was marked as off-topic.
This comment was marked as off-topic.
Please don't bump without contributing significant new information. Use the 👍 reaction button on the first post instead. |
I think there have not something can be called "side effects" if you use default space. |
c90de98
to
70d29a0
Compare
70d29a0
to
7c8abda
Compare
Is there anything that's holding this from being merged? I'm really looking forward for using this!! |
It has to be reviewed before it can be merged 🙂 |
Cool.... when is it getting reviewed? |
Tested on Linux/X11 on the latest 4.3 build, works as expected. |
When someone has the time to do so, please be patient, this is a major feature and it's the holidays 🙂 |
Here a C# demo of how I implement rollback/replay for my Rollback Netcode. Stepping API seems to work fine! 👍 In this demo the steps to set back the state are hardcoded to 10. In the real code this is determined dynamically from the incoming messages per iteration. This here is just for demonstration and debugging. Any objections? False positive? public partial class Demo : RigidBody2D {
private const int Steps = 10;
private readonly Queue<SimulationState> _history = new Queue<SimulationState>(Steps);
private Rid _space2d;
public override void _EnterTree() {
_space2d = GetViewport().FindWorld2D().Space;
PhysicsServer2D.SpaceSetActive(_space2d, false);
}
public override void _PhysicsProcess(double delta) {
// For debugging only advance physics when button is pressed
if (!Input.IsKeyPressed(Key.U)) {
return;
}
// Add entry to history (physics state is that from previous iteration, but delta is the current one.
// We do this here, for having everything together what is needed in an replay iteration
Transform2D transform = PhysicsServer2D.BodyGetState(
GetRid(),
PhysicsServer2D.BodyState.Transform)
.AsTransform2D();
Vector2 linearVelocity = PhysicsServer2D.BodyGetState(
GetRid(),
PhysicsServer2D.BodyState.LinearVelocity).AsVector2();
_history.Enqueue(new SimulationState(delta, transform, linearVelocity));
if (_history.Count > Steps) {
_history.Dequeue();
}
// Rollback
if (_history.Count > 0) {
var simulationState = _history.Peek();
PhysicsServer2D.BodySetState(
GetRid(),
PhysicsServer2D.BodyState.Transform,
simulationState.Transform2D);
PhysicsServer2D.BodySetState(
GetRid(),
PhysicsServer2D.BodyState.LinearVelocity,
simulationState.LinearVelocity);
}
// Replay
foreach (SimulationState state in _history) {
ApplyCentralForce(Vector2.Up * 200f); // Same action in every iteration
PhysicsServer2D.SpaceFlushQueries(_space2d);
PhysicsServer2D.SpaceStep(_space2d, (float)state.DeltaToNextIteration);
}
}
}
internal class SimulationState(double deltaToNextIteration, Transform2D transform2D, Vector2 linearVelocity) {
public readonly double DeltaToNextIteration = deltaToNextIteration;
public readonly Transform2D Transform2D = transform2D;
public readonly Vector2 LinearVelocity = linearVelocity;
} |
This comment was marked as off-topic.
This comment was marked as off-topic.
My review is that this PR has worked perfectly in everything I've done with it in my own networked game. If we're willing to merge a slightly-wonky PR then this one is probably ok as-in, however there remain a couple of small potential issues that I'm aware of:
|
Area signals seem to work. See attached demonstration. |
@Clonkex do you mean this comment? Because that is still very much an issue with this implementation. I mean, the implementation itself does what it should do, but it's not enough for resimulation unless we find a way to save/load the state of the physics engine (and nodes such as Area2D which also keep internal state) |
Another thing that is missing is a good way to instantly generate collision state. AFAICT, if I manually set the transform of a body (e.g. from an authoritative server) the state of Area3D is inaccurate until I run |
I just realized that my rollback netcode scenario also suffers from a lack of possibility to reset the internal state: I may register impulses/forces in the game mechanics for one tick and after some Milliseconds, when I normally want to On an unrelated note: There are still too many TODOs in the merge request's code. |
Yes, that's the one! |
Emit signals /events are implemented in To provide a way to resimulate |
Here is a C# version of the GD script using I have high hopes now that it's working in my networked project even though my netcode needs touching up. EDIT: |
Assuming these methods would get/set both the internal state of the Node and the related object in the physics server, this would be a good way of handling the matter. It wouldn't be complete without adding the corresponding |
Don't want to beat a dead horse here, but I strongly recommend that you read this comment if you haven't. I'm not sure about your specific netcode implementation, but if you're doing rollback, you're most likely going to have those issues with this PR. The comment mentions signals, but even if you're not using them, polling for overlapping areas/bodies will still fail to resimulate in certain scenarios. Other things like Once again, this is not to say that this PR isn't useful, or that it shouldn't be merged. Quite the contrary. It's just not sufficient for "full" rollback (i.e. being able to go back to a previous state and reproducing the exact same results in every scenario) |
huh... |
Well, if your game is 2D, you can use You can check it out here if you're interested. The README does a good job of explaining how it works, what it can do and what it can't. |
Unfortunately my project is 3D. Looks like CharacterBody3D does not interface with I hope this thread has an answer or else I'm going to write some C++ haha. |
Implement #1373
In #2821, it seems like the topic is quite big, but I think this pr can solve it.
Here is a simple demonstrate video of rollbackable/recordable physics simulation create by this pr:
rollbackable_simulation.mp4
But this pr is not perfect, there has two points which confuse me (I'm not familiar with multi-threads and GodotPhysics), and I mark them at below.
Here is rollback demo:
physics_rollback_test.zip