Play me at http://bit.ly/playnamba.
Source code is available at http://www.github.com/holdenlee/Namba. This is the minimal playable version (v0.1) – leave me some comments so I can make the next version better.
Detailed instructions (plus thoughts on making the game, and directions to go from here) follow. But see if you can figure it out by yourself first.
If you get a score >10, let me know in the comments:)
Move Pete (the penguin) by using the LEFT and RIGHT arrow keys (note the field wraps around). Press UP to pick up a block and DOWN to drop the block Pete is currently holding.
The goal is to make the numbers on the right-hand stack, top one first. If the stack overflows, you lose.
Your raw ingredients are the numbers on the left-hand stack. Press SPACE to drop the topmost block from that stack at the current position.
You have an unlimited supply of +, -, *, and / blocks. Press 1, 2, 3, 4, respectively, to drop those blocks.
Operations (functions) must be activated in order to act on blocks. They act on the numbers below them, so if you drop an activated “+” on blocks 3, 4, then the blocks turn into 7. To activate a block, press SHIFT in addition to what you’d normally press (DOWN, 1, 2, 3, 4, or SPACE). (Note that in this version there is no reason to press 1, 2, 3, 4 without pressing SHIFT.) The “copy” block will copy the block below it, and the “clear” block clears the whole stack. They are activated with SHIFT as well.
Once you make the topmost number on the RHS, you get a point. The speed at which the blocks come will increase.
Note that currying happens. If you drop an activated “+” on a single number, say 2, you get (+2). You can then pick up this block, activate it, and drop it on another number. How is this useful?
I wanted to make a game with a “programming” flavor to it. Stack programming seems the most concrete and game-able (and there are lots of games involving stacks, ex. stacks of colored blocks you move around to match colors), and numbers are the natural objects to make. (Though this is the inspiration it’s not clear to me that the game teaches anything about programming at all.)
When I first made the game, operation blocks came randomly with the numbers, and moreover the blocks bubbled up from the bottom of the stacks rather than coming on a separate stack. This turned out to be a very bad idea – there was no way to access the new blocks coming in, and it was too hard to make anything when the operations were random. Hence I made operations free, and new blocks come in separately.
(Note: Namba comes from Number + Lambda.)
I wrote Namba using Elm, a functional reactive programming language. Elm has all the advantages of a typical functional programming language (clean, pure, runtime error-free), and additionally makes it easy to deal with input as “signals” (hence the “reactive” part).
I’ve been playing with Elm for the past year though this is the first original game I’ve coded up. (I taught a class on Elm for Princeton Splash. See my lecture notes and examples, including a Snake clone.)
Elm code is modular, as long as one follows the “Model-update-view-(signal)” paradigm. (Basic template here.) This also tends the make the logic transparent. I can focus on the logic, because Elm does all the heavy “lift”ing with the signals.
The most involved part was creating a “typing” system. Every block has a “type” associated with it, for example, each operation is Int -> Int -> Int, and when an activated block is put on another one, the program matches the “types”, computes the “type” of the resulting block, and evaluate the expression if the “type” an Int. Since the only types that come up in this version are Int, Int -> Int, and Int -> Int -> Int, this is overkill, but it’ll be easy to extend when I put in more complicated blocks.
Here are the core parts of the model, update, view, and signal components for Namba:
The model is just all the information about the current state of the game in one place:
Update encodes the core logic: how the state changes upon various inputs (activate block, go left, go right, drop, pickup, use a “spell” (i.e., an operation +, -, *, /), drop a block from the incoming stack, or the passage of time). (I actually need a function “step : Input -> Model -> Model”, but this is not hard to make from stepGame. Basically, step builds on stepGame by saying how to start/end the game. The template is basically this.)
For the view part, I don’t have to do anything using absolute coordinates. Aside from putting things in containers for consistent spacing, I just have to specify how to put the different components relative to one another. Once I’ve written renderBlock, I can renderStack simply by “mapping” renderBlock over the list of blocks and “flow”ing down, and then “flow” right to make renderStacks. The whole display comes from putting together the display from left to right, of (1) the inputs, (2) the top panel above the stacks, (3) the stack of integers to make, and (4) the score panel.
Finally, the signal part says how to convert key presses into the types of inputs you see above.
Here are some directions I’m thinking of going from here. Ideas are welcome.
- Zen mode – puzzle mode, where you have a limited number of pre-set blocks and you try to make the given numbers. (Think of this as an extension of Numbo, the game where you try to make a certain number from using a given set of numbers and the basic operations.)
- Make different levels. At the end of each level there are bonuses for various things (ex. for “laziness”, if you have few total moves).
- Buy new functions (“spells”) that can be used using keys 5-0. More of these slots open up later in the game. The functions can have various “speeds” – how often you can use them. I want to include some “higher-order” functions – the problem is how to make these functions useful, and not make the game too complicated. In order for these functions to be useful, I could make the new integers not completely random, but obey some patterns…