Here’s a dev diary vid showing the results of my work over the last few months!
Playable build – updated
Fixed update optimisations
Now that I’ve had to reduce the physics update time-step, any code in my fixed update functions is much more performance critical. So this week I tried optimising as much of it as I could. Unfortunately there weren’t really any places I could move update code out of the fixed update altogether, but I did manage to speed up a few things.
I’ll probably have to revisit fixed update performance at some point, but for now I’m gonna move onto the next thing. Next up I think I’ll look at reworking the system that determines how parts can attach together, to make it more flexible and allow for more interesting part pairing relationships. This’ll be required for some of the new parts I want to add in the future.
Playable build – updated
Another physics problem
A few weeks ago I noticed an odd physics bug in the game, where if part of a construction was rapidly rotating around one particular axis, that rotation would be massively slowed if the construction as a whole was also rotating about another, perpendicular axis. For example, a rapidly spinning axle (acting as a drive-shaft) running longitudinally in a car would be almost completely stopped if the car yawed or pitched (say when steering or coming off a jump).
There is a gyroscopic effect that applies to a rapidly spinning object, where if you try and rotate it about a second axis perpendicular to its spin axis, it will want to rotate about about a third axis perpendicular to both. Similarly, if you prevent it rotating about one perpendicular axis, it will resist rotation about the other. This happens in game physics, just as it does in the real world (it’s what keeps bicycles up!) In Unity’s physics (PhysX 2.83) when this resistance to rotation is counteracted by the hinge constraints holding the object’s rigidbody in place, it’s as if a large torque gets applied that dramatically reduces the rigidbody’s angular velocity about its spin axis. I’m no expert on the physics of gyros, it’s possible that this is a real world effect that is just exaggerated in PhysX – but regardless it didn’t feel correct to me and could completely screw up a construction’s behaviour in the game.
I did some tests using other physics engines – a later version of PhysX (3.3) and Bullet. I reproduced the same issue in both, so I’m assuming it’s a common behaviour among most, if not all, physics engines, and that porting over to a different one isn’t going to help me.
Hack and slash
I tried hacking around the problem by overriding the mass and inertia tensor of a rapidly spinning rigidbody, but to no avail. I tried adding an “artificial” torque to counteract the slowing down effect on the spinning rigidbody, but that just caused stability issues with the hinge constraints. It was as if all the forces were fighting each other, and something had to give!
I considered implementing a custom pseudo-physical solution specifically for drive-trains (i.e. motors, axles and gears), but this would have been a huge amount of work, it would have been very difficult to integrate nicely with the PhysX physics, and would have almost certainly limited the behaviour and physical realism of the constructions.
At this point I was really stuck. I contemplated ignoring the issue and simply living with it, but that just wasn’t acceptable to me. Another option would have been to completely remove all rapidly spinning stuff (like gears and axles) from the game, but after all the work I’ve done so far, I really didn’t want to do this. Besides, it would have hugely reduced the scope of what could be built in the game, and taken away from what I think will make it unique compared to other building / sandbox type games.
An error / performance trade-off
Fortunately I found a way out. I discovered that reducing the physics fixed update time-step minimised the problem to an acceptable level (albeit not eliminating it altogether). I believe the issue is due to mathematical error that occurs with a combination of very rapidly spinning rigidbodies and a fairly large time interval between physics updates. I can’t really lower the cap on how fast stuff can spin (not without placing undue limits on the constructions that can be built), so my only option was to update the physics more frequently with a smaller time-step. Of course this comes with a significant performance cost, but it looks like it’s a trade-off I’ll have to make.
So when you play the game now you may notice a performance slowdown (depending on the complexity of your constructions, and your computer spec). Next up, I plan to remove as much code as possible from my fixed update callbacks (these get executed at the same rate as the physics update), to try and mitigate this as much as I can!
Collision bug update 2 – fixed!
Playable build – updated
Dynamic gear engagement
The engagement between gears is now activated and deactivated dynamically. This means (as the various parts of a construction move around) gears will engage if they move close enough to each other, and disengage if they move apart. The test that checks if a pair of gears are engaged is fairly expensive, and obviously I now have to do these tests every update. So to avoid doing this between every pair of gears in a construction (i.e. O(N^2), not good), I use trigger volumes around each gear to find pairs of gears that are close to each other, and then do the engagement check only on these.
New steering wheel part
I’ve added a steering wheel part to the game that attaches to axles. It has a behaviour similar to the motor, where if “switched on” it will rotate in response to user input (i.e. the usual hold shift + directional controls).

