Writing a Ray Tracer in Brainfuck: An Extreme Programming Experiment

Someone built a ray tracer in Brainfuck — an 8-instruction language — proving Turing completeness and exploring the limits of computation.
Brainfuck is an esoteric programming language with only eight instruction symbols that operates on a memory tape, designed almost to torment programmers. Yet someone used it to implement a ray tracer — a rendering algorithm that relies heavily on floating-point math, vector operations, and complex geometry. Since Brainfuck natively supports only byte-level integers, the author had to hand-build an entire math system from scratch, including multiplication, division, fixed-point representation, and square root approximation. The project has no practical engineering value; its significance lies in pushing Turing completeness to its extreme and forcing developers to deeply understand computation beneath the abstraction layers — a unique form of geek expression, much like rendering 3D graphics in Excel or building a CPU in Minecraft.
When Extreme Programming Meets Computer Graphics
In the world of programming languages, Brainfuck is something close to performance art. It has only eight instruction symbols, no variable names, no functions, and essentially zero readability. Yet someone has used this language — deliberately designed to "torture" programmers — to implement a ray tracer: a graphics rendering program that typically demands floating-point arithmetic, vector mathematics, and complex geometric calculations.
The project recently sparked discussion on Hacker News. While the community response was modest (14 points, 3 comments), the hacker spirit and technical challenge it represents are well worth exploring in depth.
Why This Is a "Crazy" Undertaking
Just How Bare-Bones Is Brainfuck?
Brainfuck was designed by Urban Müller, and the entire language consists of just eight characters: > < + - . , [ ]. It operates on a memory tape, accomplishing all computation by moving a pointer and incrementing or decrementing byte values. It is Turing complete — theoretically capable of computing anything computable — but there is a vast gulf between "theoretically possible" and "actually writable."
In this language, even a simple addition requires carefully choreographed instructions, let alone the operations that ray tracing depends on.
To get a feel for just how tedious Brainfuck is, consider the simplest example: printing the letter "A" (ASCII code 65) requires first accumulating the value 65 in the current memory cell through loops, then outputting it with . — a process that takes roughly a dozen instructions. In C, putchar('A'); does the job. Brainfuck's Turing completeness comes from its simulation of a minimal-instruction-set Turing machine — in theory, any algorithm can be implemented with these eight instructions, but the instruction count explodes exponentially. One of Müller's original goals was to create a Turing-complete language that could be implemented with the smallest possible compiler: the original Brainfuck compiler was just 240 bytes. This minimalist design makes it a classic case study in theoretical computer science for demonstrating the minimum requirements for Turing completeness, rather than any practical tool.
The Computational Burden of Ray Tracing
The core of ray tracing is simulating how light rays propagate through a scene: casting rays from a camera, intersecting them with objects in the scene, computing reflections, refractions, and shadows, and ultimately determining the color of each pixel. This process typically involves extensive floating-point operations — vector dot products, square roots, normalization, and more.
The problem is that Brainfuck natively supports only byte-level integer operations. To perform floating-point or high-precision fixed-point arithmetic, the author had to build an entire math library from scratch by hand: multiplication, division, square roots — all assembled from the most basic additions, subtractions, and loops. That is where the real technical challenge of this project lies.
Ray tracing is a rendering technique based on physical optics, with a complete recursive algorithmic framework proposed by Turner Whitted in 1980. Its core idea is reverse tracing — starting from the camera's viewpoint, casting a "primary ray" toward each pixel, and then recursively generating reflection rays, refraction rays, or shadow-detection rays after intersecting with scene objects, until the ray exits the scene or the recursion depth limit is reached. Computing each ray's intersection typically involves solving quadratic equations (for spheres) or systems of linear equations (for triangle meshes), while determining the final color requires computing normal vectors, normalization, dot products, and other vector operations. The dedicated RT Core hardware acceleration units in modern GPUs (such as the BVH traversal units introduced in NVIDIA's Turing architecture) were specifically designed to offload these high-frequency floating-point operations. In Brainfuck, even integer division must be simulated with repeated subtraction loops — which gives some sense of the enormous engineering effort required to build this entire mathematical system incrementally.
The Technical Highlights of This Project
Building a Mathematical Infrastructure by Hand
To implement ray tracing in Brainfuck, the author essentially had to first construct a "virtual machine"-style arithmetic system. Fixed-point number representation, multi-byte large-number arithmetic, approximation algorithms for trigonometric functions and square roots — things that take a single line of code in a high-level language all require dozens or hundreds of carefully arranged instructions here.
This kind of work is closer to designing a computer than to writing a program.
Pushing Readability and Maintainability to Their Limits
Brainfuck code is a stream of symbols with no discernible semantics. For a logically complex program like a ray tracer, writing it directly by hand is nearly impossible. The process typically requires higher-level abstractions — for instance, first writing macros, templates, or some kind of transpiler to generate Brainfuck code, then debugging it. A significant part of the project's value lies in these "engineering" techniques.
In practice, most complex Brainfuck programs are not written by hand at all, but instead produced through a "metaprogramming" path: the developer first designs a macro assembly language or intermediate language, writes a transpiler to compile it into Brainfuck, and then debugs the generated output. This closely mirrors how early computer programmers wrote code in assembly language and had it converted to machine code by an assembler. Debugging Brainfuck programs is itself an art: because there is no symbolic semantics whatsoever, developers typically need dedicated Brainfuck debuggers to step through and track the state of every byte on the memory tape. This approach of "writing a compiler for one language to write programs in another" is itself a core practice in compiler design and language implementation, making the project's engineering methodology as valuable as its computational result.
What Is the Point of Projects Like This?
Some might ask: what is the point of going to all this trouble to write a ray tracer in Brainfuck?
The answer is that its "uselessness" is precisely its value. Projects like this are a programmer's ultimate homage to Turing completeness — an empirical demonstration of the proposition that "any Turing-complete language can compute anything." They force the author to fully internalize the most fundamental concepts in computer science, from numerical representation to algorithm implementation.
This is also a unique form of expression within programming culture. Just as some people render 3D graphics in Excel or build CPUs inside Minecraft, these seemingly absurd creations often inspire more people to understand the essence of computation. They remind us that beneath all the abstraction layers, all software ultimately reduces to combinations of the most basic operations.
Final Thoughts
From a practical engineering standpoint, writing a ray tracer in Brainfuck serves no purpose whatsoever. But from the perspective of exploring limits and honing craft, it is a remarkable achievement. It demonstrates just how far a programmer can go under severely constrained conditions, and invites us to reconsider the underlying complexity that high-level languages hide from us.
For developers who want to deeply understand how computers work, studying the source code and implementation approach of extreme projects like this may be more illuminating than reading ten textbooks.
Related articles

Chain of Thought Isn't Just for AI: How Humans Can Use CoT to Improve Thinking Quality
Chain of Thought isn't just a prompt trick for large models. Starting from a Hacker News discussion, this article analyzes why CoT works for human thinking too, breaks down actionable ways to transfer it, and highlights the key differences between human CoT and machine CoT.
Cloudflare Teams Up with OpenAI: Closi…
Cloudflare Teams Up with OpenAI: Closing the Loop from Vulnerability Discovery to Defense with AI
Cloudflare uses OpenAI Daybreak to investigate security vulnerabilities and generate reviewable remediation plans, while developers use Codex to boost coding efficiency and quality.

Orca Multi-Agent Orchestration in Practice: A Guide to Parallel Collaboration with Claude and Codex
Orca is Stable AI's free open-source agent workbench supporting 34 agents like Claude Code and Codex in parallel. Learn its Git worktree isolation, multi-model orchestration, and mobile management.