generic tetromino game

Lua modding API reference

game

local game = require"game"

Board

An array of rows, top to bottom. Each column is two bits, from left to right going from least to most significant. 00 is empty, and 01, 10, and 11 are different tiles. Note that the indices are from 0 to 19; i.e. they don't start at 1.

type Board = [0...19]integer

CoreOption

A core option. New values for these options can be defined by defining new functions in the table. The parameters passed into the function and when the function is called depends on the specific option.

type CoreOption = table

CoreOption.value

The value of a core option. TODO: allow mutation

CoreOption.value: string | integer

GameState

The state of the game for one player.

type GameState = table

GameState:bclear

Initiates B-type clear sequence. This may invoke other mod functions if they listen to game.events.BCLEAR.

GameState:bclear() -> boolean

GameState.board

The currently active board. May be mutated.

GameState.board: Board

GameState.completed

Represents which lines, if any, were cleared. Each of the lower 4 bits represents one line, from top to bottom going from least to most significant. If you just want to get a count of how many lines were cleared, see GameState:completedcount.

GameState.completed: integer

GameState:completedcount

The number of lines that were just cleared.

GameState:completedcount() -> integer

GameState.cur

The currently active tetromino.

GameState.cur: Tetromino

GameState.das

The current DAS charge.

GameState.das: integer

GameState.doubles

The number of doubles cleared.

GameState.doubles: integer

GameState.dropdelay

The amount of time that must pass before the next piece will spawn. If zero, a piece is currently active.

GameState.dropdelay: integer

GameState.drought

The current drought.

GameState.drought: integer

GameState:efficiency

The current efficiency.

GameState:efficiency() -> integer

GameState.fallamt

Counts up to game.gravity(level) before game.events.GRAVITY is triggered and the current piece is either moved down one or locked into place.

GameState.fallamt: integer

GameState.flip

The direction that the player wants to flip the piece. This is 0 if a rotation wasn't requested, -1 if a counter-clockwise rotation was requested, or 1 if a clockwise rotation was requested.

GameState.flip: integer

GameState.level

The current level.

GameState.level: integer

GameState:lines

The number of lines cleared.

GameState:lines() -> integer

GameState:lock

Locks the currently active piece into place. This may invoke other mod functions if they listen to game.events.PRE_LOCK or game.events.LOCKED. Returns true if the piece actually locked; this may return false if a mod function cancels the lock.

GameState:lock() -> boolean

GameState.next

The tetromino up next.

GameState.next: Tetromino

GameState.oldrotation

The previous rotation. Only really used by the game to check whether the piece was just rotated, but it may be useful to set this sometimes.

GameState.oldrotation: integer

GameState.oldx

The previous x position. Only really used by the game to check whether the piece was just moved, but it may be useful to set this sometimes.

GameState.oldx: integer

GameState.oldy

The previous y position. Only really used by the game to check whether the piece was just moved, but it may be useful to set this sometimes.

GameState.oldy: integer

GameState.over

Whether the player has topped out.

GameState.over: boolean

GameState.player

The player for this game state: either 0 for player 1 or 1 for player 2.

GameState.player: integer

GameState.pushdownpts

Accumulated push-down points when soft-dropping. This value is mutable.

GameState.pushdownpts: integer

GameState:redraw

Redraws the board. This may invoke other mod functions if they listen to game.events.REDRAW.

GameState:redraw()

GameState.rotation

The current rotation.

GameState.rotation: integer

GameState.score

The current score.

GameState.score: integer

GameState.singles

The number of singles cleared.

GameState.singles: integer

GameState.softdrop

If negative, this will increase, and GameState.fallamt will remain frozen until this hits zero. If positive, the piece is being soft-dropped.

GameState.softdrop: integer

GameState.tetrises

The number of tetrises (4-line clears) cleared.

GameState.tetrises: integer

GameState.triples

The number of triples cleared.

GameState.triples: integer

GameState:trtrate

The current tetris rate.

GameState:trtrate() -> integer

GameState.waiting

If positive, this will decrease until it hits zero, and nothing else will happen in the main game loop. This is used when the game first starts (to emulate the delay in NES Tetris), and when B-type is cleared.

GameState.waiting: integer

GameState.x

The current x position.

GameState.x: integer

GameState.y

The current y position. Note that y increases from top to bottom.

GameState.y: integer

Music

Music loaded by game.loadmusic.

type Music = integer

Option

An option registered by a mod.