Its obvious application is as a vehicle steering wheel, but more generally it can be used as a “control wheel” anywhere you want to rotate bits of your construction in response to user input.
Playable build – updated
New rack gear added
I’ve just added a rack gear to the game, useful for rack and pinion steering among many other things. Rack gears engage with spur gears that are positioned directly above them.

The implementation is still preliminary and still needs a bit of refactoring / cleanup, but it seems to work well so far, which is a relief. It looks like my gear physics solution is holding up!
There is one significant issue remaining with gears generally however, which applies to all gear types but is particularly highlighted by rack gears. Whenever a construction is modified (by adding or removing a part), a search is performed to find pairs of gears that are next to one another and should be considered engaged, and then a physics constraint is set up between each pair. However this is done only once, after the construction is unfrozen and things start moving about, the gear engagement pairings are not updated. Obviously this becomes a problem if the gears move apart from one another, it also won’t engage gears that start off apart, but then move together.
So I think my next big task will be to overhaul the gear engagement system so that it updates dynamically. It will need to be reliable, and not incur a big performance cost doing lots of spatial searches etc. could be tricky!


New gears now in the game
This week I’ve been working on a Python script for Blender to procedurally generate the meshes for all the various gears I need. I’ve also added support in the game for crown gears, which engage with neighbouring spur gears at 90 deg.
Next I’m gonna extend the Blender script so it can generate a rack gear mesh, and then have a go at implementing support for rack gears in the game.
Playable build – new gear physics
Playable build – new gear physics
Well, after many weeks of trial and error, experimentation and frustration, I think I finally have a solution for the gear physics! To recap, the problem with my old implementation was that it was only considering relative angular motion between the gears, and not linear motion as well. This made the gears behave incorrectly if they had any relative linear velocity.
Need for a new solution
My old gear physics implementation was inspired by the one in Box2D, so I looked there again for ideas. It turns out they work around this problem by also taking into account the angular velocity of the rigidbodies that the gears are attached to. I played around with this idea for a while but I found it didn’t really extend well to my more general 3D case.
There were also other things to consider, like supporting other types of gear such as rack and pinion. Also, the fact that my gear physics was only updated once per FixedUpdate (and not as part of the main PhysX solver update) caused lag, or “wind-up” between the gears under high torque loads. A compromise I was living with, but was never really happy about.
Using configurable joints
So I decided to throw out my old approach and instead make use of the built in PhysX constraints (or “joints”), as exposed by Unity’s ConfigurableJoint. The idea was to position the joint anchors at the current contact point between the two gears (right at the edge of the gears where they touch), and then lock the motion only along the tangent at that contact point. Then every FixedUpdate, the joint anchors are re-positioned to the current contact point (as the gears will have moved slightly). By carefully positioning the anchors like this, the gear ratio (relative torque transfer), and the relative angular and linear motion are all taken into account automatically. This approach also makes it relatively easy to add support for rack and pinion gears. And…by using built-in joints, the gear constraints are solved along with everything else, so there is minimal wind-up.

