Playerlang
| Paradigm(s) | imperative |
|---|---|
| Designed by | User:Initys |
| Appeared in | 2024 |
| Computational class | Unknown |
| Major implementations | Python |
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. |
S |
Save: copy coins into remembered_num. |
L |
Load: copy remembered_num into coins. |
w |
Swap: exchange the values of coins and remembered_num. |
'<value>' |
Sets it to the number between the '. |
| Tile | Effect |
|---|---|
r |
sets remembered_num to a value between 0 and 256. |
R (if coins > 0) |
sets remembered_num to a value between 0 and coins. |
R (if coins < 0) |
sets remembered_num to a value between coins and 1. |
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. |
l |
Clear output (cLs). |
W |
Reverse the string in output. |
Pointer
| Tile | Effect |
|---|---|
b |
Increment pointer by 1. |
B |
Decrement pointer by 1. |
`<value>` |
Sets it to the number between the `. |
P |
Saves the pointers char in output in to the rememberd_num variable. |
Timing
| Tile | Effect |
|---|---|
t |
Wait 0.5 seconds. |
T |
Wait remembered_num / 10 seconds.
|
Conditionals
| Tile | Effect |
|---|---|
c |
If remembered_num > 0, skip the right command. |
C |
If coins ≠ remembered_num, skip the right command. |
? |
If the big flag is false, skip the right command. |
H |
If remembered_num > coins, skip the right command. |
h |
If remembered_num < coins, skip the right command |
Math
| Tile | Operation | Effect |
|---|---|---|
| 0 | + |
sets rem_num = rem_num + coins |
| 1 | - |
sets rem_num = rem_num - coins |
| 2 | * or x |
sets rem_num = rem_num * coins |
| 3 | / or ÷ |
sets rem_num = rem_num / coins |
| 4 | mod or modulo |
sets rem_num = rem_num % coins |
| 5 | power or exponent |
sets rem_num = rem_num**coins |
| 6 | square or square root |
sets rem_num = square(rem_num) |
Big flag
| Tile | Effect |
|---|---|
G |
Set the big flag to true. |
g |
Set the big flag to false. |
Termination
| Tile | Effect |
|---|---|
e\E / E |
End the program normally (prints total coins collected). |
x\E / 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\X, triggering player death.
Examples
Cat
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).
Hello, World!
Produces Hello, World! by using the " marks
>"Hello, World!"se ==================
Simple just move right(>) add the phrase "Hello, World!" to output say it(s) and end the program(e)
Truth-machine
Reads a digit. If it is 1 / not zero, prints it forever; if it is 0, prints it once and ends/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.
99 Coins
Counts down from 99 to 0, printing each number on its own line with some text.
>>>>> "NO more coins in the level"v
=====####==============================
>'99' >>w: " coins in the level"sl"Colect one, in your pocket " CA"only "D:I" coins in the level" slsDwica dv |
=======#=====================================================================================================================|
A <<<|
==============================================================================================================================
e <<<<<<<
===================================================================================================================########
'99' loads 99 in rememberd_num then a loop start printing "{number of coins} coinst in the level", "Colect one, in your pocket ", {"NO more coins in the level" if remeberd_num == coins(schould be zero) else "only {number_of coins} coins in the level" }" until rem_num is zero(c) when it is it goes down the the # because of the (a) and goes(<) to the end(e)
since the : prints the number of coins and not the rememberd_num we need to swap(w) the rem_num with coins every now and then
With Custom lycris by User:Aadenboy
>'99'w>>:" shiny gold coins in the room,"sl:" shiny gold coins"sl"Another one found, now look all around,"slD:" shiny gold coins in the room."slsv
======##===========================================================================================================================================
AaC <<<<
===================================================================================================================================================
>>>>"No shiny gold coins in the room,"sl"No shiny gold coins."sl"Level complete, new room to defeat,"sl"99 shiny gold coins in the room."slse
========##==========================================================================================================================================
lycris:
x shiny gold coins in the room, x shiny gold coins Another one found, now look all around, x-1 shiny gold coins in the room. ... No shiny gold coins in the room, No shiny gold coins. Level complete, new room to defeat, 99 shiny gold coins in the room.
Calculator
take a operator as a number(1=+,2=-,3=*,4=/)
>"+ = 1, - = 2, * = 3, / = 4"sl;s"pleas Enter two more numbers"sldCa o Ca o Ca o Ca "Invalid"sx =============================================================================================== plus= es:w0w " = rewsnA" ;w;<<<< ================================================================#### minus= es:w1w " = rewsnA" ;w;<<<< =====================================================================#### multeply= es:w2w " = rewsnA" ;w;<<<< ==========================================================================#### Devide= es:w3w " = rewsnA" ;w;<<<< ================================================================================####
No explaination for this one read the Playerlang#Math section again if you want
Number Guessing Game
picks a number between 0-11 and ask user until he gets it right
>>>> v aHah ls"!gnorW"ss<<<
=================================###===============================##=
>'11'w"Welcome to the Guessing Game"slRw>>>"Guess a num in 0-10"sl ; CaA
========================================##===============================
eeeee sls"!thgiR" <<<
=======================================================================##=
A ls"!rehgiH"<<<<<<
======================================================##
A ls"!rewoL"<<<<<<
====================================================##
- Exaple output:
Welcome to the Guessing Game
Guess a num in 0-10 Enter a number: 8
Wrong!
Lower!
Guess a num in 0-10
Enter a number: 4
Wrong!
Lower!
Guess a num in 0-10
Enter a number: 3
Right!
Player reached the end! Total coins collected: 3
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.
Inspired by
- MarioLANG — almost the same as this, but with less commands
- Befunge — another two-dimensional esoteric language.
- AsciiDots - also a two-dimensional esoteric language, but i like it more than Befunge.
- Piet — a language whose programs are images.
External resources
- Download: main.py
- View: dropbox.com - main.py