# When connecting a physics engine to another engine, should you do all your logic in the units used by the physics side or the rendering side

I'm currently intergrating pygame and pyBox2D, and am wondering which side is best to try to keep to in terms of game units of size.

Box2D is Meters

PyGame is Pixels

At the moment I am thinking I will keep everything on the box2D side where it makes sense, and then just use a scaling method to turn those numbers into pixel locations. But sometimes I will want to detect something in pixels (mouse location) and have this relate back to the location in the Meters side. Obviously I can use the reverse scaling to get that point, but I was wondering if there are any tips about this?

In order to make the scale easier, I have aligned the box2d world horizonal 0+ and vertical 0+ to match the location of pygame, which takes top left as 0,0 . First attempt I was doing something crazy with 0,0 being in the middle of my pygame world. Seems no reason not to calibrate the Box2D world to match the pygame rendering one to some degree.

Any thoughts or tips?

Like Tetrad said, it's a really good idea to constrain all of your conversions to a single place on your code. This will ensure consistency across the game.

I'm not familiar with Python, but in C# I'd create a small helper class to help me with this. For instance:

public static class UnitsConverter
{
public static float M2P(float meters) { return meters * _scale ; }
public static float P2M(float pixels) { return pixels / _scale ; }
public static void SetScale(float scale) { Scale = _scale ; }
private static float _scale = 100f;
}


And then use it everywhere:

UnitsConverter.SetScale(1000f);
float screenX = UnitsConverter.M2P(entity.X);
entity.X = UnitsConverter.P2M(mouse.X);


And I'd like to reinforce again (in case it passes unnoticed in the comments) that you should never ignore Box2D's scale definition and treat pixels as meters. The documentation clearly says:

Box2D is tuned for MKS units. Keep the size of moving objects roughly between 0.1 and 10 meters. You'll need to use some scaling system when you render your environment and actors. The Box2D testbed does this by using an OpenGL viewport transform. DO NOT USE PIXELS.

And as someone who's made this mistake before (and it took me a long time to figure out what the problem was) I can tell you that the problems it creates start showing up the most obscure ways.

If I remember correctly, everything moved sluggishly no matter how much force I applied, and collisions didn't look natural either. Changing to a more reasonable scale solved the problems completely.

• Thanks, this was basically what I was doing, but it's nice to have it so clearly re-enforced. Where I think I was going wrong was trying to use the default 0,0 position of box2d in the middle of my pygame window. Madness! Why not just simulate so that 0,0 is the edge of my window, just like the pixel part. Jan 3, 2012 at 13:30
• Yeah, you were forcing a translation to correct that offset on top of the already required scaling. Jan 3, 2012 at 13:35

The only tip I have is to make the conversion in one place and only one place. If you start having to do inline conversions all over the place from one coordinate system to another you're going to run into a whole host of problems.

My opinion is to use the Box2D units over the pixel of none of the two.

You Have to use a non pixel based units because of the engine implementation issues and "have" to use the pixel unit because of rendering issues: neither of them (may) constitutes the reality of that you intend to represent.

So the answer: use the box2D unit system as "user" system if it make sense for you; you will store this kind of values in your entities, your graphics facilities knows this and will convert in pixel when necessary.

If the box2D units do not make sense then use a metric that does. Again, store that values everywhere is necessary: your graphic engine knows and does its conversion - your phisic engine knows and does its conversions.

Edit:

Graphical user input processing (clicks & touches) has to be done in the graphics subsystem and should return the position in a consistent way i.e. the unit system you choose.

Until a satisfactory explanation for the systems odd behaviour has been found I will simply advice against using Box2D.

• Don't do this! From the documentation: Box2D is tuned for MKS units. Keep the size of moving objects roughly between 0.1 and 10 meters. You'll need to use some scaling system when you render your environment and actors. The Box2D testbed does this by using an OpenGL viewport transform. DO NOT USE PIXELS. I did not notice this warning the first time I used Box2D and the entire simulation simply did not work correctly. Imagine the force it would take to move a tank the size of a football field... :-) Dec 31, 2011 at 12:47
• Can someone explain this? I can't think of any reason beyond extremely poor design for this behaviour. Even if there is a good reason it should be simple to have a way of letting the programmer change the scale. Jan 1, 2012 at 19:25
• @eBusiness - There is a simple way of changing the scale - just apply the appropriate conversions in your code. The thing is that while many people may use pixels as their unit of their choice, it may be points, or maybe they really want metres. It also makes it easier to write for the programmer that made the library.
– DMan
Jan 1, 2012 at 22:25
• @DMan The point of writing a library is that you perform a hard and/or tedious task in a way that makes your work easily reusable by others. The author of Box2D has saved some work himself, but made every user of the library do more work, that is very unlibraryish. Jan 2, 2012 at 12:08
• @eBusiness - Said author has indeed made it easier. The work is easily reusable by others because it is using standard units.
– DMan
Jan 2, 2012 at 16:53