Categories
Welcome to the Clickteam Blogs
This new area of our site will host a range of blogs including Clickteam News, information about Fusion 3 development, ClickStore Features, User Devlogs and much more besides.

If you would like to write a guest blog article about your game, app, development or something else then please Contact Us for more information.
Collisions in Fusion 3
Posted on: January 23, 2017
Today I want to talk a bit about the collision system in Fusion 3.

Collision detection is very important in many games and we want to keep it as simple and intuitive as it has been in previous titles.On of the major differences between Clickteam Fusion and other game engines is how short there is from intent to implementation. In other engines you typically have to manually set up event handlers, callbacks or other methods or possibly even loop through all instances yourself to check for collisions. In Fusion and earlier products you only had to define the event…

If [SomeObject] collides with [AnotherObject]
—> [SomeObject]: Bounce

The KnP/TGF/CnC/Fusion engine then automatically knows your intention and handles everything for you. The game engine knows the context of all that is needed in this example. For example from “SomeObject”’s point of view the “Bounce” action means bounce off of whatever it just collided with. In this case it is “AnotherObject” and the engine can from the collision detection system figure out the resulting new angle for “SomeObject” to travel in after the bounce. High level programming, like what you do in Clickteam products, is all about getting your intention down into code that works like you expect it to do – but not limit your options when you want something different to happen.

The collision system in Fusion 3 will not be much different to what you are already used to. We will however do a lot of interesting things behind the scenes to make the system even better.

Limitations in Fusion 2.5

To use the Fusion 2.5 collision system properly you had to use some sort of movement. Without them you sometimes had to manually implement your own collision detection systems.

Always setting X,Y positions on your objects to move them would not generate the “On collision” events properly. Even when they fired the collision system would have no idea how to handle any “bounce” actions or similar. Always setting an object position is to the collision system the same as the object being completely still but always teleporting a tiny amount. It would not see this as a physical “momentum”.

To overcome this, many users used the Ball movement and controlled it’s speed and direction carefully. Some also completely ditched the Fusion collision system and only relying on the “Object is overlapping” conditions and extensions like “Move Safely” to manually move objects.

To those who don’t know the “Move Safely” extension it is an object that you can ask to move an object towards a given position. It would then in small incremental steps move the object a little bit of the way and ask the runtime for collisions. If the object was in a “forbidden” zone (like overlapping some terrain, or object it should collide with) it would carefully move a bit backwards until no longer overlapping. All this would happen nearly instantly and the end result would be the object appearing to use a very fine collision detection system. It was a clever use of callbacks and and some aspects of the Fusion collision system.

It was however slightly confusing to new users, required you to set up callback events to tell the extension when a collision was happening or not. Furthermore you would not be able to use actions like “Bounce” since the collision system never saw an actual collision itself and it would have no idea which direction to move the object in afterwards.

We want to do better.

The Fusion 3 collision system

We wanted the ability to make use of the easy to use collision system even when not using a movement. So how can you move an object some distance and have collisions be tested for along the way to the new destination? In Fusion 3 we are introducing a new action called “Move to” that at first hand looks like and works a lot like the “Set position” action. It will however work a bit like the “Move safely” object in the sense that the object might be stopped “underway” to the destination if your “On collision”-events have stopped the object.

With the “Move to” action you can make your own Ball Movement replacement in a few lines of events while still taking full advantage of the fast collision system in Fusion 3. In fact the default movements in Fusion 3 are all using this “Move to” internally. Eventually you can code your own movements and share them with your friends and they can use the movement like if it was an inbuilt movement.

From the technical side – behind the scenes

In Fusion 3 we use an acceleration data structure called an Axis Aligned Bounding Box tree (AABB-tree for short) to make your games all nice and fast. The AABB tree allows us to “split up” the world into logical pieces when we perform the collision detection so that we don’t have to test for collisions on all pairs of objects. If we didn’t do that your games would run incredibly slow. If you had 1.000 objects in your game (not entirely unrealistic) and all objects could potentially collide, then a “naive” collision system would have to test 499.500 pairs of objects for collision. Why so many pairs? It can best be described as the “Handshake” problem. If there are two people in a room then in order for all of them to greet each other then only one handshake would be required. If there are 3 people then you need 3 handshakes, 4 people = 6 handshakes, 5 people = 10 handshakes. I got the exact number from the equation: n(n-1)/2

