Ruby Koans and Puzzle Design
How a Ruby
course and
great
puzzle
games build
complexity
through
layered
discoveries
diegobit
11 Aug 2025
How a Ruby course and great puzzle games build complexity through layered discoveries
DHH talks about Ruby like a language you write poems in, beautifully designed for ergonomics. He recalls the epiphany he had when first encountering its metaprogramming... so I finally decided to try it.
The philosophy of Ruby
At first, I was just intrigued by how Ruby users seem to revere it. I don't recall anyone calling Javascript, Python, or Java beautiful – maybe only esoteric languages inspire that kind of devotion? But with Ruby, it's common to hear discussions about "programmer's happiness", "elegance", "the Ruby way", everything sprinkled with metaphors. Let's see a few examples.
From the creator's own words, Yukihiro "Matz" Matsumoto:
Language is kind of a scaffolding of the mind, a way of structuring your thinking. [...] I think a programming language should have a philosophy of helping our thinking, and so Ruby’s focus is on productivity and the joy of programming. Other programming languages, for example, focus instead on simplicity, performance, or something like that. Each programming language has a different philosophy and design. If you feel comfortable with Ruby’s philosophy, that means Ruby is your language.
This is written in the library of RubyLLM:
One beautiful API for everything. One consistent format. Minimal dependencies [...] Because working with AI should be a joy, not a chore.
Or in the words of DHH in the Rails Doctrine:
I’m not exaggerating when I say that Ruby transformed me and set the course for my life’s work. So deep was the revelation. It imbued me with a calling to do missionary work in service of Matz’s creation. To help spread this profound creation and its benefits.
Ruby Koans
Looking for a tutorial, I stumbled upon The Koans: every exercise is a "koan", a test case you must fix to progress. Everything wrapped in this narrative:
The Koans walk you along the path to enlightenment in order to learn Ruby. [...] We also teach you culture. Testing is not just something we pay lip service to, but something we live. [...]
$ ruby path_to_enlightenment.rb
Thinking AboutAsserts
test_assert_truth has damaged your karma.
You have not yet reached enlightenment ...
<false> is not true.
Please meditate on the following code:
./about_asserts.rb:10:in `test_assert_truth`
path_to_enlightenment.rb:27
mountains are merely mountains
Learning Ruby this way felt perfectly aligned with the language's philosophy. Online, some people didn't like the fact that they could be stuck guessing the solution of the current koan, until forced to look online or ask an LLM for help. I actually prefer this over reading a guide that hands me over everything: a more active and engaging way to learn, with targeted exercises shaped by a philosophy. So I set out on the path.
These are some of the very first koans of the course:
class AboutAsserts < Neo::Koan
# We shall contemplate truth by testing reality, via asserts.
def test_assert_truth
assert false # This should be true
end
# Enlightenment may be more easily achieved with appropriate
# messages.
def test_assert_with_message
assert false, "This should be true -- Please fix this"
end
# Sometimes we will ask you to fill in the values
def test_fill_in_values
assert_equal __, 1 + 1
end
# To understand reality, we must compare our expectations against
# reality.
def test_assert_equality
expected_value = __
actual_value = 1 + 1
assert expected_value == actual_value
end
test_assert_truth
introduces us to the world of test cases and asserts: false is not true. test_assert_with_message
teaches us that a string is truthy. test_fill_in_values
shows us the basic way of a test to communicate. test_assert_equality
how knowledge about the world is formed.
What fascinates me is that every koan is both an idea in the language and a precise puzzle, the minimally perfect puzzle. You are not merely told "look, in Ruby you can do this and that", but you have to try and understand it to get to the solution. This is exactly the philosophy of puzzle design that I love. There are three key differences with regular exercises: the design that went into shaping the puzzle to its core idea, the progressive nature of "the path", and the narrative built around it. Both remind me of puzzle videogames.
Puzzles and ideas
Many puzzle games teach you a concept at the beginning, telling you the rules, then give you more difficult puzzles where the idea is always the same, just made it harder by an intentionally confusing environment, or the necessity to do many steps. Then there's a handful of other puzzle games in which the path is exactly the one of "The Koans". In the videogame design language, they call them "systemic games", or "games with emergent gameplay". I think the term got really famous with Breath of the Wild, because of the physics and chemistry rules you can use to solve problems in novel ways, but let's focus on puzzle games.
In a systemic puzzle game, the author creates a system of rules that govern the world, then make a series of levels that teach you progressively more complex ideas within that system. In the best examples, each level is the smallest, the purest expression of an idea. The challenge is never in the execution, in the number of steps to solve the level, or in more complicated rules, but in the lack of knowledge, and the reward is the discovery of something unknown. The intended experience is this discovery, the increase of comprehension. The game guides you into composing its ideas into higher level ones, into abstractions, and then, composing those into higher ones. Each level, as simple as any other.
Not many games follow this principles. Among the ones that do, I can think of Baba is You by Arvi Teikari; the games made by Zachtronics; Stephen Sausage Roll by Stephen Lavelle; then there's The Witness, by Jonathan Blow. In his (great) talk Video Games and the Future of Education, he says how every puzzle is unique and important:
(clickable image to youtube timestamp. You can stop at 41:33. Or read the transcription)
Here in this picture we see these puzzles in a solved state but normally you would walk up to this row of panels and just the left one would be lit and the rest of them would be unlit, and you solve it and it lights up the next one. [...] As soon as you solve this first panel, a magical moment of non-linguistic communication happens, [...] it's not just that you gain a logical fact that this particular path on this particular puzzle resulted in a solution state of true — that is not the only thing that happens. Because the layout of this puzzle, the way that it's formatted, tells you something. [...] As the player you don't exactly know what any of that means, but we manage to build upon it.
And so in this second puzzle it's saying an idea that adds on to the first one: it's saying, you don't necessarily have to start in the middle and go straight between; you could start in one corner and go to the other corner. [...] And so the way that I think about the game is that every puzzle has an idea like this.
Another example is Outer Wilds by Mobius Digital. The world of the game is a solar system; you have a spaceship and you can go anywhere, but the sun explodes every 21 minutes and the game resets. There are almost no "actions" you can do: the "system" is only in part a rule-based one, but mostly it's a narrative one: the entire gameplay is to travel through space, read messages from an ancient extinct species, learn things about them. The game takes 10/30 hours to finish, but the last run takes only 10 minutes, as soon as you know where to go and what to do. It's the embodiment of the idea "I'd like to wipe my memory to play it again": if you discovered everything once, there's nothing else to learn, you just start the game and finish it in 10 minutes.
Back to Ruby
Anyway, I love these kinds of puzzle games, and I'm loving Ruby Koans. Why should I follow a verbose written guide, when I can have this instead:
def test_method_names_become_symbols
symbols_as_strings = Symbol.all_symbols.map { |x| x.to_s }
assert_equal __, symbols_as_strings.include?("test_method_names_become_symbols")
end
Isn't this a great way to learn (a programming language)?
Thanks for reading! If you want to dive deeper, I suggest you watch:
- The full talk of Jonathan Blow.
- This video about knowledge based games by The Game Overanalyzer.