type Option = table

Option.value

The current value of an option.

Option.value: string | integer

Screen

A screen, uh not much else to say here lol

type Screen = integer

Sfx

Sound effect loaded by game.loadsfx.

type Sfx = integer

Tetromino

A tetromino, represented by a single character string: "T", "J", "Z", "O", "S", "L", "I".

type Tetromino = string

Texture

A texture that can be drawn to. Note that not all textures support transparency.

type Texture = table

Texture:clear

Clears a texture.

Texture:clear()

Texture:cleartetromino

Clears the space a tetromino would occupy on a texture.

Texture:cleartetromino(t: Tetromino, rotation: integer, x: integer, y: integer)

Texture:drawrect

Draws a rectangle on a texture. Note that the x and y are in pixels (before the texture is scaled by SDL), not tiles.

Texture:drawrect(x: integer, y: integer, w: integer, h: integer, color: integer)

Texture:drawtetromino

Draws a tetromino on a texture. If 'opacity' is specified, it must be an integer between 0 and 255 (defaults to 255).

Texture:drawtetromino(t: Tetromino, rotation: integer, x: integer, y: integer, level: integer, opacity?: integer)

Texture:drawtetrominobrick

Draws a tetromino brick on a texture. 'id' must be a non-negative number less than 4. If 0, this is a no-op. Otherwise, 'id' represents the tile to draw. If 'opacity' is specified, it must be an integer between 0 and 255 (defaults to 255).

Texture:drawtetrominobrick(id: integer, x: integer, y: integer, level: integer, opacity?: integer)

Texture:fillrect

Draws a rectangle on a texture, and fills it in with the given color. Note that the x and y are in pixels (before the texture is scaled by SDL), not tiles.

Texture:fillrect(x: integer, y: integer, w: integer, h: integer, color: integer)

Texture:write

Writes a string or number to the screen. 'width' must only be supplied if writing a number, but it can always be omitted.

Texture:write(msg: string | integer, x: integer, y: integer, width?: integer, color: integer)

game.TILEHEIGHT

The height of the canvas, in tiles.

game.TILEHEIGHT: integer

game.TILEWIDTH

The width of the canvas, in tiles.

game.TILEWIDTH: integer

game.allempty

Checks whether a piece fits into a board at a given location.

game.allempty(board: Board, t: Tetromino, rotation: integer, x: integer, y: integer) -> boolean

game.bg

The background texture. This is cleared whenever the screen is switched, and is intended to be mostly static and infrequently updated. Transparency is not supported on this texture.

game.bg: Texture

game.color.GREEN

A green color from the NES color palette.

game.color.GREEN: integer

game.color.INVERT

Inverts the background and foreground of a color.

game.color.INVERT(color: integer) -> integer

game.color.PURPLE

A purple color from the NES color palette.

game.color.PURPLE: integer

game.color.RED

A red color from the NES color palette.

game.color.RED: integer

game.color.WHITE

Literally just white. idk why i'm even documenting this

game.color.WHITE: integer

game.color.YELLOW

A yellow color from the NES color palette.

game.color.YELLOW: integer

game.emptyboard

A board which is completely empty; useful when combined with game.allempty to check if a piece is entirely within the playfield. You shouldn't mutate this board; that would be very impolite to the other mods using it. Don't be impolite.

game.emptyboard: Board

game.events.BCLEAR

Triggers before a B-type clear. Setting GameState.waiting to 0 will cancel the clear.

game.events.BCLEAR: integer

game.events.END_GAME

Triggers immediately before the game ends.

game.events.END_GAME: integer

game.events.FLIP

Triggers when the player attempts to rotate a piece, immediately before the rotation is attempted. Setting GameState.flip to 0 will cancel the rotation. This is useful if you'd like to implement your own rotation system.

game.events.FLIP: integer

game.events.FIRST_FRAME

Triggers on the first frame that a piece spawns.

game.events.FIRST_FRAME: integer

game.events.FRAME

Triggers every frame, regardless of whether a game is being played.

game.events.FRAME: integer

game.events.GRAVITY

Triggers before a piece is shifted down or locked due to gravity. Setting GameState.fallamt to a non-zero value or setting GameState.softdrop to a negative value will cancel this.

game.events.GRAVITY: integer

game.events.LOCKED

Triggers after a piece locks. Data about the piece such as its position and rotation is lost; if you need this, use game.events.PRE_LOCK.

