Jump to content
  • Advertisement
  • 07/02/18 08:21 PM
    Sign in to follow this  

    A Really Useful Box2D Editor

    Engines and Middleware


    A Really Useful Box2D Editor

    You're a game developer. Your next project will have Box2D-powered physics, and it'll be awesome. So you wrestle with installers, build systems, possibly with compiling the library itself, and then get a rectangle moving around on-screen. Now what? If your game is non-trivial, you could have dozens of different types of objects. You're not going to have a good time describing them in code, as you'd have to recompile every time your designer (which could be you) blows his/her nose. You could come up with your own loader, but then you'd have to come up with your own file format, too, and that's time not spent actually making your game!

    Enter R.U.B.E., the Really Useful Box2D Editor. R.U.B.E. is a level designer for virtually any game that uses the Box2D physics engine. You can use it to visually create a wide variety of collision shapes, place them on-screen, and edit their properties. R.U.B.E. also boasts a comprehensive scripting system, support for nearly all Box2D constructs, and extensive customizability.



    The Setup

    I use R.U.B.E. on Ubuntu 14.04 and a reasonably beefy 2011-era Samsung laptop. R.U.B.E. is available for Windows, Mac, and Linux. The Mac version, however, does not officially support 64-bit computers; it might or might not work. Likewise for any Linux distribution other than Ubuntu. When in doubt, see if the trial version works. I'm using R.U.B.E. to develop a top-down shooter written in Java and libGDX.

    The Editor

    The user interface for a program like this should aim to minimize the barrier between the designer's ideas and his/her implementation. Fortunately, R.U.B.E.'s editor does a decent enough job of that. The controls for the editor itself are a bit clunky, relying on keyboard shortcuts to perform basic geometric transformations (e.g. pressing S to scale an object, as opposed to just grabbing a handle like in Unity or Inkscape). A bit annoying, but you'll get used to it. Other features, like the ability to position the menus freely, or the ability to copy objects to other programs as plain text, or even to run the Box2D engine to see how objects move in the world, are very much welcome. I don't think you'll be wrestling with the program too much.

    The Scripting

    My limited experience with RubeScript, the built-in scripting engine derived from AngelScript, was a pleasant one. The language itself is nothing spectacular, preferring simplicity for programmers and non-programmers alike over flashy features. Better documentation for the built-in types (strings, arrays, etc.) and code completion would've been nice, at least.

    What really makes RubeScript stand out is its thorough functionality. Almost all of the built-in editor actions--adding or deleting bodies and joints, smoothing or removing vertices--are actually implemented in RubeScript, and can be viewed in R.U.B.E.'s installation. If the developer himself can write the meat of R.U.B.E. in its own scripting system, I'm sure you can get something out of it, too. Tools like this are why game designers benefit from some programming skills.

    The Competition

    Minimal. Most available alternatives lack some of R.U.B.E.'s most defining features. These other editors are only designed for creating simple game objects (such as PhysicsEditor, which doesn't support joints), or lack adequate import/export facilities (e.g. BoxCAD, whose output requires ActionScript 3.0 to be used). Other more generic solutions such as Tiled or even Inkscape might suit your needs if you can write a loader to convert their output to Box2D worlds. I don't feel that most of these other alternatives fill the need for a 2D physics world editor, though for very small games you may disagree.

    The Surrounding Ecosystem

    I have nothing but good things to say here. The official documentation for R.U.B.E. is excellent. Even if you ignore the built-in manual (which is very detailed and contains plenty of images), there's a wealth of resources available on the official website, including sample projects and video tutorials.

    But perhaps best of all, Chris Campbell (the developer) actually gives a damn about you. He reads the forum and any e-mail he gets. It's easy to report bugs or offer feedback from within R.U.B.E. itself. I can send a hastily-written bug report or feature request through through R.U.B.E. and continue working before my concentration wavers. You'll actually get a response from Chris within a reasonable time frame, and he'll make sure you get the best out of R.U.B.E. you possibly can. He's helped me numerous times with reporting bugs, feature requests, and even general Box2D questions.

    The main problem with R.U.B.E., as I see it, is that your game's technologies will be limited to whatever has a R.U.B.E. loader and a Box2D port available. This issue isn't exclusive to R.U.B.E.--it's inherent in any technology that's not as mainstream as, say, PNGs or WAVs. While R.U.B.E. does have loaders available for many popular game frameworks and programming languages, if none of them suit your needs you'll either have to reconsider your toolkit or write your own loader.

    The Bottom Line

    A designer alone may not have much use for R.U.B.E., because odds are if he/she is using a prefab game engine like Game Maker or Unity he/she'll be using its respective built-in editor. But for programmers or designers working with programmers, R.U.B.E. is a solid investment. R.U.B.E. is flexible enough to play well with any custom game engine, yet simple enough to make entertaining game worlds with ease. I wholeheartedly recommend taking the $30 plunge.

      Report Article
    Sign in to follow this  

    User Feedback

    There are no comments to display.

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

  • Advertisement
  • Advertisement
  • Latest Featured Articles

  • Featured Blogs

  • Advertisement
  • Popular Now

  • Similar Content

    • By Catch_0x16
      Hello folks,
      I am fighting with a really simple problem that has been driving me nuts. I'm usually fairly confident with trigonometry and I'm pretty sure the issue here is not the math but in some behavior behind the scenes.
      A bit of background - basically I'm developing my own little 2D game engine using C++, in my free-time for fun. I work with game technology and simulation products IRL so for the most part this has been plain sailing. I am using Box2D for physics, and SFML for rendering.
      My game at current has a few space ships flying around via keyboard and AI input. These space ships need exhausts! So I'm currently in the process of getting a 'component' system in place, however my problem is that the animated exhaust sprites are not going where I want them to.
      When the base GameObject class runs it's update method, it does the following:
      Queries the physics object for a position Converts the physics position to a pixel position (x10 scale factor) Moves the sprite to the new position Passes new position to all 'component' objects into their 'UpdateComponent' method Components move their sprite to the correct position However the exhaust sprites seem to wander around all over the place, in no way representing where I actually want them to be! This should have been a simple case of:
      newPosition = (sin(rotationRadians) * offsetX, cos(rotationRadians) * offsetY) + oldPosition Here is the current code:
      void Exhaust::UpdateComponent(const Vec2f & position, float rotationDegrees, float deltaTime) { float angleRad = DEGREES_TO_RADIANS(rotationDegrees); float offsetX = sin(angleRad) * mOffset.x; float offsetY = cos(angleRad) * mOffset.y; sf::Vector2f newPos(position.x + offsetX, position.y + offsetY); mSprite->SetRotation(rotationDegrees); mSprite->SetPosition(newPos); mSprite->Update(deltaTime); #ifdef _DEBUG sf::Vector2f p(position.x, position.y); stringstream ss; ss << rotationDegrees; DebugUtils::DrawCross(p, 8, sf::Color::Green, ss.str()); DebugUtils::DrawCross(newPos, 8, sf::Color::Green); DebugUtils::DrawLine(p, newPos, sf::Color::Green); cout << rotationDegrees << endl; DebugUtils::DrawSpriteOutline(*mSprite->GetGraphic(), sf::Color::Green); #endif // _DEBUG }  
      And here is a gif of it all going wrong! (link below)
      Gif of game engine problem
      Any help would be much appreciated, even if it is just a thought of where the problem might be originating from!
    • By EBBLER
      i am developing an android game with libgdx and box2d. I made a simple enemy that walks towards the player.
      I can shoot bullets and move the bullets like this:
      body.applyForce(m_impulse,body.getWorldCenter(),true); // This is applied only once This moves the bullet straight forward, that is what I want. But when the ( small ) bullet hits an enemy, he gets thrown back like 100kilometers. How can i prevent that?
    • By dmatter
      This is a technical article about how I implemented the fluid in my game “Invasion of the Liquid Snatchers!” which was my entry for the fifth annual "Week of Awesome " game development competition here at GameDev.net.
      One of the biggest compliments I’ve received about the game is when people think the fluid simulation is some kind of soft-body physics or a true fluid simulation. But it isn’t!
      The simulation is achieved using Box2D doing regular hard-body collisions using lots of little (non-rotating) circle-shaped bodies. The illusion of soft-body particles is achieved in the rendering.
      The Rendering Process
      Each particle is drawn using a texture of a white circle that is opaque in the center but fades to fully transparent at the circumference:

      These are drawn to a RGBA8888 off-screen texture (using a ‘framebuffer’ in OpenGL parlance) and I ‘tint’ to the intended color of the particle (tinting is something that LibGDX can do out-of-the-box with its default shader).
      It is crucial to draw each ball larger than it is represented in Box2D. Physically speaking these balls will not overlap (because it’s a hard-body simulation after all!) yet in the rendering, we do need these balls to overlap and blend together.
      The blending is non-trivial as there are a few requirements we have to take into account:
       - The RGB color channels should blend together when particles of different colors overlap.
         -- … but we don’t want colors to saturate towards white.
         -- … and we don’t want them to darken when we blend with the initially black background color.
       - The alpha channel should accumulate additively to indicate the ‘strength’ of the liquid at each pixel.
      All of that can be achieved in GLES2.0 using this blending technique:
      glClearColor(0, 0, 0, 0); glBlendFuncSeparate(GL_ONE_MINUS_DST_ALPHA, GL_DST_ALPHA, GL_ONE, GL_ONE); Putting all that together gets us a texture of lots of blurry colored balls:

      Next up, is to contribute this to the main backbuffer as a full-screen quad using a custom shader.
      The shader treats the alpha channel of the texture as a ‘potential field’, the higher the value the stronger the field is at that fragment.
      The shader compares the strength of the field to a threshold:
      Where this field strength is strong enough then we will snap the alpha to 1.0 to manifest some liquid. Where the field strength is too weak then we will snap the alpha to 0.0 (or we could just discard the fragment) to avoid drawing anything.
      For the final game I went a little further and also included a small window around that threshold to smoothly blend between 0 and 1 in the alpha channel, this softens and effectively anti-aliases the fluid boundary.
      Here’s the shader:
      varying vec2 v_texCoords; uniform sampler2D u_texture; // field values above this are 'inside' the fluid, otherwise we are 'outside'. const float threshold = 0.6; // +/- this window around the threshold for a smooth transition around the boundary. const float window = 0.1; void main() { vec4 col = texture2D(u_texture, v_texCoords); float fieldStrength = col.a; col.a = smoothstep(threshold - window, threshold + window, fieldStrength); gl_FragColor = col; }  
      This gives us a solid edge boundary where pixels are either lit or not lit by the fluid.
      Here is the result after we apply the shader:

      Things are looking a lot more liquid-like now!
      The way this works is that when particles come within close proximity of each other their potential fields start to add up; once the field strength is high enough the shader will start lighting up pixels between the two particles. This gives us the ‘globbing together’ effect which really makes it look like a fluid.
      Since the fluid is comprised of thousands of rounded shapes it tends to leave gaps against the straight-edged tilemap. So the full-screen quad is, in fact, scaled-up to be just a little bit larger than the screen and is draw behind the main scene elements. This helps to ensure that the liquid really fills up any corners and crevices.
      Here is the final result:

      And that’s all there is for the basic technique behind it!
      Extra Niceties
      I do a few other subtle tricks which help to make the fluids feel more believable…
      Each particle has an age and a current speed. I weight these together into a ‘froth-factor’ value between 0 and 1 that is used to lighten the color of a particle. This means that younger or faster-moving particles are whiter than older or stationary parts of the fluid. The idea is to allow us to see particles mixing into a larger body of fluid. The stationary ‘wells’ where fluid collects are always a slightly darker shade compared to the fluid particles. This guarantees that we can see the particles ‘mixing’ when they drop into the wells. Magma particles are all different shades of dark red selected randomly at spawn time. This started out as a bug where magma and oil particles were being accidentally mixed together but it looked so cool that I decided to make it happen deliberately! When I remove a particle from the simulation it doesn’t just pop out of existence, instead, I fade it away. This gets further disguised by the ‘potential field’ shader which makes it look like the fluid drains or shrinks away more naturally. So, on the whole, the fading is not directly observable.  
      Performance Optimisations
      As mentioned in my post-mortem of the game I had to dedicate some time to make the simulation CPU and Memory performant:
      The ‘wells’ that receive the fluid are really just colored rectangles that “fill up”. They are not simulated. It means I can remove particles from the simulation once they are captured by the wells and just increment the fill-level of the well. If particles slow down below a threshold then they are turned into non-moving static bodies. Statics are not exactly very fluid-like but they perform much better in Box2D than thousands of dynamic bodies because they don’t respond to forces. I also trigger their decay at that point too, so they don’t hang around in this state for long enough for the player to notice. All particles will eventually decay. I set a max lifetime of 20-seconds. This is also to prevent the player from just flooding the level and cheating their way through the game. To keep Java’s Garbage Collector from stalling the gameplay I had to avoid doing memory allocations per-particle where possible. Mainly this is for things like allocating temporary Vector2 objects or Color objects. So I factored these out into singular long-lived instances and just (re)set their state per-particle. Note: This article was originally published on the author's blog, and is reproduced here with the author's kind permission.
    • By zedz
      Ive had a look at the demo but couldnt really glean the info from the demo suite One thing ive noticed over the years is 3d physics libraries crash + burn in the following situation. polygon mesh soup (doesnt even even have to be high polygon count) 100s of objects (spheres/boxes etc) in close proximity inside this meshsoup The reason they crash + burn is cause they go for accuracy over speed (which is laudable) but doesnt make for responsiveness. Im looking at something similar to this could box2d handle say 500 circles/boxs within this simple geometry say 1msec MAX on 2ghz machine? It doesnt have to give 100% accurate results just similar to what I have now, if a sphape enters a polygon, push it out cheers zed
    • By drago28
      I'm using construct 2 physics I have a working bike with everything setup and I'm able to do frontflip and backflip by adding angular velocity to the bike
      I want to increase score/ add points and display the "backflip / frontflip" text when the bike does it.
      so please help me I want to know the logic and how it's done.
      p.s. example about construct 2 is not necessary, just explain me how other games do it or anything else you have to share

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!