NDBall, "N-Dimensional Ball" or NDB is an esolang made by User:Aspwil (talk) in 2020. This esolang came from the idea of a truly infinite-dimensional esolang. The problem is if one has infinite dimensions, users will still just use maybe two or three, because using higher dimensions is unnecessary. As such, the creator had to come up with a way to force those who want to make programs to use more dimensions. They did this by limiting the length of all the dimensions. Each dimension only has space for 5 instructions, if one wants to use more than that they will need more dimensions.
Thanks to truttle1 for making a video that goes over some of the basics of the langauge: https://www.youtube.com/watch?v=idEkpMDbC2g
NDBall is a language where a ball rolls around through multi-dimensional space to execute a program. The ball itself holds a value, a single-byte integer (0-255), and starts at 0. The ball can move in any dimension, but it can only move in one of them at a time, and each dimension is only 5 cells in length. The ball starts at position 0 in all dimensions.
There are 2 ways to define a position.
First Method: Point
This defines a single point in space by putting all of its coordinates in a list. It is specified as:
This is 0 in the zeroth dimension, 1 in the first dimension, and 2 in the second dimension.
This method has a problem, however. If one wants to represent something that is in the 0th position for dimensions 0 to 15, but at a position of 3 for the 16th dimension, it must be written like this:
Now that is a lot of wasted zeros!
As such, the second method should be used.
Second Method: Vector List
A list of coordinates, specified with dimension number and length in that dimension. It is specified as:
The code from earlier is 3 in the 16th dimension so it can be written as:
This is the same position as before, but much easier to write and understand.
|>n||Move the ball forward in dimension n.|
|<n||Move the ball backward in dimension n.|
|+||Increment the value of the ball by one.|
|-||Decrement the value of the ball by one.|
|p||Print out the ASCII value associated with the value of the ball.|
|P||Print out the value of the ball as a number.|
|$||Take in input as a single character and set the value of the ball to its ASCII code.|
|%||Take in input as number and set the value of the ball to it|
|E||End the program.|
|#mov||"mov" is a movement instruction (ex. >3). If the ball`s movement is the same as the direction specified by the movement instruction, then the instruction remembers the current value of the ball. If the ball's movement is different, then the balls value is set to what it is remembering. By default, this instruction remembers 0.|
||||Reverse the direction of the ball.|
|Kmov||If the movement of the ball matches the movement instruction mov, then the ball passes through the instruction unchanged. Otherwise, the direction is reversed|
|a||An "apioform" joins the hive. Increment the hive value by 1.|
|f||An apioform leaves the hive to pollinate flowers. Decrement the hive value by 1.|
|q||The queen leaves the hive, taking all apioforms with her. Set the hive value to 0.|
|n||Nectar attract apioforms to or away from the hive. Set the hive value to the ball's value.|
|H||The hive itself. Set the balls value to the hives value.|
|Y[X,movA,movB]||Run a simple if statement. If the value of the ball is below X then the ball moves according to movA. If not, then it moves according to movB. Both movA and movB are movement instructions.|
|/||Make the current line a comment, which is ignored.|
|s||Swap the balls value and the instructions value. By default, the instructions value is 0.|
|L||Read in a full line of text. Each time the ball goes over it, it spits out the next one. Terminated with a 0 value. If it is empty, it will read in a new line.|
|R||Set the ball's value to a random number between 0 and 255.|
|S[num]||When the ball first encounters this instruction, start a timer for "num" milliseconds. When the ball encounters the cell again, hold the ball until the timer is done, then releases it in the same direction it was going.|
|St[num]||When hit by the ball, opens string memory num, and send all future output there instead of printing to the terminal.|
|ESt||When hit by the ball, stop redirecting output to the currently open string memory and switches back to the regular terminal output.|
|PSt[num]||Print what is currently stored in string memory num.|
Each line of code consists of 1 position and 1 instruction. For example:
is at position 0 and the instruction is "Move forward in the 0th dimension".
(0) >0 (1) % (2) Y[1,>0,>1] (2,1) P (2,2) <1 (3) P (4) E
(thank you for code provided by truttle)
Adding 2 numbers
Using the apiform to save data. 14 instructions.
(0) >0 (1) % (2) n (3) % (4) >1 (4,1) <0 (3,1) Y[1,<0,>1] (3,2) a (3,3) >0 (4,3) <1 (4,2) - (2,1) H (1,1) P (0,1) E
Using 65 instructions in 3 dimensions.
(0) >0 (1) + (2) Y[71,<0,>0] (3) + (4) >1 (4,1) <0 (3,1) p (2,1) <0 (1,1) + (0,1) Y[101,>0,>1] (0,2) >0 (1,2) p (2,2) >0 (3,2) + (4,2) Y[108,<0,>1] (4,3) <0 (3,3) p (2,3) p (1,3) + (0,3) >1 (0,4) >0 (1,4) + (2,4) + (3,4) p (4,4) >2 (4,4,1) <0 (3,4,1) - (2,4,1) Y[33,<0,>0] (1,4,1) p (0,4,1) <1 (0,3,1) >0 (1,3,1) + (2,3,1) Y[119,<0,>0] (3,3,1) p (4,3,1) <1 (4,2,1) <0 (3,2,1) - (2,2,1) <0 (1,2,1) - (0,2,1) Y[112,<1,>0] (0,1,1) >0 (1,1,1) p (2,1,1) >0 (3,1,1) + (4,1,1) Y[114,<0,<1] (4,0,1) <0 (3,0,1) p (2,0,1) <0 (1,0,1) - (0,0,1) Y[110,>2,>0] (0,0,2) >0 (1,0,2) - (2,0,2) p (3,0,2) - (4,0,2) >1 (4,1,2) <0 (3,1,2) - (2,1,2) Y[101,<0,>0] (1,1,2) p (0,1,2) >1 (0,2,2) >0 (1,2,2) - (2,2,2) Y[34,>0,<0] (3,2,2) p (4,2,2) E
99 Bottles of beer on the wall
Using 9 String memories to save pre-generated phrases. 445 instructions in 4 dimensions. The program is too long to include here.
Using 104 instructions and 5 dimensions, this is a functional 4-function calculator.
Also see the NDBall Program Archive for a list of a bunch of programs