game.events.LOCKED: integer

game.events.LVLUP

Triggers after the level is incremented.

game.events.LVLUP: integer

game.events.PAUSE

Triggers when the game is paused or unpaused. Read game.pause to determine which.

game.events.PAUSE: integer

game.events.PRE_LOCK

Triggers before a piece locks. Line clears aren't computed at this point; if you need this, use game.events.LOCKED.

game.events.PRE_LOCK: integer

game.events.RAW_MOUSEDOWN

Triggers when a button on the mouse is pressed. A third argument is supplied to the mod function for this event: a string of the button that was pressed ("Left", "Middle", "Right", "X1", "X2", or "Invalid"). You shouldn't use this unless you have a very specific use-case which calls for it.

game.events.RAW_MOUSEDOWN: integer

game.events.RAW_MOUSEUP

Triggers when a button on the mouse is released. A third argument is supplied to the mod function for this event: a string of the button that was released ("Left", "Middle", "Right", "X1", "X2", or "Invalid"). You shouldn't use this unless you have a very specific use-case which calls for it.

game.events.RAW_MOUSEUP: integer

game.events.RAW_MOUSEMOVE

Triggers when the mouse is moved. A third argument is supplied to the mod function for this event: a table containing two integer values, containing the x and y position of the cursor. You shouldn't use this unless you have a very specific use-case which calls for it.

game.events.RAW_MOUSEMOVE: integer

game.events.RAW_KEYDOWN

Triggers when a key on the keyboard is pressed. A third argument is supplied to the mod function for this event: a string of the key that was pressed. This differs from game.events.RAW_TEXTINPUT in that it only sends single key presses, regardless of any modifiers (e.g. shift) being used. You shouldn't use this unless you have a very specific use-case which calls for it.

game.events.RAW_KEYDOWN: integer

game.events.RAW_KEYUP

Triggers when a key on the keyboard is released. A third argument is supplied to the mod function for this event: a string of the key that was released. You shouldn't use this unless you have a very specific use-case which calls for it.

game.events.RAW_KEYUP: integer

game.events.RAW_TEXTINPUT

Triggers when something is typed on the keyboard. A third argument is supplied to the mod function for this event: a string of what was typed. This differs from game.events.RAW_KEYDOWN in that it sends a string of what was actually typed by the user, taking modifiers (e.g. shift) into account, and supporting composition (e.g. for non-ASCII characters). You shouldn't use this unless you have a very specific use-case which calls for it.

game.events.RAW_TEXTINPUT: integer

game.events.REDRAW

Triggers after the board is redrawn.

game.events.REDRAW: integer

game.events.ROTATE

Triggers after the piece is rotated.

game.events.ROTATE: integer

game.events.SHIFT

Triggers after the piece is shifted in the x direction.

game.events.SHIFT: integer

game.events.START_GAME

Triggers when the game starts, immediately after the current and next piece are first chosen. Note that this isn't the first event that's triggered in a game, since game.events.TICK triggers even during the initial start delay.

game.events.START_GAME: integer

game.events.SWITCH_SCREEN

Triggers when the active Screen is switched. Read game.scr to check which screen is now active. For most use cases you probably don't want to use this event; use a more specific event such as game.events.END_GAME instead.

game.events.SWITCH_SCREEN: integer

game.events.TICK

Triggers every frame for all players in-game.

game.events.TICK: integer

game.events.TOPOUT

Triggers after the player tops out.

game.events.TOPOUT: integer

game.fg

The foreground texture. This is cleared whenever the screen is switched, and is intended for screen-dependent graphics that are frequently updated. This texture supports transparency.

game.fg: Texture

game.freeze

Completely freezes all game logic. The only event that's triggered when the game is frozen is game.events.FRAME. This function can be safely called more than once; subsequent calls will have no effect. Call game.unfreeze to resume game logic.

game.freeze()

game.gravity

Gets the gravity of a level; i.e. the value that GameState.fallamt must reach before the current piece moves down or locks.

game.gravity(level: integer) -> integer

game.haltmusic

Halts the currently playing music if there is any.

game.haltmusic()

game.height

The B-type height, or nil if not playing on B-type. This value is mutable, but mutating it when not on game.screen.LVLSELECT when game.type is "b" won't have any effect. This value will never be greater than 8.

game.height: integer?

game.loadmusic

Loads music from the given path and returns an object that can be played with game.playmusic. The working directory is set to the directory that mod.lua resides in when the file is first run, so you can use a relative path here.

