Game Development Community

dev|Pro Game Development Curriculum

2D Tuesdays: Box2D Dev Discussion

by Michael Perry · 06/12/2012 (9:57 am) · 18 comments

2D Tuesdays: Box2D Developer Updates


Greetings everyone. It's 2D Tuesday! Each week someone on the 2D team will post a blog or resource related to Torque 2D and/or iTorque 2D. The majority of the posts will come from myself, but don't be shocked if someone else takes over for me from time to time.

Last week, I started with the plan of attack for integrating Box2D in an R&D branch of our repository. This week, I'd like to continue talking about the implementation. Ripping out the physics system and replacing it is no small task. Many parts of the engine have to change for a proper implementation, even some modules that have nothing to do with physics. I touched on this in a forum post, but I promised I would go into greater detail in one of these 2D Tuesday blogs. Before continuing, here is the usual disclaimer.


Do not take the content from these blogs as law. I'm never going to say "this will be in x.x version" or "this is ready to be used right now". There's going to be a lot of R&D discussion. I might even post a discussion I had with Melv that ended up being scrapped. It might be useful for you to understand how we communicate internally, or amusing to see the mad scientists we really are. I will not post timelines. I will not post release dates. I will not commit the team to something we cannot deliver on.

The First Exchange

The following is an e-mail from Melv based on his investigation of the current 2D technology and what will immediately be impacted:

Here's a quick summary of the points we discussed:

  • Dynamic resizing of collision-shapes/joint-anchors will not happen at runtime implicitly. This is because the overhead of doing so is extremely high and dictates a whole bunch of support code that we need to remove. This will be for tooling only but can be exposed as a method that will perform the appropriate actions. At least this way, the massive overhead only happens when an explicit action is taken and the API does not push the user towards bad practices.
  • There is a real issue in that supporting n-objects whether they be collision-shapes or joints is difficult to expose using the TorqueScript binding system. This is because we do not wish to have the overhead of having each object (whether a collision-shape or joint type) be a SimObject. Unfortunately, TorqueScript requires this. At best, we will have a bunch of functions exposed from t2dSceneObject that deal with creating/destroying/enumerating/configuring all the types. This leads to a messy configuration. For an example of this, look at how the circle/polygon collision-shapes are configured in TGB. There are methods that are mutually exclusive in operation and are only valid according to the collision-mode. Expanding this to support several collision-shapes / joints would be extremely messy.
  • The TileMap is impacted by the changes in a big way so it is being removed from the build temporarily. I will resurrect it later but for now, it cannot delay the Box2D integration. I would like this to be a separate task later.
  • Reusing old assets can be done but it cannot be guaranteed to be a lossless operation. For instance, mount-points, auto-mount-rotation and many other things will not work as they have no analogy in the new system. I would like to work on resurrecting old assets and looking at the conversion processes required as a separate task later.
  • Pathing will cause simulation problems because it warps objects from position to position therefore causing overlaps and tunneling issues.
  • Trigger will need converting to use the Box2D sensor collision shapes.
  • Particles should be mainly unaffected (ignoring the asset resurrection issues)

Serialization and Versions

To be clear here, the serialization/versioning system I wrote allows you to support multiple versions but in the fact of the huge changes we're making, we cannot guarantee that loading the binary data will result in a perfect representation of the original object because certain features are not available. Also, when we deserialize stuff we currently load them into systems like "t2dPhysics" which will be removed. We cannot have the situation where we have to keep a whole bunch of code just so we can deserialize. In this case, we will create a structure that will load the data but perform no operations on it. Then the deserialize (load) method will be written to see what it can do with the data.
Post Box2D integration, all versions have been marked as version #16 and all previous versions for saving will be removed meaning you can load <#16 version but not save it at <#16. This work will be a separate body of work.

Hopefully that last section drives home the point I was making about how a Box2D implementation affects more than just physics. Serialization is just one area. If you have ever browsed the source code to see how objects are serialized/deserialized, you will see where t2dPhysics gets used. Obviously, that has to go. That begs the question "What else changes?"

Sweeping Changes

The following information was pulled directly from our internal wiki. This is a quick reference for our developers to look at to see what code they need to change when porting a project:

  • All world units are now physical units i.e. the meter.
  • Objects to "real world" equivalents, not pixels
  • Y axis has been inverted. +Y is now "UP", -Y is "DOWN".
  • "Rotation" is now referred to as "Angle".
  • Positive angle gives anti-clockwise rotation whereas negative angle gives clockwise rotation.
  • t2dVector now uses fields of "x" and "y" rather than "mX" and "mY".
  • t2dSceneGraph has been renamed to be t2dScene.
  • The old "setGraphGroup" & "getGraphGroup" calls are replaced by "setSceneGroup" and "getSceneGroup".
  • The old "setLayer" & "getLayer" calls are replaced by "setSceneLayer" and "getSceneLayer".
  • Nearly all of the collision control methods and fields have been removed, only a few remain so it's much easier to use.
  • The collision callback occurs on the "t2dScene" namespace now, not the "t2dSceneObject".
  • The "mounting" feature has been removed. This is completely subsumed by the use of "Joints"
  • The joint API exists on the "t2dScene" namespace, not the "t2dSceneObject" one.
  • A lot of API documentation exists inside the C++ code.
  • The C++ now separates "ConsoleMethod" for types into their own header files i.e. "t2dSceneObject_ScriptBinding.h"
  • The TorqueScript method names are identical to the C++ method names.
  • There is now an extremely detailed Debug-Drawing and metrics display available.
  • I have tried to maintain compatibility for all binary-save files. It should be able to load older files and convert that data into the new format appropriately.

