Notes
Thoughts on programming, games, and whatever else.
-
Super Mario 64's elegant collision system
2025-12-31Most resources on 3D collision are either too technical (Separating Axis Theorem, GJK algorithm) or not technical enough ("just use a physics engine"). There's a gap for the developer who wants something quick, dirty, and good enough for most games. Super Mario 64's approach fills that gap brilliantly.
Mario is a point collider. That's it!
Collision triangles are grouped into three types--floor, wall, or ceiling--determined solely by the Z component of the triangle's normal vector. Floors point up, ceilings point down, walls are everything in between.
Detection works by extending each triangle into a triangular prism along its normal. If Mario's point is inside this prism, he gets pushed out. Each triangle type uses different prism dimensions: walls extend further horizontally, floors and ceilings extend further vertically. This simulates Mario being taller than he is wide without any complex shape math.
The secret sauce: the prism detection uses the triangle's normal snapped to the nearest axis vector, not the actual normal. This prevents seams where triangles meet--imagine walking across a floor made of slightly angled triangles. Without snapping, you'd catch on edges constantly. The real normal is still used for collision resolution, so surfaces feel correct.
This approach is genius because it's dead simple. No SAT, no GJK. Just point-in-prism tests and push-out vectors. One of the best parts is that it works with arbitrary triangle soups! No need for Carmack-style brush systems like Quake required. I've implemented this in Lua and JavaScript for first-person shooters and it just works.
I also prefer this over capsule colliders, the common modern choice. Capsules have rounded bottoms that cause floaty behavior when walking off platform edges--bad for game feel in platformers. The prism method gives you hard edges where you want them.
Sometimes the 1996 solution is still the right one.
Credit to pannenkoek2012 on YouTube, whose videos go into incredible detail about Super Mario 64's inner workings.
-
Maybe stocks aren't a great investment
2025-12-03Here's a graph of the S&P 500's closing price for the last 100 years. It goes up and to the right, and since this is a logarithmic graph, the growth is dramatic. This is what long-term index fund investors point to as proof of their investing thesis.

Here's the chart of gold. Gold has also gone up over time, especially after the 1971 removal of the U.S. gold standard when the dollar became a free-floating fiat currency. It has had much longer periods of going sideways than the S&P, which has caused many to consider it a boring store of value rather than an investment.
What's interesting about gold is how stable it has been as a store of value throughout human civilization. An 8-gram Roman aureus from the 1st century BCE was worth a legionary's monthly salary and could buy 100-200 loaves of bread--roughly $500-$1,000 in today's dollars, similar to wages today.

Gold being a constant store of value throughout history is dubious, but it may be the best proxy we have besides real estate. If we assume it's roughly consistent, we can divide the S&P 500's price by gold to approximate the real value of stocks.

Viewed this way, the S&P 500 hasn't really gone up and to the right--it has gone mostly sideways. The boom and bust cycles of the U.S. economy become much more visible.
I find this perspective useful because most stock charts show nominal prices. When the news reports "The S&P made a new record high today," it's worth asking: in terms of what?
If we take this assumption seriously--that gold has remained constant while the dollar has devalued--the implications for long-term financial planning are interesting:
-
Hold gold in proportion to your risk tolerance. If stocks fluctuate around a mean, gold provides stability.
-
Buy stocks at the cheap end of the cycle. The SPX/gold ratio resembles a sine wave, so buying when it's low (and rising) could make sense.
If instead we assume dollar devaluation is guaranteed but gold isn't necessarily a perfect store of value, the strategy shifts:
-
Buy a broad basket of assets. If everything rises in nominal terms due to inflation, diversification captures that.
-
Use long-dated options (LEAPS) to go leveraged-long on inflation that markets may not fully price in.
This is not financial advice--just an interesting way to think about stock valuations.
-
-
Lisp Visualization Test
2025-10-15I recently prototyped an idea of making an interactive version of Lisp using visual blocks, inspired by Scratch (which is how I originally learned programming!).
There are two types of blocks - lists and atoms. The lists automatically lay themselves out either horizontally or vertically depending on how nested they are.