Obviously we do not want that amount of testing to happen all the time in your games. Instead we have to be smart about which objects could potentially collide. If two objects are far apart and don’t move much then we don’t even need to test them at all. The good old rule of thumb for performance sound a bit like:

“It’s not how fast you can do some work, it’s how fast you can avoid doing unnecessary work”.

One obvious observation is that if no objects moved then no collision detection is even needed. As a consequence of this we can also only iterate objects that actually moved when we need to test for collisions. This means we can in our “outer loop” ignore iterating the static objects like walls. For all the iterated objects we can then ask the AABB tree which objects are nearby and then iterate those in the inner loop to test for collisions.

The AABB tree works by asking it for the closest node that fully contains a given rectangle or circle.

In the example image we use the bounding circle of the bounding box of the object. In practice one can take a much more snug fitting bounding circle but that requires doing a little bit of image analysis to find the best fitting bounding circle for that particular image/object.

The part where we ask the AABB-tree for the nearby objects is the key to the performance of the collision system. It allows us to ignore all the objects that aren’t relevant.

Fast moving objects

Even now we have a lot of potential objects to test for collisions with. To make matters worse we have to take care of a typical problem in collision systems: fast moving objects.

As you might know most game engines are only updated around 60 times per second. Moving objects might not move far between each frame when the speed is low, but if you are factoring in incredibly fast moving bullets then they might “skip” over entire walls or objects between frames. This is not acceptable and we have to find a solution.

Many game engines use sub-stepping which breaks the collision routines into even finer steps so you might end up doing up to around 500 collision detection steps per second to find those collisions that might have been missed for the fast moving objects. When you have many objects this will also become a performance bottleneck. In Fusion 3 we are using a different approach that again draws back to the quote from earlier “it’s how fast you can avoid doing unnecessary work”.

To ensure that no object is skipped we make the AABB-tree look at a larger area that covers the entire area the object moved from and to. We call this area the “broadphase”. This gives us a larger list of potential objects to look at in the collision detection algorithm but it gives us the security of not missing any objects. It is still better than many-doubling our workload and not even getting guarantees for accurate collisions.

In the GIF you can see the broadphase as the trailing blue circle.

From our inner collision detection loop we have now reduced the problem to only looking at a pair of objects. Are those two objects even colliding? We only know that they might since they are near each other and at least one of them moved. Doing fine and accurate collision detection between only two objects is still a big task and can be slow. Looping over all the pixels in two sprites to find one pixel that overlaps is not very fast. Once again we will attempt to avoid doing unnecessary work by not even getting to that point.

Fusion 3 then does a series of simple tests to weed out the cases where objects aren’t colliding and it’s quick to determine so. Since both objects can potentially be moving very very fast we can’t simply test if their bounding boxes overlap each other. We need a way to test if they might overlap that takes time into account. In Fusion 3 we implemented a fast quadratic solver that very quickly can determine if the two moving objects will collide along the way and return the first possible time of impact. If the solver sees that they will not collide then the pair can be discarded and we move on in the collision system. If it however sees that there is a potential collision we can perform more precise substepping as needed.

In this GIF the resulting collision surface normal can be seen pointing out from the collided surface.

Collision systems are hard to do properly and I can’t get fully into all the details that we have put into ours. There are many edge-cases and other performance optimizations that are simply too boring to write and read about for these blog posts.

We’d love to hear your comments on our blog posts and on our development.Throw us a mention on Twitter or Facebook and tell us what you think!

https://twitter.com/Clickteam

https://www.facebook.com/clickteam/


Visit Clickteam @ FacebookVisit Clickteam @ TwitterVisit Clickteam @ YoutubeVisit Clickteam @ TwitchVisit Clickteam's The Reactor @ PatreonVisit Clickteam @ itch.io