Recreation Developer Deep Dives are an ongoing collection with the aim of shedding mild on particular design, artwork, or technical options inside a online game with the intention to present how seemingly easy, elementary design selections aren’t actually that straightforward in any respect.
Earlier installments cowl matters equivalent to how artwork director Olivier Latouche reimagined the artwork course of Basis, how the creator of the RPG Roadwarden designed its narrative for influence and variance, and how the papercraft-based aesthetic of Paper Minimize Mansion got here collectively with the developer calls the Reverse UV technique.
On this version, Tim FitzRandolph of Toyful Video games provides an illuminating look into the comfortable physique physics simulation of JellyCar Worlds, aiming to evenly educate on the fundamentals to encourage comparable simulations.
Hello, I’m @walaber, an unbiased developer, most well-known because the creator of the JellyCar collection of video games. On the event of the a lot overdue launch of JellyCar Worlds (my trendy sequel that updates and improves JellyCar for contemporary platforms), I’ve determined to lastly spend a while sharing the small print about how the soft-body physics simulation works within the recreation, which supplies the sport its distinctive appeal and gameplay.
JellyCar is powered by a customized soft-body (solely!) physics engine, which allows the entire gameplay options and interactions. On this article, I’ll clarify every aspect concerned in making a simulation just like the one in JellyCar Worlds, as clearly and visually as potential. This isn’t a full-blown step-by-step tutorial, so don’t anticipate code snippets. As an alternative, this could familiarize you with the primary ideas, provide you with a place to begin on your personal investigations into comparable physics simulations, and hopefully encourage you to attempt making some physics-based gameplay of your individual.
It’s All Only a Bunch Of Factors
Inflexible physique simulations normally function on the concept of a small variety of “our bodies,” that are then composed of many “colliders.” Colliders are sometimes numerous primitives like cubes, spheres, capsules, and maybe convex hulls derived from meshes.
Against this, the 2D soft-body system in JellyCar is form of the alternative: we now have many, many particular person our bodies that transfer round, and their combination positions are used to outline the form (“collider”) of the thing.
These “our bodies” are normally known as level lots, as they’re a single level with a mass (“weight”) that may transfer round because of forces. So, step one in constructing a comfortable physique simulation is to get a bunch of level lots that may accumulate forces, and combine these forces into modifications in velocity and modifications in place. In different phrases, a bunch of factors which you could push round and so they transfer. At this level, you may need one thing that appears like this: a bunch of dots that may fall with gravity.
This doesn’t seem like a lot, however it’s the guts of the complete simulation! Almost every thing we do previous this level will merely be numerous methods to supply forces that act on these factors to make them transfer as comfortable, squishy objects.
Shapes and Collision Detection
The subsequent step (and by far probably the most daunting) is to attach these factors into particular person shapes (every level represents a “vertex” or nook on the form), in order that they will act collectively like a bigger single object (a “comfortable physique.”) Defining the form may be very easy! We create a brand new idea known as a “comfortable physique,” and its form is solely an inventory of level lots. Connecting these level lots so as defines the form of the physique:
Now comes the arduous half: detecting collisions between two shapes! In spite of everything, we gained’t have a lot gameplay if we are able to’t have our comfortable our bodies collide, push, and squish one another. Collision detection is a deep and sometimes troublesome subject, however fortunately for our functions we are able to create a simplified system. It hinges on this realization: when our comfortable our bodies collide, we might want to reply by transferring and adjusting velocities on the person level lots concerned.
Additionally, it’s a comfortable physique system, we really need our objects to deform, so we don’t want to determine find out how to transfer total shapes to resolve overlap, we are able to simply transfer the offending factors the place an overlap is going on, and let the physique deform in consequence!
In essence, which means that we are able to simplify the issue fairly a bit. In JellyCar’s system, collision detection appears to be like like this:
Given a possible collision between objects A and B:
- Take a look at all factors on object A, and see if any of them are inside object B.
- Take a look at all factors on object B, and see if any of them are inside object A.
- If some extent is inside an object, transfer that time and the closest edge on the thing simply sufficient in order that the purpose is not inside the thing.
And that’s mainly it! Let’s break this down into separate issues. First: find out how to know if some extent is inside the opposite physique’s form. That is primarily asking if some extent is inside a closed polygon. Fortunately it is a well-researched downside, and plenty of options exist. The strategy I utilized in JellyCar is that this:
Discover a level you understand is exterior the form. Draw a line between your check level, and the surface level. Rely up the variety of occasions this line crosses the form. If the quantity is odd, the check level is inside the form. If the quantity is even, the check level is exterior the form. Notice that this algorithm solely works for polygons with out self-intersections.
Now that we all know our check level is inside the opposite object’s form (polygon), we have to get it out! As a result of the basic constructing blocks of our simulation are the purpose lots at every nook, our answer must contain transferring some quantity of level lots. It really works like this: discover the closest level on the form to our check level. This can give us a course to maneuver the check level to get it out of the form, and in addition the sting (2 factors) on the form that it’s closest to.
Now we are able to transfer all 3 factors simply sufficient to get the purpose exterior of the form. How a lot we transfer the factors relies on the relative mass between all 3 factors and in addition the place alongside the sting we’re.
We additionally want to regulate the velocities of the factors concerned, since a collision has taken place, and issues like friction and their relative velocities should be accounted for. After I was coding this, I had no thought find out how to resolve a collision between some extent and a line, so I got here up with a easy approximation. I think about the sting is definitely simply one other level, positioned on the precise spot to supply the identical regular between the check level and the sting. Then I take advantage of the usual maths for an inelastic collision between two good spheres (think about billiard balls). This offers me a beginning place for the ensuing velocities from the collision, which I then alter a bit primarily based on the specified friction between the supplies concerned. Lastly, I take the ensuing velocity for the digital level that represents the sting, and distribute it again to the two factors on that edge, and we’re carried out!
Now we now have dealt with the scary a part of our simulation, and shapes can now collide and resolve their collisions. Test it out, it’s superb:
OK possibly not but. We don’t have something inflicting these objects to keep their form! Which brings us to…
The primary tactic to have the our bodies hold their form whereas permitting satisfying deformation is springs. A spring is de facto only a power that acts on two Level Plenty, making an attempt to maintain them a selected distance aside from one another. Too shut? Apply a power that pushes them aside. Too far? Apply a power that pulls them collectively.
We will add springs between the factors throughout the thing’s form (its “edges”), and in addition add inside springs (form of like constructing a bridge) to present the thing some construction.
This goes a great distance, and we now mainly have a working comfortable physique simulation, test it out!
When an object deforms, the springs are compressed, after which they push on the factors to attempt to get again to their authentic form.
When you begin making gameplay with this technique, you would possibly begin operating into some points with objects “popping inside out”. This can be a facet impact of the springs: they haven’t any idea of orientation, they only need to keep distance. A typical instance of that is with lengthy, skinny objects such as you see beneath:
When some extent is compressed arduous sufficient, the springs generally tend to “pop” to a steady configuration with the purpose on the unsuitable facet of the thing. You’ll be able to in fact simply attempt to keep away from this taking place by not letting objects compress that a lot, however we’re making a soft-body recreation in any case, we would like issues to SQUISH.
My major answer to that is what I’m calling:
The fundamental thought is that this: what if we may have some spring forces that know the form of the thing, and all the time tried to drag on the factors to get them again to the unique form? My answer works by imagining that the unique form of the thing exists as a stable metallic body. Every physics step, we attempt to align the body over the precise physics object, matching its place and angle as precisely as we are able to. Then, we are able to apply a spring power between every level on the thing, and its corresponding level on this digital inflexible “body.” These springs will all the time “pull” the factors again towards their appropriate place:
The trickiest half is determining the place to position the body. Since our objects are made up of many individually transferring factors, and certain deforming wildly, we don’t even have a “place” and “angle” for the physique as a complete. So, we now have to derive it in some way. My technique is fairly easy. First, common the positions of all of the factors concerned to get the “geometric middle” of the thing. That is our place. Then, examine the angle from this middle to every level, to the angle of the identical level on the body. Averaging these angles will give us an approximate angle for the physique, primarily based on the place all of the factors are on the given second. You’ll be able to see this visualized right here:
Form matching makes an enormous distinction, and permits for enjoyable gameplay just like the JellyCar getting fully squashed flat by an enormous heavy door, and it might pop again to its form with ease.
This technique does have just a few issues to be careful for. When an object is lengthy and thin, squishing it from one course doesn’t displace the factors as a lot as squishing it from the opposite.
See how the factors on the back and front of the automotive get pulled so removed from the body? This will produce unrealistically massive forces that trigger objects to behave unnaturally. I’ve overcome this by supporting a number of form matching “frames” per object, so I can break up the frames into extra localized areas of an object.
Notice: whereas writing this text I additionally realized I may simply clamp the power / max distance for the form matching springs and that ought to assist loads! Grasp on a second whereas I replace my physics engine (lol).
One other technique that helps objects hold their form is to fill them with digital “gasoline” (like inflating a balloon.) This produces a strain power pushing out on the sides of the form, primarily based on the quantity of the thing in comparison with the quantity of digital “gasoline” inside. This works superb, and produces actually nice movement for objects. The tires on the JellyCar work like this, together with (fairly clearly) the balloon power-up.
The main draw back to a strain power is that it’ll all the time form of push objects to grow to be spherical/inflated. For instance, utilizing strain on the automotive doesn’t assist an excessive amount of as a result of it can distort the form of the automotive:
Connecting Issues Collectively
At this level we now have described most of what we have to make a recreation like JellyCar! Aside from a solution to really join the tires to the automotive!
The ultimate piece of the puzzle is the idea of joints. The only type of a joint merely “welds” two level lots collectively (presumably on totally different comfortable physique objects) to attach them like a hinge. You’ll be able to see this used loads within the recreation, and it’s actually simply so simple as making certain that the place of the 2 level lots are all the time equivalent (and probably adjusting the velocities as nicely, relying on what kind of integrator you’re utilizing).
This doesn’t actually work for attaching the tires to the automotive, although, as a result of the 2 our bodies don’t have conveniently positioned level lots precisely the place we have to join them. For this I’ve made a barely extra sophisticated hinge that I name a “pin joint”. It really works by choosing a number of factors on a physique, and creating an “anchor” by way of a weighted common of these factors (in any case, every level is transferring independently on a deforming object.) Then we are able to do the same process to the straightforward weld joint to verify the 2 anchors keep related, by transferring (and adjusting the velocities) the factors concerned on every physique to align the anchors.
That’s a Wrap!
OK, for those who made it this far, you have to be focused on physics simulations, thanks for studying to the top! I hope this has given you on the very least a greater thought of how JellyCar works, and even maybe impressed you to make a few of your individual customized physics simulations for your self.