You can right-click on blocks to execute them, and defining variables makes them show up as blocks in the environment - making the environment itself editable and interactive.

Here you can see me defining a variable and a function, and then using the function to update the variable in the environment.

This project isn't live yet because I'm still working out the bugs. Hopefully soon!
-
Local LLM Optimism
2025-09-14I don't want to make costly API calls to a supercomputer, I want to run the LLM on my own machine, have it be efficient, and have it be smart, too.
Things appear to be generally moving in this direction. The new local LLMs released by OpenAI (the GPT-OSS series) are pretty good locally, even the 20B model is reasonably smart and runs well on my M4 MacBook Pro that I bought earlier this year. The time to first token still isn't perfect, but it's reasonable and the intelligence of the model is reasonable too. In my experience it can handle some non-trivial programming tasks such as writing custom MDPs in Julia given some reference documents.
My hunch is that, because the demand is there for local LLMs, we will get more tech moving in this direction. To this point I'll suggest Apple's upcoming M5 chip's upgraded neural engine as evidence.
I am optimistic that we can avoid the future where a few megacorps control the only AIs in town.
-
Iteration Time is (arguably) the Most Important Thing
2025-09-12When programming, I care about iteration time. A lot.
It affects my choice of tech stack dramatically. Maybe more than most other single consideration besides ecosystem. And, unlike ecosystem, I don't think enough developers talk about iteration time.
Iteration time is the time it takes for you to write a change to a line of code and see that change reflected in whatever you're building. When this time is low, I can flow as a developer. Stay in the flow state, never leave context. Put on some good coding music (drum and bass, anyone?) and go for hours pounding coffee. :)
When build times become a consideration, this all flies out the window. Make a change, run a compile, oops now I'm browsing Hacker News or Tiktok. There goes 15 minutes! Oh wait, what was I doing again? So much time wasted, so many context changes! Productivity tanks by like 50%.
This is part of the reason why I love scripting languages so much, or Julia with its REPL-driven development. I much prefer dealing with runtime errors or mucking up some typing issue than breaking my flow state.
Maybe you're the same way. Or maybe you just don't know it yet.
-
Everybody just wants immediate mode
2025-09-10In retained mode, you build a tree of persistent UI objects. Create a button, add it to a panel, add that to a window. When something changes, find the right object and update it. The DOM, Win32, Qt, GTK, Cocoa--all retained mode.
In immediate mode, you redraw the UI every frame as a function of state. No persistent objects. Just "if this condition, draw a button here." Dear ImGui is the canonical example.
Why care? Immediate mode makes
UI = f(state). Your UI cannot desync from your data because there is no separate UI state. An entire class of bugs becomes impossible.This is why everyone loves React. It brought immediate mode thinking to the browser--components as functions of props and state, the virtual DOM handling mutations. The browser is fundamentally retained mode, and React makes it feel like it isn't.
The endless churn of JS frameworks is developers searching for better immediate mode semantics on a retained mode platform. I don't think this framing comes up enough. When people ask "why do we need yet another JavaScript framework?" the answer is rarely framed this way. But that's the core of it.
This lens explains the 2010s. Desktop UI was "solved"--Qt, GTK, WPF all worked. Yet developers reached for Electron despite the bloat. There are many reasons: cross-platform, web talent pool, npm ecosystem. But immediate mode is underappreciated. Developers will pay a real cost to avoid retained mode. The new generation of native frameworks--Flutter, SwiftUI, Jetpack Compose--all converged on declarative, immediate-style rendering.
I love immediate mode. For technical applications, Dear ImGui is hard to beat. Your entire UI defined in one place as a function of data. No scattered callbacks or state sync bugs. Just draw what you need.
When developers add complexity to "solved" problems, ask what abstraction they're escaping. Often it's retained mode.