increpare
banner
increpare.bsky.social
increpare
@increpare.bsky.social
Game developer in Berlin, innit.
www.increpare.com
bsky.app/profile/incr... shell and yolk ^^
It's all about the details innit
November 11, 2025 at 3:19 PM
Counterpoint: it's top-tier comedy that counter strike disables alt+f4 to (rage)quit.
November 11, 2025 at 9:04 AM
Are you subtweeting monkey island lol
November 11, 2025 at 8:14 AM
Oh, here's my code for that file with various implementations -not really standalone but whatever gist.github.com/increpare/2c...
PlayerCamera.gd
GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
November 10, 2025 at 8:49 PM
Oeuf on Steam
3D physics-platformer where you are an egg! Roll, hop and slide your way back home.
store.steampowered.com
November 10, 2025 at 8:46 PM
Final results!

Doing a direct benchmark so we can compare the relative performance (this is over a whole run, invoking each version 500 times a second), we get this: That’s a nice > 100x speedup! Now it barely shows up at all! [25/25]
November 10, 2025 at 8:46 PM
Ideally we’d want to pick a plane so that we have similar numbers of points on both sides, but at this point we’re more than fast enough - I just want to see if this extra little step would help. And it did, a ~25% speedup. [24/x]
November 10, 2025 at 8:46 PM
Fourth optimization: find_bottom_point_radial_split
Checking signs is a really easy way to subdivide things, soI thought I’d try divide these arcs depending on whether they’re above or below the y=0 plane: [23/x]
November 10, 2025 at 8:46 PM
Now instead of 8 buckets with 82-124 vertices, we have 32 buckets with precisely 28 vertices each (you can’t see, but each spoke includes the subdivided points on both sides of it at the pointy side of the egg). [22/x]
November 10, 2025 at 8:46 PM
But we can still slice it up like a pie, and that worked really well once I got it working. This was super fast, took ~ 15% of the time of the previous optimisation. [21/x]
November 10, 2025 at 8:46 PM
Oops. I had forgotten I had subdivided the top (I think for texturing/lighting purposes). So a pure meridian subdivision doesn’t work. [20/x]
November 10, 2025 at 8:46 PM
Why not chunk things into meridians and calculate from there? I spent a while coding this, and then got very confused because the buckets were all different sizes. And then I looked at the collision model again... [19/x]
November 10, 2025 at 8:46 PM
Third optimization: find_bottom_point_radial
Looking at the egg, there is structure that we might be able to capitalise on: we have meridians! [18/x]
November 10, 2025 at 8:46 PM
The octant approach was better because it slices right through the dense areas. So to some extent my efforts to do this were a big half-assed, but I decided I just wanted a more stateless approach. [17/x]
November 10, 2025 at 8:46 PM
I wanted to avoid having to go traverse multiple neighbourhoods recursively. When I made them big enough that you would almost always find yourself in the same neighbourhood, the biggest neighbourhood was bigger than the biggest of the octants, because vertices cluster at the tip of the egg. [16/x]
November 10, 2025 at 8:46 PM
If I know that one particular point was the lowest in the last frame, it’s likely that that point or one of its neighbours will be lowest on the next frame. However I was a bit wary of this (&messed up my implementation when I tried) because it’s optimising for the best-case scenario. [15/x]
November 10, 2025 at 8:46 PM
Interlude: using state/traversals
So, having discussed it with other people I wanted to try to use the information from the previous frame to help out with the next one. [14/x]
November 10, 2025 at 8:46 PM
So, the reason I jumped to implementing octant bucketing first is that it’s super easy to check which bucket you’re in - you just have to check the signs of the various coordinates. [13/x]
November 10, 2025 at 8:46 PM
In total the egg has 738 vertices. Each of our regions has between 82 and 124 vertices, which we’re just searching through. This provided an enormous speed up - it can be executed in less than a tenth of the time of the original function! [12/x]
November 10, 2025 at 8:46 PM
So, the next speedup was to split up the egg’s vertices into eight buckets according to which sides of the XY/YZ/XZ planes space they were on: [11/x]
November 10, 2025 at 8:46 PM
Second optimization: find_bottom_point_octant

One advantage of having a shape we know in advance is that we pre-calculate stuff to speed up computation at runtime. [10/x]
November 10, 2025 at 8:46 PM
( There was some small floating-point error induced by the dot-producting, but it’s overall within my tolerances. (I will use this approach in all subsequent optimisations). ) [9/x]
November 10, 2025 at 8:46 PM
Dot products are way cheaper than full transforms. One way of thinking about this is that a transform gives you a whole vector, but a dot product is just calculating a single number. This is borne out by the speed-up, it just takes a third of the time to execute! [8/x]
November 10, 2025 at 8:46 PM