Sim-eth-es Troubleshootings

Finally fixed it. I’ve increased maxSubSteps to 8 in the physicsspace settings before but that didn’t help.
Now with update(t, 0); everything works as expected (okay well the character is moving with 9.75 instead of 10, but that’s my fault). GREAT!

I’m not sure why those two quotes are telling different things:

but that’s bullet :smiley:

Edit: Just tested it, it even works with update(t, 0) (so t being the variable time from SiO2, not 1/60f constant)!

1 Like

Sorry not mentioned it clearly enough.

The first quote was from an old doc was saying do not us maxSubSteps=0.
In the the second one author mentions it was and out-of-date doc and you are pretty much safe to use maxSubSteps=0 for fixed time step.
this is the link to ref Setting maxSubSteps = 0 - Real-Time Physics Simulation Forum

Edit:

Edit 2:
And a nice reading

More over I believe maxSubSteps=0 is very reasonable on server side because we do not need interpolation on server side. It is just a wasting ? SimEtheral can interpolate it smoothly in client side.
Paul much more thanks. I got to know great info today due to you. :slightly_smiling_face:

I am exactly using this way except that I do not call it server client.

for example for combat mechanics I have three modules :
combat: for server side
combat-common: for RMI api and components.
combat-view: for client side

maxSubSteps=0 means that if for some reason your update loop is slow then your physics will also slow down.

Also, using a variable tpf with maxSubSteps=0 is super dangerous as you might have a HUGE tpf and then all of your objects might teleport I guess.

From my reading of the code, if you have bullet configured for 1/60th of a second but call update(1f, 8) then it will internally run its update loop 8 times trying to get as close to that 1/60th of a second as it can.

Likewise, running update(1f, 0) would run the integration for all objects/contacts/etc. with t=1 second… which is probably not what you want… which is why variable tpf is bad here.

I mean, you can try it but I think if you are going to pass (t, 0) then t should probably be a fixed and reasonable size (1/60 if you want 60 hz updates).

re: the problem in case someone who knows bullet code better than me looks into this…
At first I thought the issue was that these make up frames were clearing the state and so the stuff we set in the control driver was getting cleared for the second makeup frame. But that didn’t appear to be the case for two reasons:

  1. tweaking the code to pass a t very close to the real tpf (like within a fraction) would cause different behavior than simply passing the exact tpf (and I don’t remember which one failed but either should have caused one frame to run).
  2. moving the control driver stuff to either the prephysics tick or post physics tick (which are run even on the makeup frames) didn’t fix the problem. (This is what makes me think that the issue was when tpf exactly aligned with real time passing.)

Anyway, the only downside of update(t, 0) is that physics will slow down if the real update rate slows down. For example if your game is really busy and so the update loop is only running at 30 hz then physics will look like it is running in half-time slow speed.

Personally, I’m ok with this for a couple reasons. 1) it’s likely physics that is killing the update rate anyway… so makeup frames may not fix anything, 2) I’d rather have physics run a little slow for a bit than have objects start warping through walls.

2 Likes

Sorry for the next stupid question but when I add a Ghost Component to an entity it disappears from the screen for some reason I was unable to debug yet. Everything else is the same., but I also don’t see any update packets moving it away or something and indeed the client is loading the Spatial and moving it in place. The only thing which could be the problem is that the ZoneNetworkSystem’s PhysicsObserver is skipping them, but that’s only relevant for physically moved objects anyway

My first thought was “A Ghost component should make an object invisible, no?” and then I remembered it can be linked to another object. So I’m not 100% sure what you mean and it’s probably worth seeing code.

The rigid body with the ghost child should be unaffected by having a ghost child. But the ghost is server-side only as there is no reason to have it on the client.

Well in my case it doesnt have a parental rigid body as I wanted to do item pickups by walking over the items so I have an objectType and a Ghost which is triggered upon Walking over it. I guess you would suggest two different entities for that then?

But why do you need a ghost if you already have the object? Just detect the contact and pick it up.

The object doesnt have a regular collision. I dont want the player to bounce over it or something

