Video wird geladen...

Video konnte nicht geladen werden

Zur Startseite

I wrote a 2D game, entirely in type-level Typescript. Yes, you read that right. This is flappy bird, written only in Typescript types. How did I do it? It involves a lot of type magic, and a new type-level Typescript runtime I made in Rust + Zig. Let me...

625,414 Aufrufe • vor 2 Jahren •via X (Twitter)

11 Kommentare

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

First off, type-level Typescript can be thought of as a purely functional programming language, where everything is immutable. So we can't have some global game state (bird position, pipes, etc.) and mutate it What we can do is use functions to return a new, updated game state

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

So each frame, we pass the game state through a series of updates that need to happen each frame: handling jumps, applying gravity to the bird, moving the pipes. The end result looks something like this, and its a surprisingly elegant, linear, pipelining of functions:

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

The next part is rendering. I drew inspiration from modern graphics APIs and added a command buffer to the game state: basically a list of drawing commands Each frame, we update the game state, and populate the draw command buffer. In the end even rendering becomes elegant too:

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

Okay, that's the type-level logic. But in the video, the game is running in the browser, how does that work? This where some hardcore programming comes into play.

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

The basic rundown is that I created a type-level Typescript runtime, allowing types to be run outside of the Typescript compiler/language server. It's made of two parts: 1. A compiler in Rust to convert Typescript types -> bytecode 2. A custom VM in Zig to execute that bytecode

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

I then compile the runtime to Wasm, and each frame it takes the draw commands from the game and executes them using the web canvas API. And that's the basic overview of how I made flappy bird in type-level Typescript! More detail in this blog post:

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

But that's not all. By creating this runtime, I also accidentally created probably the fastest and most complete type-checker for Typescript, but types only.

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

My hope is that by focusing on nailing down type-checking type-level Typescript first, which is a way easier task than all of Typescript, the runtime can be useful very quickly. Check out the source here: And play the game here:

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

And here is the final Typescript code for the game, if you wanna check out my unholy type-level trickery. It's actually not that bad, just the moving pipe logic and the collision with pipe logic is unsightly because it needs to do iterative recursion

Profilbild von Ninja
Ninjavor 2 Jahren

You should definitely make a video about this if you haven't already

Profilbild von zack (in SF)
zack (in SF)vor 2 Jahren

great idea, probably gonna use @Remotion or @fframes_rust for making the visuals!

Ähnliche Videos