Balsa Model Flight Simulator - Irregular Corporation
Hi,
Continuing our Show-and-Tell series here, today I want to talk about the AI in the game.
This was an entirely new thing for me, because in previous projects, I hadn't done a lot with AI. KSP didn't have much in the way of autonomous behaviours, other than simple controllers for facial expressions and basic attitude control in spacecraft, so this was the first time I got to actually put together a fully-featured AI system that could control flying vehicles and actually make them do things. I thought it was pretty interesting, so read on to learn more about how that happened:
So the AI in Balsa needs to be able to pilot vehicles on its own, to make them appear like they are under intelligent control, and ultimately, they need to also be able to play against the player, as opponents. This means the AI needs to not only be able to fly, it also needs to direct them through race courses and missions routes, acquire and lock targets when in combat, then engage them and attack as well.
Add to that the fact that in Balsa, we don't even know what the vehicles actually look like, because they are made of parts, and don't have fixed performance stats, and the whole prospect seems pretty daunting.
The best way to deal with this sort of complex system though, is to just take it in steps. In the words of Adam Savage: "You don't have to know how to make the whole thing, you just need to know what the next step is."
So the way I took this on in Balsa was to split the AI into several layers. Each layer takes care of a different level of behaviour, receiving instructions from the layer(s) above and directing the layer(s) below. This way, the AI behaviour is broken down into several levels of abstraction, going from the most basic level of controlling the aircraft input state, to the most abstract levels, where the AI is just thinking in terms of tasks and mission objectives.
Each level does only one thing, and doesn't try to understand what the other layers are doing, so that makes their individual jobs much simpler, and my own job of putting all this together actually becomes doable. This wasn't done in one go either. It was gradually built up over several iterations over many months, each time adding more functionality over the things I had made previously.
I should mention also, the AI in Balsa does not 'cheat'. It doesn't move the vehicle over a vector path, and doesn't introduce any non-physical or impossible forces to the model. It is actually flying the plane, using the same input signals you use.
From a game developer's perspective, this might sound like a really convoluted way of doing things. Pretty much every game AI cheats in some way or another, and when it's tuned and balanced, it's very hard to notice that the AI is cutting some corners here and there.
But doing it this way was a lot of fun to implement, and it lets some really cool things happen without us having to explicitly code them. For instance, if you shoot the wing off an enemy NPC, it may be able to continue flying (and fighting), because it's still doing what it can to maintain level flight. Some of the stock vehicles are actually pretty good at taking damage, in fact. However, it might just be too damaged to stay in control, and without us having to code it explicitly, it would just not be able to keep flying despite its best efforts.
A simpler NPC system, maybe one in which vehicles move through a predefined path, for instance, would have to be manually programmed to do this sort of thing. Here, the NPCs are flying using the same physics you experience, so anything that can happen to you in the simulation, can also happen to them.
This is all well and good, but how does this AI actually work? Time to get technical now.
The first layer is what I called the Fly-By-Wire layer. It sits in the vehicle's input receiver pipeline, intercepting the input that is sent to the vehicle (in your own plane this comes from your transmitter, but NPC planes have a similar virtual thing as well), and modifies the commands that get sent down to the vehicle's parts (to move control surfaces, fire guns, throttle engines, etc).
In the Fly-By-Wire layer we use lots of Control Loop systems, or as they're more commonly known, PID loops. These are really cool bits of code that, when fed a 'target' signal (called the set point), a measured 'feedback' value, and some tuning parameters, will generate an output signal that tries to get the measured value to match the set point. You then tweak the tuning parameters to control how quickly the output gets there, how much it corrects for drifting error, and how much it tries to prevent overshooting and overcorrecting.
The beauty of PID loops is that they don't require you to have a complete understanding of what is actually happening inside the thing you are controlling. This makes them excellent for controlling complex things that have lots of unknowns in them, like a simulated aircraft flying around with physical forces and an unknown arrangement of parts.
We actually have multiple levels of PID loops in Balsa's Vehicle AI, and the first and most basic of these is the Autotrim system.
Autotrim isn't technically even an AI controller, because it actually runs on the player's own vehicle. It doesn't fully control it either; all it does is look at the aircraft's controls state as the input, and based on the vehicle's angular velocity (the feedback), produces an adjusted control output so that when you aren't telling it to pitch, roll or yaw, it will try to zero out any rotation on the vehicle.
If you know KSP, this might seem familiar. Back there this was called SAS, and it worked in pretty much the same way, although this time I had the advantage of actually knowing what I was doing a bit more, so I managed to make a cleaner and more reliable implementation.
Autotrim doesn't really qualify as AI, but I wanted to mention it because the first layer of the AI, called the Autopilot Layer, is based on the same principle. It reads in the vehicle's physics state, and outputs a control signal for the parts. The difference here is that, unlike Autotrim, the autopilot isn't just trying to zero out rotations, it is also trying to make sure your rotations get zeroed out with the vehicle pointing in the right direction.
The Autopilot layer is also a bit more involved than SAS was in KSP, because this is not a spacecraft in space we are trying to control, but a fixed-wing airplane in flight. That means we can't just tell it to apply full rudder if we want it to change heading. We need to teach it to do coordinated turns, using all control inputs at the same time.
This happens with a series of intermediate steps in the control routine, which ties in all three controls to work together, so that when the aircraft is told to turn to a given heading, it will bank into the turn, pull the nose up, and use the rudder to maintain a coordinated turn. I called that the roll-yaw and bank-and-yank stages of the autopilot, because that's what it actually does.
This is the very bottom layer of the vehicle AI. It receives the most basic of inputs (a target pitch, roll, yaw and airspeed value), and outputs a control signal that actually directs the vehicle's parts to move in response, just as you do as the pilot. It is very much like a real autopilot system in that sense. If you've played other flight sims, you might be familiar with heading hold, altitude hold and speed hold autopilot modes. That's sort of what we are doing here.
So ok, we have something that will steer the plane towards the direction we tell it to go, but where should it go? This is the job of the next layer of AI, called the Flight Director.
In Balsa, the Flight Director is the middle AI layer. It receives a target waypoint vector from higher AI modules, and uses that to set the autopilot's target attitude. Basically, the flight director gets told where to go, and in turn tells the autopilot how to get there.
It is also responsible for two additional things. One, It checks whether the plane has reached the given waypoint, and notifies the higher level AI about it (which usually causes it to be given a new waypoint).
Two, it also takes care of the Terrain Avoidance stage. This originally used to be a higher-level function of the AI, but I later had to move it down to the FD layer. More about that in a bit.
On top of the Flight Director layer, we have the NPC AI layer. This is what decides where the vehicle needs to go.
At this level, we really don't know and don't care about how the vehicle will get to the point we are telling it to go to. We don't care what the shape of the vehicle is, if it's flying right side up or inverted, none of that. That is the job of the lower layers, and at the NPC level all we care about is picking out a position in the world that we want to get to, and what speed we want to get there at.
The NPC layer uses targeting as well as scenery and mission nodes to orient itself, but this is assuming everything is great and going according to plan. What if there are enemies around? What if we run out of fuel and need to crash land? The NPC layer also deals with that sort of stuff.
This happens using what I called the Task Stack. It is a set of NPC-level behaviours (or states), which are prioritized, so that at any point only the most critical priority state is active, and the less important ones are on hold.
There are several different types of Tasks, which command the vehicle to do different things when given a destination (usually in the form of a Waypoint Marker) or a Target, which can be another vehicle, including yours.
So, imagine we are an NPC plane in a combat mission. Our first job is to fly the mission route. We start at a spawn position, and get given the first waypoint in a route by the NPC spawner.
Each waypoint has a link to the next waypoint on the route, so the Mission task directs the vehicle to fly to the current waypoint, and once it gets told (by the Flight Director) that it got there, it selects the next waypoint. When the route ends, it can either head to a new route, or find an exit route which ends at a despawn marker. That's the basic 'mission' of a combat NPC vehicle.
But this first job is also the least critical job. What if along the way we spot an enemy? If that happens, the combat version of the NPC AI will enable the 'offensive' behaviour, which is a higher-priority, target-seeker type task. It will direct the plane out of its mission route to attack the targeted enemy.
This offensive state actually has sub-states of its own, because to actually engage in aerial combat, we have a few different steps to go through. We aren't trying to ram the enemy, we want to shoot it with our guns, so after chasing down the target and getting close enough, we switch to an aiming sub-state, where instead of trying to reach the enemy's position, we try to match speeds and aim our weapons.
Aiming is trickier than it seems, because remember the AI isn't cheating here. It shoots with the same projectiles you do, so just like you, it needs to lead the target and compensate for bullet drop if it wants to get a hit.
Finally, when the AI sees a good aiming solution in front of it, it pulls the trigger and fires the weapons. This is yet another sub-state of the offensive behaviour, because ammo is just as finite for NPCs as it is for you, so we don't want to hold down the trigger and spend the entire ammo load on a single burst. The firing behaviour normally does short bursts, to save on ammo and make each shot count.
This took a lot of tweaking and tuning to get right, but in the end the combat NPCs in Balsa turned out quite capable of getting some hits in and scoring kills. In fact, I daresay they are slightly more accurate than the average Imperial Stormtrooper.
That's the Offensive task of the NPC AI, but there can be other more critical tasks in the stack, which take priority over all of that.
For instance, suppose that as we engage, we run out of ammo. At that point we might as well forget about engaging and just get out of the fight as fast as possible. This is called the 'return to home' task, and it can be triggered in this sort of situation.
But suppose that as you head out, we get an enemy trying to shoot you down. This would trigger the Evasive task, and when active it will steer the plane not towards the target, but away from it.
There is also the Emergency task, which is meant to be used when crash-landing is the only remaining option.
These lower priority tasks are in place, but currently they are just empty behaviour slots, as they aren't fully implemented yet.
In practice, however, combat planes do already evade attackers pretty well. As they are trying to chase down their targets and the targets do the same in return, they get into some pretty compelling dogfights, with scissoring and turn-fighting manoeuvres and all.
And lastly, the lowest level task on the NPC layer used to be the Terrain Avoidance task. Like I mentioned earlier, this worked ok at first, but as the AI developed and new gameplay situations like racing were added, it had to be moved out of the task stack to the lower FD layer.
This was because with this system of priority behaviours, whenever the AI spotted an obstacle ahead, it would entirely forget anything it was doing to just steer away from the obstacle. This was certainly effective to avoid terrain and obstacles, but it resulted in very cowardly NPC vehicles, which were so afraid of crashing into anything, they would rather fly in circles than try to race you.
The new terrain avoidance module is much smarter. Instead of taking complete control, it will gradually apply a correction command, which gets incrementally more authoritative based on how close the obstacle is. And because the avoidance system isn't a task anymore, the task directions are still coming down from the AI layer, so even as the vehicle is steering away from the terrain, it doesn't forget what it was trying to do originally.
This is called 'soft-wall' avoidance, and it results in a much smoother, less dramatic and generally more efficient way of getting around obstacles. This makes the AI a lot better at racing, as most of the time, a small correction is all it needs to find a clear path.
This more or less covers how the AI in Balsa operates. It was one of the most fun parts of the projects to do, and I can spend hours watching the AI airplanes fly around and shoot at each other, tweaking and tuning it. Of course, like everything else, there's still lots of room to expand and improve, but as it stands I think it can already create some pretty fun gameplay and put up a respectable challenge for single player and PvE missions.
For me, this was the part of the project in which I learned the most, and it was surprising to me just how much knowledge I picked up from my seemingly unrelated hobby projects and even just watching lots and lots of YouTube videos from RC, electronics and robotics makers. I definitely recommend nerding out that way. It's very educational and entertaining, and much more often than I would have imagined, you end up finding real life uses for the stuff you learn.
There is actually one last layer for the whole NPC vehicle system, which is what gets them spawning into the world in the first place. This is actually part of Balsa's Scenario Logic system, and that is going to be the topic of my next post, so stay tuned for that. đ
For now, thanks for reading, and see you on the next one!
Balsa Model Flight Simulator - Irregular Corporation
Hi Again,
So today I want to talk about the gameâs aerodynamics.
On the previous blog I talked about the morphing parts in the game, and I mentioned briefly that those morph tweaks do have an effect on a wingâs flight model. Today I want to get into more detail on how each of the changes you can make affect the flight dynamics.
So, simulated flight for a game is all about vectors and geometry, when you get down to it. In a nutshell, itâs about taking in values from the physics simulation, like where things are and where they are going, and using that along with measurements of your aircraft to calculate the actual forces that act on the vehicle. If you do that well enough, the result is something that feels very much like flying.
In a typical flight simulator, where you know in advance what the aircraft type is, the usual way to do this is to set up known flight handling parameters for each aircraft in advance, which you then tune until it feels right and accurate for that plane.
In Balsa, however, we donât actually know what the aircraft looks like, because we arenât making them, the players are. So we canât have pre-tuned flight handling stats for each vehicle.
What we do have is information about the parts you use. We know where they are, and using the Morphing Parts system, we can also know their final shapes as well, by looking at the mesh vertices.
I went over that in detail on the previous post, but basically what the aerodynamic surface parts do is look at specific vertices on the partâs mesh, and use those to figure out the dimensions for the various measurements that define the surface.
So with that we have enough information to figure out the general shape of your wings. Now, how does that shape actually affect the flight physics?
Fortunately, lots of very smart people in the past have already figured all of this out, so this information can be easily found out there, and after some digging around I was able to piece together what each variation in wing geometry does on its own.
There are some essential dimensions that define a wing, and they all have specific names. Iâm going to go over some of them here, and try to explain how the game factors in their effects:
Span, Chord, Area and Aspect Ratio
Span is the length of the wing, looking at it from above or from the front. Itâs essentially the length of the wing. The Chord is how âdeepâ the wing is. That is, how long it is in the longitudinal (front/back) axis of the vehicle. These two dimensions together define the basic shape of a rectangular wing , and more importantly, its area.
The area of a wing surface (also called the Planform Area) is the area of the wing looking at it from above. Interestingly enough, the amount of lift you get out of a surface is actually only dependent on its area. The ratio between span and chord doesnât actually change that, although it has other effects.
This ratio between chord and span has its own name: Aspect Ratio. It basically represents how âsquareâ or rectangular a wing is. High aspect ratio wings are long and skinny, like in a glider; low aspect wings are short and stubby, like in a fighter jet.
The main effect of aspect ratio for a wing is that it affects the stall Angle of Attack of the wing. Higher aspect wings tend to stall at a lower angle than low aspect ones. However, high aspect wings also create less induced drag than their stubby counterparts (that is the part of the lift force vector that isnât perpendicular to the airstream, so it acts like drag). This makes them great for gliders, where you want to minimize drag losses as much as possible.
However, really long wings also have higher moments of inertia, which makes the plane harder to turn, so if maneuverability is your goal, you probably donât want that.
On the other hand, low aspect wings are much more resistant to stalling, and will normally tolerate much higher angles of attack before they enter a stall.
In game, notice how a low aspect wing design, like the DeltaRay M1 tends to lose lots of speed when you pitch up and down hard (try it at low throttle), but also has pretty soft, forgiving stalls. On high aspect wings like on the Glider One, on the other hand, notice how the long wings make the plane really hard to roll.
Dihedra
Dihedral is the name for the angle the wings make to the horizontal plane. This angle causes the wing on the inside of a banking turn to produce more lift than the one on the outside, which will cause the plane to roll back out of the turn on its own. Dihedral isnât a morph tweak in Balsa, as itâs achieved by simply rotating the wings using the Rotate tool.
In model aircraft, especially ones with no aileron control, a good amount of dihedral angle can really help the plane stay level as it flies. Keep in mind though that extremely high angles arenât all good, because you are effectively reducing your planform area when you are level, and stability is also always a tradeoff against maneuverability.
Dihedral always means a positive angle. The opposite case, where wings are tilted down, is called anhedral.
Sweep
This is the angle at which the wing, erm, sweeps, back. Swept wings are usually found on high speed aircraft, as they perform better than straight wings as you approach transonic speeds. There are other lower speed effects, however, that you are more likely to see in model scale:
A swept back wing presents its leading edge at an angle to the airstream, when the plane is flying forward. This means swept back wings will produce more or less lift as you yaw left and right, which causes the aircraft to roll in response to yaw slip. This is known as roll/yaw coupling, and itâs pretty significant. It's the reason why highly swept, high wing aircraft (e.g. the Antonov An-124) have anhedral wings.
Swept wings also tend to be more pitch-stable, as the tip sections are located aft enough to be able to lever against the CoM for pitch. (flying wing aircraft are all swept wings for this reason. Their wingtips are their tails)
Thickness
Thick wings tend to have a 'soft stall' as angle of attack increases, compared to thin ones, so they are generally more forgiving. This is not quite the same effect as aspect ratio has, however, as what changes here isnât the angle at which the stall happens, but rather how sharp the transition is between normal and stalled flight.
Thick wings also have more forward area, on the other hand, so they have more drag at zero AoA, this means thin wings can fly much faster, as they can effectively cut through the air more easily.
In game, the effects of thickness and aspect ratio are achieved by altering the lift-vs-AoA curve that wings use to calculate the lift for any angle of attack. We start with a standard curve that represents an average shape airfoil, and for each surface, we assign it a modified version of that curve based on its specific geometry values.
Taper
Tapering simply means that the measures of the wing change from root to tip. In Balsa, we have two controls for tapering horizontally and vertically separately.
Horizontal tapering causes the wing chord to decrease towards the tip, so it becomes a trapezoid shape. Aerodynamically, this has some effects, as a highly tapered surface will have the center of pressure (the point where aero forces act on) closer to the fuselage.
This also affects the moment of inertia for the whole vehicle, as the mass is more concentrated towards the center. Of course, tapering also affects the total area of the wing in general, so it has a very direct effect on the amount of lift generated.
Vertically tapered wings get thinner towards the tip, which simply means that the effects of thickness will be different at the tip and the root. Generally most aircraft wings will become thinner towards the tip, both for structural reasons (you donât want a thin beam having to support a big heavy thing at its end), and also to make sure that when the wing stalls, it begins stalling from the tips inwards, to reduce the chance of going into a spin.
Multiple Aerodynamic Surfaces
All this Iâve explained so far is just part of the story. You might have noticed that while these dimensions and angles describe the shape of a wing, they are all straight lines and corner angles. None of that is saying anything about curved wings.
The way we handle curving sections on wing parts is to use multiple straight surfaces in a single wing. Usually there are three on each wing part (with a few exceptions like the Weevot control surface and Modwing 0). Each surface tracks a smaller subsection of the wing, and does its simulation for just that section. The resulting forces then combine together to act as a more complex shaped wing.
This has the same effect as what you get when you build a larger wing in the vehicle editor using multiple smaller wing parts, except that itâs already built in on the part itself.
In the end, these small surfaces all work together, taking in their local airstream velocities, and using their internal measurements to output the forces for lift and drag on themselves. With each surface contributing its own forces to the vehicle rigid body, you get a very convincing model for simulated flight, in a way that works for any shape of vehicle, no matter what it is.
Also, this parts-based simulation naturally already supports things like breaking vehicles down into pieces. If you lose half your wing, we donât need to code rules into the game for how to respond to that. It will happen on its own, as the broken off wing is no longer there to produce any lift. It also automatically takes care of simulating control surfaces. These are also using the same flight model, but being able to rotate, they can change their angle to the airstream in very much the same way real ones do.
Of course, none of this is to say the aerodynamics of Balsa are complete in any way. There are lots of areas I want to continue expanding on in the future. For instance I really want to get the downstream effects of surfaces (say a wing) affecting the incoming airstream for other surfaces further aft, and to factor in the effects of prop wash, ground effect, and so on. There is still a lot of room to grow with Balsaâs aerodynamics, but I think with our current model, there is quite enough there to have a lot of fun tinkering and experimenting with different designs.
For now, happy flying, and thanks for reading! See you on the next dev blog!
As we are wrapping up for the end of the year we are also wrapping up lots of awesome development work for Balsa. This month we won't have a show-and-tell or deep dive for you, as we have a few important deadlines we need to hit. However, we wanted to take the time to thank everyone for their support this year and sticking with us in the lead-up to Early Access!
2020 has been a whirlwind for everyone and we are ready to head into 2021 with lots of exciting Balsa news and updates. As we have mentioned in previous updates we'll have another beta happening too, so keep an eye on our Steam updates or join our wonderful Discord community.
The team have mainly been working on the Career Mode gameplay logic and content, setting up the progression systems and all, so completing missions can earn you XP points and unlock stuff as you go. It's not super ground-breaking or unique for Balsa, but it's really important to make the game actually play out. (There is a bunch of new parts too, but they're not quite ready to show currently...)
We can let you know that in January our show-and-tell will feature aerodynamics and how they work, so keep your eyes peeled for that update, it's a gooden. In the meantime here is a sneak peak:
Today I want to talk about one of the features in Balsa I implemented a while back, which has become a sort of crucial component of how vehicle design and simulation works in the game, Morphing Parts.
(This is a long one. You have been warned)
The idea for morphing parts is something I've had in mind since back in the days of KSP. We didn't have those then, and you ended up having to have lots of very similar parts in the game, with minor differences in shape, so you could have enough design options to do things. It was sort of like putting together a puzzle out of those many pieces.
With Balsa, we decided early on we wanted to have morphing parts in the game, especially for wing parts. These are parts that can smoothly change shape, so that you can have a lot more design freedom, with much fewer parts.
[/img]
So internally, there are several ways you can approach this. One option is to use something called Blend Shapes, which is where you set up multiple versions of a 3D model, all having the same geometry, but with the model vertices in different positions.
Then in the game, you start with the base model, and you use these variant Blend Shape models to push around the vertices of the mesh towards these 'target' shapes.
This scheme also lets you combine multiple blends together, which basically adds them up to give you a new combined version of the mesh. Sometimes that works really well, other times... you end up with a gnarly mess.
Another approach is to use rigging, which is how 3D character models are animated. You set up an underlying skeleton, and each vertex in the model is assigned a value for how much the position and orientation of each bone will affect it. For our parts, this also works well, because unlike real life bones, these things don't actually have to be connected to one another, so you can use bones as a sort of 'anchor' to move parts of a model around, like say, the corners of a square wing panel.
So there's many ways to skin this cat, and the way we chose to implement this in Balsa was, well, both.
[img]{STEAM_CLAN_IMAGE}/33908629/c036182160a523944b6828ce5bf4ef2a3e0d9d96.png[/img]
Parts in Balsa are put together using Modules. This is a concept that came up a bit late in the game for KSP, but this time, it was something I had in mind from the outset, so there is a lot more modularity to Balsa's Modules. For instance, while in KSP we would maybe have one module called Engine for all the engine functionality of a part, in Balsa engines are further split into more basic components. One is the engine core itself, which merely takes an input resource (like Fuel or Electric Charge) and converts it to an output resource (called Drive Power). That's all it does. Then we have a Starter module, which is different for Electric motors or Fuel engines and handles the ignition logic, but the common core is the same. Then there are other modules, like Engine sounds and effects, and so on.
[img]{STEAM_CLAN_IMAGE}/33908629/8bde2e822b4ccbee07692886de7c7b559c05d376.png[/img]
With Part Morphing, we do pretty much the same thing, but with actually even more modules. We have one module that controls morphing via bones and rigging, another module that controls blend shapes, and these are all set up to do their one job, and [i]only[/i] their job. Another higher-level module (called PartMorphing) is where the actual morph tweaks are defined --these are the options you see as sliders when you right click a part in game-- and those in turn contain the setup for which blend shapes and bone displacements to use when the 'master' tweak value is changed.
[img]{STEAM_CLAN_IMAGE}/33908629/de5c8d1553f82f733afecc82f3726c11af2479e7.png[/img]
Hopefully that wasn't too bad to get your head around, but the gist of it is that we end up with a really flexible system, where morphing parts can be set up in several different ways. This is really handy for us and also for mod makers, because all these tools are part of the Balsa SDK.
So then, we have our morphing parts, and we can control their shapes via in-game tweaks (and now, just recently, via 3D handles as well). But this doesn't actually mean anything to the game yet, and worse still, it actually creates a few new problems.
The first big problem we have now, is that even though the part model gets morphed, this is only visual. There are also invisible models (called collision meshes) in the game which are used for the physics. In normal character animation this normally doesn't matter too much, because game characters typically have simplified collision geometry (like a big cylinder or capsule that is roughly the size of a person), so you normally don't see it and don't care. But here, the vehicle editor actually relies on the physics to detect for instance, where you have the mouse cursor over a part. If the collision geometry isn't super accurate to the shape of a part, the whole vehicle editor breaks down.
So to sort that (and other problems) out, what we did was set up a new modular system for morphing parts, which I called Mesh Tracking. This isn't a single module, but rather a collection of modules and module subtypes that all share access to the state of the morphed mesh, as it morphs.
[img]{STEAM_CLAN_IMAGE}/33908629/03acb02518dedf4b612d0ca331a8f954cf5fd2b1.png[/img]
Basically, a master tracker module keeps track of the mesh, and any time it gets modified, it lets the other submodules know about it. This is mainly for efficiency as all this mesh tracking stuff gets expensive on the hardware, so it's best if we only do it once for everything that needs it, instead of having each thing do that on its own.
So then on top of that, we can build all sorts of mesh-aware modules that do different things, using the concept of Mesh Tracking. This is done by simply storing a list of the vertices you want to track, and using the tracked mesh updates to look up where they are after each morph.
One very important one is called ProcMeshCollider, short for Procedural Mesh Collider. What that one does is keep track of a list of vertices on the model, which it then uses to create a lower-detail collision mesh. This is then guaranteed to always be accurate to the morphed part, because it gets created using the same vertices. The lower detail is a sort of byproduct of it, because we don't need to have it track all the verts of the original model, so we just pick enough to give us a good approximation of the general shape.
[img]{STEAM_CLAN_IMAGE}/33908629/948cb597234d00b26f906547d91e21bb2dca1601.gif[/img]
This modular approach is also great because it solves another problem, which is that collision meshes in PhysX can't be concave shapes (if you want good performance), they must be convex. Because these are all modules, we can sort that out by just having multiple ProcMeshCollider modules on the same part, each producing a convex piece of the model.
Now we have the visual and physical model of the parts set up to morph, which is great, but how should these shape-shifting wings simulate themselves in flight? The flight model also needs to get updated to account for the varied geometry of morphing wings.
This is also done via mesh tracking. We have, as you might have guessed, yet another module, where aerodynamic surfaces are defined. Surfaces store a more specific set of tracked vertices on the mesh than the colliders, because for these, we really need to know not only where the vertex is, but also which part of the wing it's [i]supposed to be[/i].
[img]{STEAM_CLAN_IMAGE}/33908629/f8076b9b6dbf9113cf947d770be307df6db2423d.png[/img]
So aero surfaces are set up using a little editor tool I put together, that basically walks you through a wizard type thing where you specify the vertex to be tracked for each of the eight required points to define the thing. These eight vertices are used to define three planes, which are then used to calculate the geometries for a 3D aerodynamic element. From that, we then figure out all the measurements needed to simulate that surface.
There are quite a few different measurements the game's flight model takes into account, and that might be a good topic for a future post, because it's pretty involved and this post is already pretty long. (And we're only about half-way there. Sit tight.)
So there are many more modules that use the tracked mesh data for their own things, which are interesting to talk about briefly:
One such module handles the system that keeps child parts of a morphing parent attached in place as the parent changes shape. This might seem really obvious when you see it working (because anything else would just be wrong), but it's actually pretty involved and is in fact another rabbit hole in its own right, if you want to fully nerd out on geometry and triangle coordinates and stuff. I might make another post on that one later.
[img]https://i.imgur.com/aH2d1TT.gif[/img]
Yet another module uses the mesh data to keep attachment planes in place, which we use to make attaching things to small places (like the leading/trailing edges of wings) easier in the vehicle editor. This actually ties back to the previous module I mentioned, because attachment planes and nodes can track the mesh more accurately.
And just this week, the latest addition to the ever growing collection of mesh tracking modules is the new 3D morphing handle feature.
These are the handles that appear when you mouse over morphing parts in the editor, allowing you to edit the morphing part much more conveniently than through the context menu sliders (those are still there, in any case).
[img]{STEAM_CLAN_IMAGE}/33908629/3750c777efd3a081a2d50a3a2735cea1426b9d3d.png[/img]
Each handle is positioned based on tracked vertices, so that as one handle causes the entire thing to change shape, the rest of the handles can move along with it.
This tracked vertex placement mode made it much easier to figure out where to put the handles around the part. Can you imagine the mess of trying to work out [i]by hand[/i] where each handle should be, if the value of any one handle can cause all others to move?
This also sort of gave us a bonus feature, which is that morphing handles can actually have two modes of operation. One is Direct mode, where the handle is dragged around linearly, and its position along its range of motion directly defines the value of the tweak it controls. Kind of like a fader potentiometer, if you're into electronics.
The other mode is called Relative mode. All it does is, instead of setting the value of the tweak directly, it uses the handle value as an offset to gradually increment or decrement the tweak itself. Think of using a gamepad to move an on-screen cursor, compared to using a mouse. That's the difference of relative and direct control.
The cool thing is that because the handles are tied to the mesh, and moving the handle also moves the mesh, what this does is that when everything is set up right, it creates a sort of spring-like behaviour, where the displaced handle causes the mesh to move [i]towards[/i] the handle, which in turn causes the handle to return to its neutral position. Basically the neutral point 'catches up' to the handle. This allows the handles to control part morphing with a very high degree of control, and gives us a neat smooth transition effect as a bonus (smoothly transitioning things are always a good thing in any game).
If you've made it this far, congrats! As you can tell, I tend to get carried away when talking about this stuff, but hopefully you now have a better understanding of how this part of Balsa's internal workings operate. If you want to get into mod making, hopefully this is also useful information on how to use the mesh tracking modules in your own creations.
So thanks for reading, and see you on the next dev post!
Cheer[[/img]
So internally, there are several ways you can approach this. One option is to use something called Blend Shapes, which is where you set up multiple versions of a 3D model, all having the same geometry, but with the model vertices in different positions.
Then in the game, you start with the base model, and you use these variant Blend Shape models to push around the vertices of the mesh towards these 'target' shapes.
This scheme also lets you combine multiple blends together, which basically adds them up to give you a new combined version of the mesh. Sometimes that works really well, other times... you end up with a gnarly mess.
Another approach is to use rigging, which is how 3D character models are animated. You set up an underlying skeleton, and each vertex in the model is assigned a value for how much the position and orientation of each bone will affect it. For our parts, this also works well, because unlike real life bones, these things don't actually have to be connected to one another, so you can use bones as a sort of 'anchor' to move parts of a model around, like say, the corners of a square wing panel.
So there's many ways to skin this cat, and the way we chose to implement this in Balsa was, well, both.
Parts in Balsa are put together using Modules. This is a concept that came up a bit late in the game for KSP, but this time, it was something I had in mind from the outset, so there is a lot more modularity to Balsa's Modules. For instance, while in KSP we would maybe have one module called Engine for all the engine functionality of a part, in Balsa engines are further split into more basic components. One is the engine core itself, which merely takes an input resource (like Fuel or Electric Charge) and converts it to an output resource (called Drive Power). That's all it does. Then we have a Starter module, which is different for Electric motors or Fuel engines and handles the ignition logic, but the common core is the same. Then there are other modules, like Engine sounds and effects, and so on.
With Part Morphing, we do pretty much the same thing, but with actually even more modules. We have one module that controls morphing via bones and rigging, another module that controls blend shapes, and these are all set up to do their one job, and only their job. Another higher-level module (called PartMorphing) is where the actual morph tweaks are defined --these are the options you see as sliders when you right click a part in game-- and those in turn contain the setup for which blend shapes and bone displacements to use when the 'master' tweak value is changed.
Hopefully that wasn't too bad to get your head around, but the gist of it is that we end up with a really flexible system, where morphing parts can be set up in several different ways. This is really handy for us and also for mod makers, because all these tools are part of the Balsa SDK.
So then, we have our morphing parts, and we can control their shapes via in-game tweaks (and now, just recently, via 3D handles as well). But this doesn't actually mean anything to the game yet, and worse still, it actually creates a few new problems.
The first big problem we have now, is that even though the part model gets morphed, this is only visual. There are also invisible models (called collision meshes) in the game which are used for the physics. In normal character animation this normally doesn't matter too much, because game characters typically have simplified collision geometry (like a big cylinder or capsule that is roughly the size of a person), so you normally don't see it and don't care. But here, the vehicle editor actually relies on the physics to detect for instance, where you have the mouse cursor over a part. If the collision geometry isn't super accurate to the shape of a part, the whole vehicle editor breaks down.
So to sort that (and other problems) out, what we did was set up a new modular system for morphing parts, which I called Mesh Tracking. This isn't a single module, but rather a collection of modules and module subtypes that all share access to the state of the morphed mesh, as it morphs.
Basically, a master tracker module keeps track of the mesh, and any time it gets modified, it lets the other submodules know about it. This is mainly for efficiency as all this mesh tracking stuff gets expensive on the hardware, so it's best if we only do it once for everything that needs it, instead of having each thing do that on its own.
So then on top of that, we can build all sorts of mesh-aware modules that do different things, using the concept of Mesh Tracking. This is done by simply storing a list of the vertices you want to track, and using the tracked mesh updates to look up where they are after each morph.
One very important one is called ProcMeshCollider, short for Procedural Mesh Collider. What that one does is keep track of a list of vertices on the model, which it then uses to create a lower-detail collision mesh. This is then guaranteed to always be accurate to the morphed part, because it gets created using the same vertices. The lower detail is a sort of byproduct of it, because we don't need to have it track all the verts of the original model, so we just pick enough to give us a good approximation of the general shape.
This modular approach is also great because it solves another problem, which is that collision meshes in PhysX can't be concave shapes (if you want good performance), they must be convex. Because these are all modules, we can sort that out by just having multiple ProcMeshCollider modules on the same part, each producing a convex piece of the model.
Now we have the visual and physical model of the parts set up to morph, which is great, but how should these shape-shifting wings simulate themselves in flight? The flight model also needs to get updated to account for the varied geometry of morphing wings.
This is also done via mesh tracking. We have, as you might have guessed, yet another module, where aerodynamic surfaces are defined. Surfaces store a more specific set of tracked vertices on the mesh than the colliders, because for these, we really need to know not only where the vertex is, but also which part of the wing it's supposed to be.
So aero surfaces are set up using a little editor tool I put together, that basically walks you through a wizard type thing where you specify the vertex to be tracked for each of the eight required points to define the thing. These eight vertices are used to define three planes, which are then used to calculate the geometries for a 3D aerodynamic element. From that, we then figure out all the measurements needed to simulate that surface.
There are quite a few different measurements the game's flight model takes into account, and that might be a good topic for a future post, because it's pretty involved and this post is already pretty long. (And we're only about half-way there. Sit tight.)
So there are many more modules that use the tracked mesh data for their own things, which are interesting to talk about briefly:
One such module handles the system that keeps child parts of a morphing parent attached in place as the parent changes shape. This might seem really obvious when you see it working (because anything else would just be wrong), but it's actually pretty involved and is in fact another rabbit hole in its own right, if you want to fully nerd out on geometry and triangle coordinates and stuff. I might make another post on that one later.
Yet another module uses the mesh data to keep attachment planes in place, which we use to make attaching things to small places (like the leading/trailing edges of wings) easier in the vehicle editor. This actually ties back to the previous module I mentioned, because attachment planes and nodes can track the mesh more accurately.
And just this week, the latest addition to the ever growing collection of mesh tracking modules is the new 3D morphing handle feature.
These are the handles that appear when you mouse over morphing parts in the editor, allowing you to edit the morphing part much more conveniently than through the context menu sliders (those are still there, in any case).
Each handle is positioned based on tracked vertices, so that as one handle causes the entire thing to change shape, the rest of the handles can move along with it.
This tracked vertex placement mode made it much easier to figure out where to put the handles around the part. Can you imagine the mess of trying to work out by hand where each handle should be, if the value of any one handle can cause all others to move?
This also sort of gave us a bonus feature, which is that morphing handles can actually have two modes of operation. One is Direct mode, where the handle is dragged around linearly, and its position along its range of motion directly defines the value of the tweak it controls. Kind of like a fader potentiometer, if you're into electronics.
The other mode is called Relative mode. All it does is, instead of setting the value of the tweak directly, it uses the handle value as an offset to gradually increment or decrement the tweak itself. Think of using a gamepad to move an on-screen cursor, compared to using a mouse. That's the difference of relative and direct control.
The cool thing is that because the handles are tied to the mesh, and moving the handle also moves the mesh, what this does is that when everything is set up right, it creates a sort of spring-like behaviour, where the displaced handle causes the mesh to move towards the handle, which in turn causes the handle to return to its neutral position. Basically the neutral point 'catches up' to the handle. This allows the handles to control part morphing with a very high degree of control, and gives us a neat smooth transition effect as a bonus (smoothly transitioning things are always a good thing in any game).
If you've made it this far, congrats! As you can tell, I tend to get carried away when talking about this stuff, but hopefully you now have a better understanding of how this part of Balsa's internal workings operate. If you want to get into mod making, hopefully this is also useful information on how to use the mesh tracking modules in your own creations.
So thanks for reading, and see you on the next dev post!
Balsa Model Flight Simulator - Irregular Corporation
Hi,
So summerâs come and gone now, and everyone is asking for an update on when Balsa is going to launch into Early Access, so I wanted to share with everyone the latest news on the development.
As you know we've had a good deal of great feedback coming in the past few months, from both the Steam demo and from the closed Beta testing groups, and that's been the main focus of our work the last couple of months.
However, as we plowed through bugs and feature requests, we realized that there are still significant areas of the game that are in real need of being developed further, to the point that if we were to release the game as it is, we run the risk of it not coming across the way it should.
You can compare that to looking at an unfinished painting, and later finding that the objects in the background are not the ones you imagined they would be. We tend to fill in the gaps when we look at unfinished things, and although one can argue that is the nature of Early Access, it's still important to make sure that your core ideas are getting through.
So what do I mean by this? Well, essentially, that we still have some work ahead of us before Balsa can hit Early Access.
We are a VERY small team here. As in, we are a total of two people. Itâs just been Drake and myself working on Balsa all this time, and although being a tiny team gives you a lot of freedom to make decisions quickly and stay on your feet, it also means our work output is, well, limited. Thereâs only so much two people can do in any amount of time.
And there is quite a lot that we want to do. We have planned a very significant revision of the Career Mode part of the game, as well as considerable improvements to basic usability and early user experience.
I actually want to share those plans in more detail, but rather than make this post into a full essay, we can do better. We are setting up periodic Development Updates from now on, in which youâll get the latest on where we are in development, what our current ideas and challenges are, as well as some behind the scene (screen?) content.
In terms of the release date, we are now targeting early 2021 to hit Early Access. This extended development schedule gives us the extra time we need to get all our planned features and revisions in, and as we get closer to release, we have also planned a second round of Beta Testing. Weâll share more details on that later, as we approach that stage.
For now, we are jumping right back into development, and as usual, Iâll be talking about that in detail over on our Discord server, so you can join us there for an almost daily nerd-out session with me.
I want to give my deepest thanks to everybody whoâs been following the development of Balsa, and eagerly anticipating the release.
Balsa Model Flight Simulator - Irregular Corporation
Hey folks!
We will be hosting a livestream with @HarvesteR tomorrow, August 20th, showing off the beta and taking on some of our internal team at The Irregular Corporation in a dogfight!
Balsa Model Flight Simulator - Irregular Corporation
Hey everyone!
Our Balsa Model Flight Sim free demo has now gone live for the duration of the Steam Festival (June 16th - 22nd). We are super excited for you all to get hands on with this demo and let us know what you think!
Not only this but we will be hosting a video showcasing the demo and some of the cool features of Balsa on Thursday 18th June at 4pm BST! đș
In this video lead developer Felipe âHarvesteRâ Falanghe will be showing off how to build a vehicle from scratch, various editor features, and the aerodynamics overlay before taking it out for a test flight and much more! This will in turn be followed by Felipe answering some of the community's burning questions.
Note: as this is a pre-recorded video Felipe will be hanging out in the Balsa Discord when the stream goes live to answer any questions you have, chat with him here!
Want to know what is featured in the demo? Well we have a handy list for you here:
In-game Vehicle Editor - Build anything you can imagine using parts that snap together in a hands-on, intuitive way.
A physics-based flight model, ensures your designs behave realistically as they fly (and crash).
Single-player Free-Flight Mode - Hone your skills or enjoy a relaxed flying experience in the Demo Free Flight Sandbox Mode.
Fully Explorable World - Discover beautiful Wirraway Bay from the air or on foot. Switch to Pilot controls to freely walk around the map, FPS-style. You can also pick up and hand-launch your vehicles from wherever you are.
No time limits, unlimited vehicle designs - There are no time or saving restrictions in the demo. You're free to play for as long as you want, and create as many designs as you can imagine.
Build Areas around the world - No need to leave the flight to edit your creations. Around Wirraway Bay, you'll find Build Tents where you can tweak and rebuild just as if you were back at your workshop.
Civilian NPC Vehicles - You're not alone in the Balsa Free Flight demo. Look around, and you just might find other AI-controlled aircraft flying around as well.
Steam Workshop Support - Share your creations made in the demo with other players through the Steam Workshop, publish, browse and subscribe to workshop content directly from the game.
You can head over to our Steam page here and give us feedback or just spend time discussing the demo.
Weâll see you in the workshop and (hopefully) in the skies!
Balsa Model Flight Simulator - Irregular Corporation
Balsa Demo covers the essentials of Balsa Model Flight Simulator; a detailed model flight sim with a powerful editor where you can design, build, fly and battle with model aircraft. Developed by the creator of Kerbal Space Program, Balsa is a virtual flight experience like no other.
Please note: Our live streamed video will be pre-recorded footage of the demo, you will be able to chat live with Felipe during the stream on our Discord page here.
Balsa Model Flight Simulator - Irregular Corporation
Update: We have now hit capacity for the beta and have closed the sign-up form. Thank you so much for helping us hit this so quickly! We'll have more news about the date/time very soon so stay tuned :)
Weâve got some very exciting news to share with you about Balsa today! We have had our heads down and weâve been working hard on development. We are now ready to open up the sign-up page for folk to join the closed beta weâll be hosting later in the year.
If youâre new to Balsa Model Flight Simulator, developer Felipe âHarvesteRâ Falanghe has put together an awesome introduction video which shows you the basics of building your first model and how to make it fly successfully...and sometimes not so successfullyâŠ
Please note: This is a closed beta and we have a limited number of slots available - this will be first come first serve. Once weâve hit the maximum amount of sign-ups we will close the form. Do not be disheartened if you do not make it into the beta we have much more exciting Balsa news coming as well!
If youâre looking for other ways to hear about Balsa news you can follow us on Discord, Twitter and add to your Steam wishlist today!