Some of those are going to make for good porting instructions, while others are almost completely unrelated to physics. For example, moving ConsoleMethods to their own _ScriptBinding.h has dramatically reduced the bloat of individual source files. used to be 11,037 lines. Now it is 4,745.

For something simpler, like t2dSceneGraph being changed to t2dScene, think of how well that flows with what is usually associated to it. A t2dSceneWindow will contain a t2dScene, which holds t2dSceneObjects. Small change with great results.

Time and Effort

So how long does a proper implementation take? We wouldn't be the first to implement Box2D into our 2D technology. Heck, Melv did so in another R&D branch in the past. Unfortunately, we had to start over for this implementation. In the span of about 25 days, this is how far we got:

Quote:So the status this morning is good news. I've managed to get most of the integration work done. Obviously I've left out the tile-map stuff as I said I would but I've managed to bring everything else together and get it compiling. Now that I can execute the TGBGame, I set-up a test-bed to test my work so far. I'm kind of patting myself of the back here (sorry about that) but god damn if it didn't just work first time with no bugs! By this I mean the scene initialized Box2D and appears to be going correctly through its ticking/interpolation cycle.

This afternoon I'm now working on the picking side of things that will allow a pick for render as well as its usual utility from the scripts. With that in place we should have a potential visible set for rendering and I can then check the rendering of sprites, scrollers etc. I think if I can get that working then I might just put together a quick video showing it working.

Beyond that I need to add in the contact processing that allows functionality like contact-callbacks i.e. OnBeginContact & OnEndContact. This may be where the t2dTrigger becomes redundant as it provides no more utility that you get in the t2dSceneObject: we shall see on that one.

There's a whole extra bunch of functionality we can add here but I'm keen to keep things simple for now and I'm really being cautious and not exposing contacts directly to the scripts but rather collate them then emit them if the scene-object is asking for them as TS sucks and is slow.

Back to the picking though, I'm going to only expose what Box2D sort of provides i.e. AABB picking and ray-casts. I need to think about this a little further over the next few hours because there's a difference between an AABB pick and the other picks. The AABB is, as you may know, a virtual hull surrounding the "size" of the object (not the collision shapes). Picking a ray is against the collision-shapes so I need to be clear here. I'm actually thinking of distinguishing them in some way to make it clear. Also, the "CastCollision" calls will go, at least for now. These will take some work to get working and I don't think they're important right now.

I intend to get picking to support the render AABB (size) and then probably point & line and drop the circle pick support. If that's needed then it can be brought back if/when the cast-collision stuff is because it'd use the same sort of code.

So I'd say, ignoring getting tile-maps working, I'm about 70% the way there.
Getting to 70% in less than a month is extremely impressive for a single developer, albeit a very experienced and skilled one. Keep in mind the long term series of tasks include the engine implementation, fixing the editors, porting projects, updating documentation, and of course training. What gets really exciting is when you get an e-mail update two days later that contains the following:

Quote:So the Box2D integration is going extremely well and I'm ahead of schedule. I've managed to get it integrated minus joints and collision-callbacks (which I'm working on now).

On the basis that without an image or video it didn't happen, I thought I'd put together a quick video showing you it working:


Configuring this stuff is really simple and fluid. Ignoring the background of the scene, here's the loop that creates some footballs, sorry ... soccer balls:

// Footballs (not soccer balls).
for ( %n = 0; %n < 100; %n++ )
%obj = new t2dStaticSprite();
%obj.setImageMap( FootballImageMap );
%obj.setPosition( getRandom(-40,40), getRandom(40,100) );
%obj.setAngle( getRandom(-180,180) );
%obj.setSize( 4, 4 );
%obj.createCircleCollisionShape( 2 );

%scene.addToScene( %obj );

... and the same for the boxes:

// Boxes.
for ( %n = 0; %n < 100; %n++ )
%obj = new t2dStaticSprite();
%obj.setImageMap( MiniTileMapImageMap, getRandom(0,15) );
%obj.setPosition( getRandom(-40,40), getRandom(40,100) );
%obj.setAngle( getRandom(-180,180) );
%objWidth = getRandom(1,8);
%objHeight = getRandom(1,4);
%obj.setSize( %objWidth, %objHeight );
%obj.createPolygonBoxCollisionShape( %objWidth, %objHeight );
%scene.addToScene( %obj );

All of Box2Ds collision shapes are supported i.e. polygon, circle, edge & chain shapes. You can also have an unlimited number of them per scene object. This will prove particularly useful for tile-layers which I need to work on soon.

Whilst integrating Box2D I took the opportunity to perform a much needed tidy up on the API including general formatting. This includes separating the script-bindings into their own header file for types as well as ordering, grouping and synchronizing the field & method declarations & definitions in the source.

The next steps are:
Get contact callbacks working
Add the API for joints
Resurrect tile-maps
All appropriate level builder modifications
For now though, I think this is good progress. :)