Everything you want to detect collision on, will have some physics to do just that. How you handle the collision/contact, is up to you - you can completely override the ‘normal’ physics collision if you want, and just detect the collision, check the object type/id, handle the ‘pickup’ and then ‘end’ the collision with no further consequences.

Most physics systems also have a ‘ghost’ feature , so they can detect collisions, but the objects do not interact in any way. If the object has physics before being a ‘ghost’, then you can maybe change the properties on that object so it becomes a physical ‘ghost’.

I think pick up item is a physical object and it has contact with terrain but it has a different mask than player so do no collide with player. then you attach a ghost object to it which listens to player contact and do the pickup.

That’s what I try to use with the Ghost Component but as said it removes the component which I can’t understand tbh because sure Ghost Objects aren’t synchronized with the client by sending the BodyPosition.class (unlike that happens for regular physics objects), but they are synchronized because they are a Model and Models are placed (especially when I supply a Position.class manually)

But I don’t want that either, just a simple “first aid kit” rotation around the y axis, maybe hovering, maybe even hovering sine-waved along the y axis.

If you have a Position and a ModelInfo and that’s what your view system is looking for then the ghost component should have no effect on that system.

If that’s not the case then you need to check each of those assumptions.

Well that’s the point, when I comment out the Ghost() statement, suddenly everything becomes visible, which makes no sense unless it would be removed from the Physics Container where it got displayed from earlier on.

Code was this btw:

ed.setComponents(result, ObjectTypes.pickupHealthType(ed), new SpawnPosition(position),
                new Position(position.x, position.y, position.z), ShapeInfos.boxInfo(ed), new Ghost(Ghost.COLLIDE_DYNAMIC));

What I’ve suspected, could it be that Ghost implicitly adds a BodyPosition and so it’s moved from the ModelContainer to the MobsContainer?

Edit: Yep, that’s it: Evidence from the Log:

ModelContainer.addObject(Entity[EntityId[4], values=[ObjectType[type=2], Position[location=Vec3[30.0, 4.0, -40.0], facing=Quatd[0.0, 0.0, 0.0, 1.0]]]])
00:06:02,513 INFO  [MessageDebugger] Received:StringIdMessage[id=null, string=pickupHealth]
ModelContainer.updateObject(Entity[EntityId[4], values=[ObjectType[type=2], Position[location=Vec3[30.0, 4.0, -40.0], facing=Quatd[0.0, 0.0, 0.0, 1.0]]]])
MobContainer.addObject(Entity[EntityId[4], values=[ObjectType[type=2], BodyPosition[null]]])

Obviously I’ve truncated the log and there are many MobContainer.add’s with BodyPosition null, but those probably get published by the systems in place usually but not for ghosts. Not sure if I should go with 2 entities or ensure that a ghost entity is updated like regular physics systems

Edit: According to the BodyPositionPublisher.java, the ghost object should be getting a proper BodyPosition, just like a Mob.
Further Investigation shows that in Mob#updateSpatial the PositionTransistion is null due to an empty buffer, but BodyPositionPublisher is adding Frames to the BodyPosition, so I don’t get why that happens, furthermore making the ZoneNetworkSystem update the entity doesn’t work either, so essentially: How can I keep supplying BodyPositions? [In my use-case they won’t change anyway so the network would prevent them from being transmitted]

Ghosts can move so they have positions like anything else… but if you want to not publish them then don’t publish them.

Basically, if it’s an:
SiO2/EntityGhostObject.java at master · Simsilica/SiO2 · GitHub

then ignore it in your publishers?

Or am I missing something?

Yeah, my problem is that they are published in a way that a BodyPosition Object is created on the client but the buffer is always empty and hence the spatial’s position is never set or updated and I can’t get that buffer to be filled

No… BodyPosition is created on the server and then gets sent to the client. So don’t create a BodyPosition for ghosts. That’s code you control.

So I shouldn’t try to “fill” the buffer instead? Like it would be true for every moving physics object? (On the other hand that’s where the parent field is for)