game.loadmusic(path: string) -> Music

game.loadsfx

Load a sound effect from the given path and returns an object that can be played with game.playsfx. The working directory is set to the directory that mod.lua resides in when the file is first run, so you can use a relative path here.

game.loadsfx(path: string) -> Sfx

game.multiplayer

Whether or not the game is being played multiplayer, either local or online.

game.multiplayer: boolean

game.newboard

Creates a new board, which can be safely mutated.

game.newboard() -> Board

game.newoption

Registers a new option. The second argument is a table, which must have a 'default' key, whose value is the default value of the option, and an 'events' key, whose value is the bitwise OR of all events that functions for this option will listen to. Register values for the new option by creating functions within the option, i.e. for option foo with value bar: `function foo.bar(ev, player)`. ev is the event that caused this function to be called, and player is the player the event is associated with: either 0 for player 1, or 1 for player 2.

game.newoption(name: string, {default: string | integer, events: integer}) -> Option

game.options.lines_per_level

TODO

game.options.lines_per_level: CoreOption

game.options.rng

TODO

game.options.rng: CoreOption

game.overlay

The overlay texture. This is intended for screen-independent graphics. This texture supports transparency.

game.overlay: Texture

game.pause

Whether the game is currently paused. This value is mutable.

game.pause: boolean

game.pausemusic

Pauses the currently playing music if there is any.

game.pausemusic()

game.players

GameState states for both players. If game.multiplayer is false, index 1 is invalid here.

game.players: [0...1]GameState

game.playgamemusic

Plays game music according to the value of the "music" core option.

game.playgamemusic()

game.playmusic

Plays music.

game.playmusic(mus: Music)

game.playsfx

Plays a sound effect. If 'pan' is negative, the sound plays moreso to the left, if positive, it plays moreso to the right. If zero, the sound plays equally left and right (i.e. no position changes). The default pan is zero.

game.playsfx(sfx: Sfx, pan?: integer)

game.prompt

Displays a prompt containing one or two choices. When a choice is selected, the respective callback function is called. This should, at minimum, set game.scr to a different screen.

game.prompt(msg: string, choice1: string, action1: function (), choice2?: string, action2?: function ())

game.rng.misc

A miscellaneous 16-bit unsigned integer used by the selected RNG algorithm. The exact meaning of this number differs based on the active RNG algorithm. This value is mutable; if your mod implements an RNG algorithm that preserves data between games, this should be used so games replay correctly.

game.rng.misc: integer

game.rng.next

Runs the PRNG function to get the next random number and returns the result.

game.rng.next() -> integer

game.rng.value

The most recently generated random number.

game.rng.value: integer

game.scr

The currently active screen. This can be mutated to switch to a different screen, potentially invoking other mod functions that listen to game.events.SWITCH_SCREEN. game.screen.PROMPT is NOT a valid argument for this function; use game.prompt instead.

game.scr: Screen

game.screen.CREDITS

The credits screen.

game.screen.CREDITS: Screen

game.screen.GAME

The game screen.

game.screen.GAME: Screen

game.screen.INPUT

The input mapping screen.

game.screen.INPUT: Screen

game.screen.LEADERBOARD

The leaderboard screen, where the player enters their name to save their score.

game.screen.LEADERBOARD: Screen

game.screen.LVLSELECT

The level select screen.

game.screen.LVLSELECT: Screen

game.screen.ONLINE

The online screen.

game.screen.ONLINE: Screen

game.screen.OPTIONS

The options screen.

game.screen.OPTIONS: Screen

game.screen.PROMPT

The prompt screen, used for user input and error messages.

game.screen.PROMPT: Screen

game.screen.REPLAY

The replay selection screen.

game.screen.REPLAY: Screen

game.screen.ROCKET

The rocket (statistics) screen.

game.screen.ROCKET: Screen

game.screen.TITLE

The title screen.

game.screen.TITLE: Screen

game.startlevel

The level the game was started at, or the level the game will start at if not currently in a game. This value is mutable, but mutating it when not on game.screen.LVLSELECT won't have any effect.

game.startlevel: integer

game.type

The type of the game, either "a", "b", or nil if inapplicable.

game.type: string?

game.unfreeze

If the game was frozen by game.freeze, resumes game logic. This function is a no-op if the game isn't frozen.

game.unfreeze()

Undocumented

CoreOption.__name: string
game.__useroptions: table