Wait? You want to see what YOUTUBE_LINK was? Fine:

Next Time

That's it for this week folks. I was really looking forward to this post, since you all were asking a lot of relevant questions in last week's blog. I think next week I will wrap up Box2D and give you a final teaser, then move on to a new subject. Keep posting and I'll see you all in IRC.

06/12/2012 (10:19 am)
This is pretty interesting. I wonder if you could comment on the work required to upgrade to Physx 3.x, and whether that is something we can expect in the forseeable future?
06/12/2012 (10:45 am)
@John - Glad you like the blog. Unfortunately I'm not in a position to talk about 3D stuff, which is why I've started 2D Tuesdays. I wanted to manage the expectation that I will be blogging more often, but I will only be covering our 2D technology. If I can think of something 3D, I will hold off until our community hour on Fridays.
06/12/2012 (11:11 am)
PhysX 3.x integration is not in the plan for 1.3.
06/12/2012 (11:36 am)
Being fairly new to the community, I wasn't aware you were doing community hours. How does one participate?
06/12/2012 (11:37 am)
@John in the CE we use the newest version of the Bullet Engine (I believe it's the latest anw) it should have any feature that PhysX has if you have any question about it refer to the Community Discussion thread.

Now back on topic!
Looks pretty good! It's nice to have these blogs so we can see that something is going on! Even if it is not on the 3D engine which I work on I love to read your blogs and I am always interested in your progress! Good work guys!
06/12/2012 (11:52 am)
Great to see the 2d side of things getting serious attention!

In working with Box2D with XNA and Flash I've found that creating a moving/rotating/zooming camera is universally tedious due to the changing units between the physics simulation and the engine units and the matrix math needed to get everything moving together smoothly.

I think it would be really great to have that complexity hidden within the fancy new t2dCamera ;) object and even exposed to the editor.
06/12/2012 (11:56 am)
@John - It's really simple. Every Friday at 12:00pm (PST), several employees will participate in various aspects of the community. A few of us will join our IRC channel for live discussion. Others will post in blogs, forum threads, and resources. We look for existing discussions we can join in on, or create an entirely new topic. It's easy to spot us via our profile badges. We're the ones with the dark purple background in our names/studio.
06/12/2012 (2:07 pm)
Go Mich and Melv!
06/12/2012 (7:52 pm)
Keep bringing videos to these blog posts whenever possible! It made it very enjoyable to see the result.
06/13/2012 (12:54 am)
I was looking forward to this post since Sunday. Ahhhhh. Quenching. Now if I can make it another week. <scratch scratch>
06/13/2012 (11:40 am)
I was happy to see that box2D wasn't limited to flat surfaced objects.
06/13/2012 (10:15 pm)
@Charlie: Lucky you. Soon I'll be re-enacting scenes from Drugstore Cowboy with only one fix per week :)
06/14/2012 (4:02 am)
Looking good Mich and Melv. Keep at it.
06/15/2012 (8:19 pm)
Dang! This all looks great and exciting. I'm actively looking forward to future 2D Tuesdays!
06/16/2012 (10:48 pm)
Last time we talked about Box2D integration we were in 2009, so I would like to know if you are finally implementing the current SVN version or something older? A lot of improvements has been done lately, specially with tilemap (since you are updating this part as well).

The full disclosure part in the introduction doesn't excite me much...

Would it be possible on the next 2D Tuesdays to establish a list of the current known bugs and problems with the engine so I can clearly see if my next project (that doesn't need Box2D) is doable with the current version or not?

06/17/2012 (9:39 am)
@Rivage - We are working with the latest Box 2D version. I know the Full Disclosure seems like a wet blanket, but I have to protect the team. I want to set real expectations and not hype something.

To be clear about your request, do you want a list of known bugs for Torque 2D 1.7.6 or iTorque 2D 1.5? I have something else planned for this Tuesday, but I can add your suggestion to another 2D Tuesday entry once I know the answer to the question I just asked.
06/17/2012 (1:31 pm)
Yes please.
A list of known bugs for Torque 2D 1.7.6 (mainly) because it's hardly easy to guess that from the bugs forum. Many are just errors from users while using the product.

So I can choice which engine is best for my next project.
06/18/2012 (10:43 am)
@Rivage - Alright. I'll see what I can do. I'll have to compare our current bug tracker list with what's in the forums. Granted, many of them would be irrelevant if we ended up using the R&D work as a live release, but that would of course come with its own known issues list.

Again, tomorrow is too short of notice and I already have something ready. Just keep following the blogs and I will state next week's agenda each time.