TIS-100 Hacker's Guide

Puzzle Lua

Puzzles in TIS-100 are implemented as Lua programs.

As of June 24, 2015, TIS-100 uses MoonSharp 0.9.5.0 to interprete the puzzles.

A puzzle must implement the following functions. None of the functions take arguments.

Global variables do persist between function calls. Global variables are discarded when TIS-100 notices and loads an updated version of the puzzle.

Notes on matching the style used by the official puzzles.

Functions and constants available to puzzle Lua.

get_name()

get_name() is evaluated only once upon load, no later than upon entering the SPECIFICATION EDITOR. It will not be re-evaluated on re-entering the SPECIFICATION EDITOR, nor upon entering the program editor.

Returns a single string used as the puzzle's title. If the name is longer than 33 characters, it will not display correctly on the program editing screen.

The name is not forced to upper case (as of July 4, 2015); to match TIS-100 style it should be all upper case.

function get_name()
    return "EXAMPLE PUZZLE"
end

get_description()

get_description() is evaluated only once upon entering the program editor. It will not be re-evaluated.

Returns an array (numbered table) of strings. Each entry in the array is a bullet point in the puzzle description and will be word-wrapped. The space to display the description is 33×6; the bullets themselves (">") are outside of this space. The name will be forced into upper case before displaying if it isn't already.

function get_description()
    return {
        "THIS IS THE FIRST BULLET POINT AND WILL BE WRAPPED",
        "THIS IS ANOTHER BULLET POINT",
        }
end

get_streams()

get_streams() is evaluated upon entering SPECIFICATION EDITOR to provide compiler error messages. Evaluated twice more each time you enter the solution editor. Evaluated once more after finishing the first page of a puzzle. Evaluated once more after stopping a run.

Returns an array (numbered table) of input and output streams. Each stream is itself an array whose elements are

  1. Type
  2. Name
  3. Position
  4. Values

Type must be one of STREAM_INPUT, STREAM_OUTPUT, and STREAM_IMAGE.

The name is a simple string. For STREAM_INPUT, the name should be 6 characters or less to avoid overlapping other streams. For STREAM_OUTPUT, the name should be 8 characters or less. The name is not used for STREAM_IMAGE.

The position is an integer from 0 through 3 representing the which column of nodes the stream is connected to. 0 represents the leftmost column and 3 the rightmost column.

The values are an array of integers.

For STREAM_INPUT and STREAM_OUTPUT, the values should be in the range -99 through 999. These streams can only display the first 39 elements.

Numbers outside of the range of -99 through 999 are clamped to -99 or 999.

For STREAM_IMAGE, the values should be in the range 0 through 4. There must be exactly 540 values, enough to fill a 30×18 image. The image is filled top to bottom, left to right.
The values are interpreted as:

ValueColor
0 Black#000000
1 Dark Grey#464646
2 Light Grey#9c9c9c
3 White#fafafa
4 Red#c00b0b

(How STREAM_IMAGE behaves from the TIS-100 assembly point of view.)

get_streams() will be called four times, once for each test. The first three times math.random() will be seeded with a fixed value to ensure that the tests are identical between runs. If the SPEC number is s, and the test number t=1,2,3, then the seed is (100s+t−1) mod 232. The fourth time it is seeded with an arbitrary number so that the last test is not predictable. Generally the values from get_streams() should be randomly generated. Code should use math.random(min,max) to generate random numbers. Code should not call math.randomseed(seed). math.random(min,max) is based on the C# System.Random, not the version from the primary Lua implementation. Details on math.random's implementation are available.

The left side of the display has space for approximately 41 columns of information. Additional columns will be rendered underneath the nodes. A STREAM_INPUT occupied about 7 columns, a STREAM_OUTPUT about 9, and a STREAM_IMAGE about 34.

Type Min Max Max Count Width
STREAM_INPUT -999 999 39 7
STREAM_OUTPUT -999 999 39 9
STREAM_IMAGE 0 4 540 34
function get_streams()
    return { 
        { STREAM_INPUT,  "IN", 1, {1,2,3,4,5,6} },
        { STREAM_OUTPUT, "IN", 1, {1,2,3,4,5,6} },
    }
end

get_layout()

get_layout() is evaluated only once upon load, no later than upon entering the program editor. It will not be re-evaluated on re-entering the SPECIFICATION EDITOR, nor upon entering the program editor.

Returns an array (numbered table) of types for the nodes. The array must have exactly 12 elements, and represent the nodes in a 4×3 arrangement. Valid values are TILE_COMPUTE (program node, T21), TILE_MEMORY (stack memory node, T30), and TILE_DAMAGED (unusable damaged node).

In this example the entire right column is damaged, the top and bottom nodes on the left are stack nodes, and the rest are compute nodes.

function get_layout()
    return { 
    TILE_MEMORY,   TILE_COMPUTE,  TILE_COMPUTE,  TILE_DAMAGED,
    TILE_COMPUTE,  TILE_COMPUTE,  TILE_COMPUTE,  TILE_DAMAGED,
    TILE_MEMORY,   TILE_COMPUTE,  TILE_COMPUTE,  TILE_DAMAGED,
    }
end

Notes

Many thanks to AapOpSokken on Reddit the updated algorithm for calculating the seed.