Gamelang is an esoteric programming language in which programs are written as two-dimensional platformer levels. A virtual player character navigates the level under the influence of gravity and directional tiles, and the tiles it lands on or walks through determine what the program does. The language was designed as a curiosity: can a Mario-style level layout constitute a working program?
Overview
A Gamelang program is a plain-text file where each character in the two-dimensional grid is either a platform, a tile with semantic meaning, or empty space. Execution is driven by a single "player" entity that obeys simplified platformer physics:
- The player falls downward each tick unless the tile directly below is a platform (
# or =).
- The player moves horizontally according to its current direction (initially stationary).
- When the player occupies a tile, that tile's effect is applied.
The interpreter maintains the following state:
| Variable |
Description
|
| coins |
The primary integer register. Starts at 0.
|
| remembered_num |
A secondary integer register. Starts at 0.
|
| output |
An accumulation string that can be printed or cleared.
|
| pointer |
An index into the output string.
|
| big |
A boolean flag. Starts as false.
|
Tile Reference
Platforms
| Tile |
Effect
|
# |
Solid platform. Blocks the player from passing through vertically.
|
= |
Solid platform (same as #).
|
Movement
| Tile |
Effect
|
> |
Set horizontal direction to right.
|
< |
Set horizontal direction to left.
|
Λ / ʌ / ~ |
Jump: move the player up two rows on the next tick.
|
v / V |
Drop: move the player down two rows immediately, passing through platforms.
|
! |
Stop horizontal movement (set direction to 0).
|
|
Wall: reverse the player's last horizontal step (push back one tile).
|
A |
Elevator up: move the player upward until a # tile is found above, then land one row above it.
|
a |
Elevator down: move the player downward until a # tile is found below, then land one row below it.
|
Coins (primary register)
| Tile |
Effect
|
o (lowercase) |
Collect coin: increment coins by 1. The tile is replaced with a space (consumed).
|
O (uppercase) |
Collect coin: increment coins by 1. The tile is replaced with lowercase o (reusable once).
|
I |
Increment coins by 1 (without consuming a tile).
|
D |
Decrement coins by 1.
|
Remembered number (secondary register)
| Tile |
Effect
|
i |
Increment remembered_num by 1.
|
d |
Decrement remembered_num by 1.
|
r |
Remember: copy coins into remembered_num.
|
R |
Recall: copy remembered_num into coins.
|
w |
Swap: exchange the values of coins and remembered_num.
|
Input
| Tile |
Effect
|
, |
Read a single character from the user; store its ASCII value in remembered_num.
|
; |
Read an integer from the user; store it in remembered_num. Loops until valid input is given.
|
Output
| Tile |
Effect
|
. |
Append the character whose ASCII value is coins mod 256 to output.
|
: |
Append the decimal representation of coins to output.
|
s / S |
Print output to stdout (say).
|
p |
Print the single character at output[pointer] to stdout.
|
P |
Print all characters from output[pointer] to the end of output, advancing the pointer each time.
|
l |
Clear output (cLs).
|
W |
Reverse the string in output.
|
Pointer
| Tile |
Effect
|
1 |
Increment pointer by 1.
|
0 |
Decrement pointer by 1.
|
Timing
| Tile |
Effect
|
t |
Wait 0.5 seconds.
|
T |
Wait remembered_num / 10 seconds.
|
Conditionals
| Tile |
Effect
|
c |
If remembered_num > 0, skip the next two tiles in the current horizontal direction.
|
C |
If coins ≠ remembered_num, skip the next two tiles.
|
b |
If the big flag is true, skip the next two tiles.
|
All skip operations also call apply_landed_tile on the destination, so the tile landed on after the skip is immediately processed.
Big flag
| Tile |
Effect
|
+ |
Set the big flag to true.
|
- |
Set the big flag to false.
|
Termination
| Tile |
Effect
|
e / E |
End the program normally (prints total coins collected).
|
x / X |
Kill the player (prints total coins collected and exits).
|
Out-of-bounds
If the player walks off the edge of the level (any coordinate outside the grid), the tile is treated as x, triggering player death.
Examples
Reads one character and echoes it back.
>,w.se
=======
- The player walks right, reads a character into remembered_num (
,), swaps it into coins (w), appends the character to output (.), prints output (s), then reaches the end (e).
Reads a digit. If it is not 0, prints it forever; if it is 0, prints it once and exits.
>o; Cv R:se
==========#=========
>>>>:s<
====================
- The player collects one coin (
o), reads a number into remembered_num (;), then checks whether coins ≠ remembered_num (C). If they differ (input was not 1), the player drops (v) to the lower platform, which loops printing coins forever. If they are equal (input was 1), the player continues: R recalls the input into coins, : appends it to output, s prints it, and e exits.
Counts down from 99 to 0, printing each number on its own line.
>IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIv
====================================================================================================#
> w :slDTwcev w iii <
#============#======================================================================================#
A <<
===============
e <<<<<
========######==
- The first row loads 99 into remembered_num via 99 consecutive
I tiles, then drops (v) into the main loop. Each loop iteration: swaps remembered_num into coins (w), appends the number (:), prints it (s), clears output (l), decrements coins (D), waits (T), swaps back (w), and checks whether remembered_num > 0 (c). When true the player drops via v to the elevator platform, rides the elevator (A) back up to the loop start. When remembered_num reaches 0 the check fails and the player hits e, ending the program.
Produces Hello, World! by carefully manipulating the coins register to the ASCII value of each character in sequence.
<|
> iiiiiiiiiv <|
===========# <|
>>>d IIII IIII c~< . v <| Output: "Hello, World!"
==============================# <|
<|
<|
vv . DD>~c IIIIIId<iiiii <<< <|
==========##==========================================
>>>> IIIIIII .. III. R iiiiiiii>dIIIIIc~< III. vVv
========================================================###==#
> <|
vv ii. idid >~cdIIIIIIIIIII <iiii . DDDDDDDDDDDD <|
====##=======================================================|
>>>dIIIIIIIIIIIc~< DDDDDDDD. III. DDDDDD.DDDDDDDD.Rvvv
=========================================================###=#
Print>> es. IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII <|
=============================================================#
last Bit Done (33='!')
Computational class
The computational class of Gamelang has not been formally established. The language has a single unbounded integer register (coins), a secondary integer register, and the ability to loop using elevator/direction tiles. Whether this is sufficient for Turing completeness remains an open question.
Interpreter
The reference interpreter is written in Python and is invoked as:
python main.py <file.gamelang>
To enable a step-by-step debug view (showing player position, current tile, and register values after each tick), set the slowness variable at the top of main.py to a value greater than 0.4.
See also
- Befunge — another two-dimensional esoteric language.
- Piet — a language whose programs are images.
External resources
- (Reference interpreter source — link TBD)