1
votes

As part of my save/load game code, I need to save the state of all the Box2D bodies that are in the world. When I do this and then load and recreate them there is a quick pop were some of the bodies separate from each other. I've double and triple checked my save game information and it is correct.

For each body, I'm saving the world position, angle, AngularVelocity and LinearVelocity. Is there more I need to save?

I'm just wondering if it's not really possible to fully save the state of the Box2D world.

I am using the C++ Box2d code in iOS.

2
Are they all the same size and shape or something? ...otherwise I can't see how those 4 variables would be enough.iforce2d
I am saving the body shape as well, I was just mentioning the dynamic data.Roger Gilbrat
You might find this useful: iforce2d.net/b2djsoniforce2d
Thanks, I'll dig into that code see what they are doing that might be different from my code.Roger Gilbrat

2 Answers

1
votes

There is dump function of b2world. It put all the information about the world into log file. So you can see this log file and understand what do you have to save.

PS: Did not tried this function myself

1
votes

For each body, I'm saving the world position, angle, AngularVelocity and LinearVelocity. Is there more I need to save?

From a review of the Box2D 2.3.2 b2Body member variables (in b2Body.h), you may also want to save:

  • the ordering of the bodies (perhaps by saving them in the order they're accessed from b2World as b2World::Dump() does),
  • the linear and angular damping values (via b2Body::GetLinearDamping() and b2Body::GetAngularDamping()),
  • the gravity scale (via b2Body::GetGravityScale()),
  • the type (via b2Body::GetType()),
  • the is-bullet value (via b2Body::IsBullet()),
  • the is-sleeping-allowed value (via b2Body::IsSleepingAllowed()),
  • the is-awake value (via b2Body::IsAwake()),
  • the is-active value (via b2Body::IsActive()),
  • the is-fixed-rotation value (via b2Body::IsFixedRotation()),
  • the fixture-list and its order (via b2Body::GetFixtureList()),
  • the user-data (via b2Body::GetUserData()),
  • the force,
  • the torque, and
  • the sleep time.

Unfortunately, there is no readable public access to these last three state values.

If your world has joints, you may also want to save those but those I'd suggest saving from the world's perspective.

I'm just wondering if it's not really possible to fully save the state of the Box2D world.

That depends on what you're doing in your game and what you're willing to do code-wise.

If you're applying forces or torques and your world is not set to auto clear those forces then from a purely b2Body perspective: no. OTOH, if you're applying forces or torques, you could save those on your own in which case forces and torques could be savable: yes.

The sleep time, that'd be a question of how much that matters to you. If you want to be able to reload your game at a later time such that it'd resume exactly like it'd never been paused, then at least from a user-level perspective, you'd be stuck; the answer's no. OTOH yes, if you're willing to modify the Box2D library sources that is.

For example, you can add code to the b2Body.h file like the following that provides read access to the sleep time state:

class b2Body
{
public:
    ...

    /// Get the sleep time.
    float32 GetSleepTime() const;

    ...
};

...

inline float32 b2Body::GetSleepTime() const
{
    return m_sleepTime;
}

Of course, this wouldn't be complete without write access as well. While doable, that could be more difficult depending on whether you'd want to be able to restore the sleep time on construction of the body or if setting it after construction (via a setter) suffices (the latter being less code but the former perhaps being more semantically appealing). Anyways, let me know if you'd also like to see code for loading the value.