MineFriff
MineFriff brings the joy of traditional esolangs such as Befunge and ><> into the blocky pixelated world of Minecraft. Much like fungeoid languages, MineFriff allows code to be set out in a 2D code area, which can range from a 100*100 grid (allowing for 10,000 instructions) to any size of square (or cube).
As aforementioned, MineFriff allows for free-form code to be written in any size cube (meaning that 3D code is allowed).
MineFriff comes in three flavours: Strict, Freeform and Textual. Strict MineFriff is contained in a 100 by 100 block grid, and can be exported to a .mf
file. However, strict MineFriff is only available in the official MineFriff interpreter world. Freeform MineFriff is available in any world but is unexportable to an actual file – code is run using
/py MineFriff
Textual MineFriff is a text based ascii version of the blocky esolang, which is avaliable to everyone – all one needs is the python based MineFriff interpreter.
Concepts
Code Box
Like most fungeoidal esolangs, MineFriff has a code box in which the program is placed. In strict MineFriff, this code box is as shown:
In freeform MineFriff, this code box is essentially non-existant; programs can take any form they want and can be even 3d. In textual MineFriff, the code box spans an infinite amount of space, both vertically and horizontally.
Instruction pointer (IP)
The instruction pointer is what drives the interpreting of MineFriff programs. It starts in the top left corner of the program (strict and textual) or wherever the player is standing in freeform. It can move left, right, up, down, and in the case of freeform MineFriff, up layers and down layers. In strict MineFriff, when the IP reaches the edge of the code box, the IP “wraps around” to the other side (e.g. if it reaches the far right side, it will go to the far left side and continue). This doesn’t in happen in freeform MineFriff, as there isn’t any code box to wrap around. This functionality is being worked on for textual MineFriff.
The temporary register
Rather than having literals pushed directly onto the stack, MineFriff has a temporary register (temp reg) in which literals are constructed. This allows for any value to be created without having to worry about impacting the stack. The temp reg can be treated as either an int
eger, a char
acter or a float
.
Creating literals
To create characters and integers in MineFriff, they must be constructed using the values 0
to f
(a = 10, b = 11, c = 12, d = 13, e = 14, f = 15). By default, values are added to each other in the temp reg -- for example, ffe
will result in 44
(15 + 15 + 14). Different mathematical operations can be used (namely, */%-+
).
Interpreting modes
When pushing the value stored in the temp reg onto the stack (and recently, when getting input), it will, by default, push it as an integer. This can be changed with the C
, I
and F
The stack
The stack in MineFriff is like the stack in most other fungeoids – it can have values pushed to it, it can have stack operations performed, it can be shifted left and right – all of the usual stuff. However, when popping values from the stack, they are placed back into the temp reg (hence, overwriting the current value), rather than deleted into nowhere.
Commands
MineFriff has 33 commands:
Command | Symbol | Minecraft Block Equivalent |
---|---|---|
Move the IP left. | < | Oak Wood Planks |
Move the IP right. | > | Spruce Wood Planks |
Move the IP up. | ^ | Birch Wood Planks |
Move the IP down. | v | Jungle Wood Planks |
Print the top value on the stack. | o | Sponge |
Add a literal to the temp reg. | 0123456789abcdef | Wool (block data gives the value) |
Reverse the contents of the stack. | r | Netherrack |
Push the temp reg onto the stack and reset it to 0. | , | Piston |
Pop the top item from the stack and place it in the temp reg. | . | Sticky Piston |
Push the length of the stack onto the stack. | l | Stone |
Pop `x` and `y` off the stack. Push `y == x` back on (1 if true, 0 if false). | = | Bedrock |
Duplicate the top item of the stack. | : | Hopper |
Swap the top two items of the stack. | $ | Obsidian |
Skip the next instruction (trampoline). | # | Slime Block |
Pop the top value from the stack and skip the next instruction if it is zero (conditional trampoline). | ? | Redstone Lamp (off) |
End the program | ; | Glass Block |
Pop `x` and `y` off the stack. Push `y > x` back on (1 if true, 0 if false). | ) | Diamond Block |
Pop `x` and `y` off the stack. Push `y < x` back on (1 if true, 0 if false). | ( | Coal Block |
Pop `x` and `y` off the stack. Push `y * x` back on. | * | Podzol |
Pop `x` and `y` off the stack. Push `y / x` back on. | / | Diorite (raw) |
Pop `x` and `y` off the stack. Push `y + x` back on. | + | Andesite (raw) |
Pop `x` and `y` off the stack. Push `y - x` back on. | - | Granite (raw) |
Change the direction of the IP to a random direction. | x | Dispenser |
Go back to the start of the current line in the same direction. | ~ | Hay Block |
Go to the start of the next line. | ` | End Bricks |
Treat the temp reg as an integer. | I | Packed Ice |
Treat the temp reg as a character. | C | Birch Wood |
Treat the temp reg as a float. | F | Furnace |
Right shift the stack by 1. | ] | Dirt Block |
Left shift the stack by 1. | [ | Cobblestone |
Pop `x` and `y` off the stack. Push `y % x` back on. | % | Sand (normal) |
Start/end a comment | { } | N/A |
Delete the last item on the stack (pop it, without saving it) | ! | Not implemented yet |
Print the contents of the stack up to a certain point (determiend the last item on the stack) | p | Not implemented yet |
Examples
Hello World
Cff3,a*a,9*c,a*b4,a*b1,8*a7,ff2,ffe,a*b1,9*c,:a*a1,9*8,` >l?#;o~
Or, using the new print command - prints it reversed however.
C9*8,a*a1,9*c,:a*b1,ffe,ff2,8*a7,a*b1,a*b4,9*c,a*a,ff3,p;
Explanation (degolfed)
C9*8,` [Push the letter H (ascii value of 72) to the stack] a*a1,` [Push the letter e (ascii value of 101) to the stack] 9*c,` [Push the letter l (ascii value of 108) to the stack] :` [Duplicate the l] a*b1,` [Push the letter o (ascii value of 111) to the stack] ffe,` [Push a comma (ascii value of 44) to the stack] ff2,` [Push a space (ascii value of 32) to the stack] 8*a7,` [Push the letter w (ascii value of 87) to the stack] a*b1,` [Push the letter o (ascii value of 111) to the stack] a*b4,` [Push the letter r (ascii value of 114) to the stack] 9*c,` [Push the letter l (ascii value of 108) to the stack] a*a,` [Push the letter d (ascii value of 100) to the stack] ff3,` [Push the letter ! (ascii value of 33) to the stack] r` [Reverse the stack (not in the block version -- accidentally left out] >l?#;o~ [Push the length of the stack onto the stack, and if it is zero, end the program. Otherwise, print the top char on the stack and continue]
Fizzbuzz
0,` >I1,+:a*a1,=?;`~o,aC < >:f,%?`Ca*c2,:a*b7,7*e,a*c2,:f*7,a*7,oooooooo^ >:5,%?`Ca*c2,:a*b7,6*b,oooo ^ >:3,%?`Ca*c2,:f*7,a*7,oooo ^ >:o ^
Explanation
0,` [Push a 0 onto the stack to act as the count] >I1,+:a*a1,=?;`~o,aC < [Change the push mode to Int, increment the count by 1, and if it equals 100, stop. Otherwise, continue to the next line (~o,aC prints a newline after branching)] >:f,%?`Ca*c2,:a*b7,7*e,a*c2,:f*7,a*7,oooooooo^ [See if the count can be divded by 15 with no remainder, if so, print FizzBuzz and continue.] >:5,%?`Ca*c2,:a*b7,6*b,oooo ^ [See if the count can be divded by 5 with no remainder, if so, print Buzz and continue.] >:3,%?`Ca*c2,:f*7,a*7,oooo ^ [See if the count can be divded by 3 with no remainder, if so, print Fizz and continue.] >:o ^ [Simply print the number and continue]
99 bottles of beer
Ia*a,` >I1,-:0,=?;` ~ >Cff2,ffe,c*9,c*9,a*97,a*b9,ff2,a*a1,d*8,a*b6,ff2,a*b,a*b1,ff2,a*b4,a*a1,a*a1,e*7,ff2,a*a2,a*b1,ff2,a*b5,a*a1,c*9,a*b6,a*b6,a*b1,e*7,ff2,` >r:or` >lI1,=?`o~ >Ca,a*46,a*b4,a*a1,a*a1,e*7,ff2,a*a2,a*b1,ff2,a*b5,a*a1,c*9,a*b6,a*b6,a*b1,e*7,ff2,` >r:or` >lI1,=?`o~ >Cff2,ffe,a*a,a*b,d*9,a*b1,a*b4,a*97,ff2,a*b6,f*7,ff2,a*b5,a*b5,a*97,e*8,ff2,ffe,a*b,a*b9,a*b1,a*a,ff2,a*a1,a*b,a*b1,ff2,a*a1,a*a7,a*97,c*7,` >lI1,=?`o~ >Ca*46,c*9,c*9,a*97,a*b9,ff2,a*a1,d*8,a*b6,ff2,a*b,a*b1,ff2,a*b4,a*a1,a*a1,e*7,ff2,a*a2,a*b1,ff2,a*b5,a*a1,c*9,a*b6,a*b6,a*b1,e*7,ff2,` >r:I1,-or` >l1,=?`o~ >Ca,a,oo ^
Blocks coming soon
Deadfish Interpreter
` [MineFriff Deadfish Interpreter] 0,` [The first item in the stack will always be the accumulator] >Ca*62,a*62, oo i` [Output the interpreter prompt and then accept input] r.rI, Cffc, $` [Switch the stack around, adding a star on] v ^>r:Cffc,=?#v!~ >r:I8*8*4,= ?#v.*0,` [Check the 256 requirement] v >:I1-2,=?#~.*0,~ [Check the -1 requirement] ^ >r:Cf*7,=?#v!rI1,+~ [i(ncrement the accumulator)] ^ >:Ca*a,=?#v!rI1,-1~ [d(ecrement the accumulator)] ^ >:Ca*b1,=?#v!r:oCa,o~ [o(utput the accumulator)] ^ >:Ca*b5,=?#v!r:*~ [s(quare the accumulator)] ;
Blocks coming soon
Cat Program (take and print input)
Cip;
Blocks coming soon
External Resources
- Offical github repository -- use
main.py
for textual MineFriff andMineFriff.py
for freeform and strict MineFriff (requires the installaiton of a mod, which is described at the link). Note that for textual MineFriff,ConstLib.py
must also be downloaded - Official Javascript MineFriff interpreter -- official javascript/html5 interpreter and runner of textual MineFriff (WIP)