Sounds good in principle, right? However the re-positioning of the joint anchors is where things get tricky. If every fixed update, they are simply re-positioned exactly to the new contact point, the gears will gradually slip when under load. This is because a joint doesn’t perfectly rigidly lock its anchors together, and there will usually be a small difference in position between them, even after the physics solve. This error gets fed back into the new joint anchor positions and the error accumulates over time.
Correcting the joint anchors
So I tried correcting for this error by figuring out what the anchor position delta was vs. what it should have been. This is not easy because there is not really an absolute angle for a rigidbody, only an absolute position. The orientation angles of a rigidbody wrap every 360 degrees of rotation, so you’ve no idea how many of these rotations have happened since the last update. You end up having to integrate velocity over time and accumulate the positional delta as found at the contact point between the two gears. There are two problems with this. First, I found that when comparing the contact point velocities between the two gears as reported by Rigidbody.GetPointVelocity, they seemed slightly off if the gears were moving linearly relative to one another. Close, but not spot on. This small error was compounded by the second problem, which is that by accumulating the contact position delta over time, any errors also accumulate – quickly. It creates a feedback loop, the error feeds into the joint anchors, which causes the joint to pull the rigidbodies around too much, causing more positional error, which feeds into the new anchor positions in the next update, and so on. This leads to unstable physics behaviour – high impulses, oscillations, and your machines exploding like crazy.
At this point I got pretty desperate, thinking I might have to abandon gears altogether, maybe even the whole game. I even tried mocking up a solution using physics colliders (one BoxCollider for each gear tooth!), and using the collisions between the teeth to provide the gear behaviour. Er yeah – that didn’t work unsurprisingly.
Predefined anchor positions
Then I came up with the idea for the solution I have now. Re-positioning the joint anchors exactly to the gear’s contact point leads to accumulated error and gear slip. So instead, each gear is given predefined positions at equal intervals around its circumference, and every update the one closest to the current contact point is found, and that’s the position used for the joint anchor. As long as the distance between these predefined positions is greater than the distance between the joint anchors after the physics solve, you get no gear slip.

However, there is a problem with this if the gears are different sizes, as shown above. The next / previous predefined anchor positions as measured along the contact tangent don’t quite line up due to the differing radii. I tried correcting for this with a fun bit of trig, the maths worked out beautifully, but in practice it led me right back to another feedback loop, the joint and its corrected anchor positions ended up fighting each other, causing oscillations, exploding machines and much cursing. In the end I just went with a simpler approach of just upping the number of predefined anchor positions, so that any differences along the contact tangent were minimised. However, this of course means the distance between each predefined position is smaller, so increasing the chance of gears slipping under load. In practice it’s actually not too bad though, it takes quite a high torque load to cause slip (to the point where axle hinge joints are also being noticeably pulled apart).
Next steps
This whole endeavour has been very frustrating, as the ideas I tried often worked fine most of the time, only to fail in particular use cases (certain combinations of bevel gears seemed to be particularly sensitive). I spent a lot of time switching back and forth between my various approaches, trying different modifications, until homing in on what I have now. It was so time consuming as I had to do lots of testing every time I made a change to check that I hadn’t broken one of my many test cases.
Well, hopefully the implementation I ended up with will see me through. I’ve tested a lot of situations (complex gear trains, high torque loads, high rpm, etc.) but the open ended nature of this game means I might have missed a case where things go bad, let’s hope not. Next up I’m going to work on implementing rack and pinion gears, and probably worm gears too, I wanna really be sure these will actually work with no problems, before going ahead with any other part of the game.
Gear physics – a bit of a setback
I just realised it’s been ages since my last post! This is because there hasn’t been anything new in the game to speak of over the last few weeks. Unfortunately, progress on the project was completely halted when I discovered a serious flaw in my gear constraint implementation.
The problem is, it is only transferring rotational motion between gears, not linear motion. This works for static constructions with rotating gears, but as soon as the gears themselves move about, it is totally (noticeably) incorrect. If I can’t fix this, then it pretty much screws up the rest of the game as I have it planned. So I need to try and get it sorted before proceeding with anything else.
Over the last few weeks I have been digging through Box2D and Bullet code for inspiration, and have tried a few different solutions with varying degrees of success. I have one idea I’m pursuing at the moment that seems promising, but we’ll see, it may come to nothing.
The good news is, if I can fix this gear physics issue, it’ll fairly easily allow me to add rack and pinion gears (where linear motion is obviously crucial).
Honestly, I’ve been very demotivated by this setback. The game wasn’t progressing as quickly as I’d like anyway, and this really hasn’t helped. It’s been a real struggle to keep going. Hopefully I’ll figure out a solution soon, wish me luck!


