Tetris-playing computer programs have recently become more popular with the development of Zetris (mat1jaczyyy), a port of MisaMino (misakamm) to the official Tetris game Puyo Puyo Tetris. Since then, new programs have been developed such as Cold Clear (MinusKelvin), Tetras (traias), Wataame (ameyasu), and Hikari (SoRA_X7). Currently, all of these independently solve the problem of interfacing with the host game. This duplicates a lot of work between these projects, especially since this interfacing code is generally not made public due to concerns about such programs being used to cheat in online Tetris games. This repository aims to specify a common interface for communication between a Tetris-playing program and a Tetris frontend, similar to how the Universal Chess Interface solves a similar problem for Chess.
A bot conforming to the TBP exists as a standalone executable that is executed
by the frontend and communicates over standard input and output. Each message is
JSON terminated by a line break. On the web, a conforming bot is a script that
can be executed as a Web Worker and communicates using the postMessage
API.
JSON is chosen as the data format because it is ubiquitous, human readable, and
easily allows the protocol to be extended in the future. Every message consists
of an object with a type
attribute indicating its type. Messages with an
unrecognized type should be ignored.
This document specifies the minimum viable product of the TBP, as well as the minimum subset a conforming bot must implement. This version of the TBP can only be used with bots playing guideline-conforming Tetris games, but extensions will allow this limitation to be lifted in the future.
The rules
message tells the bot what game rules are in place. Currently, this
message is empty, and will be extended later. The bot must respond with either
the ready
message, if the bot can play with those rules, or error
if it
cannot. The standard guideline rules are the default; 10x40 board, pieces spawn
in the North orientation at x=4, roughly y=19, hold is allowed, the Super
Rotation System is used, etc. Since many Tetris games have slightly different
peculiarities, the defaults are not precisely specified.
The start
message tells the bot to begin calculating from the specified
position. This message must be sent before asking the bot for a move.
Attribute | Description |
---|---|
hold |
Either a pieces if hold is filled or null if hold is empty. |
queue |
A list of pieces. Example: ["S", "Z", "O"] |
combo |
The number of consecutive line clears that have been made. |
back_to_back |
A boolean indicating back to back status. |
board |
A list of 40 lists of 10 board cells. |
A board cell can be either null
to indicate that it is empty, or a string
indicating which piece was used to fill it, or "G"
for garbage cells.
The stop
message tells the bot to stop calculating.
The suggest
message tells the bot to suggest some next moves in order of
preference. It is only valid to send this message if the bot is calculating. The
bot must reply as quickly as possible with a suggestion
message containing
suggested moves.
The play
message tells the bot to advance its game state as if the specified
move was played and begin calculating from that position. It is only valid to
send this message if the bot is calculating. Whether a hold was performed is
inferred from the type of piece placed.
Attribute | Description |
---|---|
move |
The move, as specified in the suggestion message. |
The new_piece
message informs the bot that a new piece has been added to the
queue. This message is generally paired with a play
message.
Attribute | Description |
---|---|
piece |
A piece. Example: "T" |
The quit
message tells the bot to exit.
The error
message informs the frontend that the bot cannot play with the
specified rules.
The ready
message tells the frontend that the bot understands the specified
game rules and is ready to receive a position to calculate from.
The info
message must be sent by the bot to advertise to the frontend what
TBP features it supports. Once the frontend receives this message, it can inform
the bot of the game rules using the rules
message.
Attribute | Description |
---|---|
name |
A string, the human-friendly name of the bot. Example: "Cold Clear" |
version |
A string version identifier. Example: "Gen 14 proto 8" |
author |
A string identifying the author of the bot. Example: "SoRA_X7" |
features |
A list of supported features. |
The suggestion
message is sent in response to a suggest
message. It informs
the frontend of what moves the bot wishes to make in order of preference. The
frontend should play the most preferred valid move. If no moves are valid, the
bot forfeits and the frontend should tell the bot to stop calculation. Whether
a hold should be performed is inferred from the type of piece to be placed.
Attribute | Description |
---|---|
moves |
A list of moves in order of preference. |
A move is an object with the following attributes:
Attribute | Description |
---|---|
location |
A piece location specifying where the piece should be placed. |
spin |
One of "none" , "mini" , or "full" indicating whether a spin should be performed. |
A piece location is an object with the following attributes:
Attribute | Description |
---|---|
type |
The type of piece this is. Example: "I" |
orientation |
The rotation state of the piece. Spawn orientation is "north" , after a clockwise rotation "east" , etc. |
x |
The x coordinate of the center of the piece, with 0 being the coordinate of the leftmost column. |
y |
The y coordinate of the center of the piece, with 0 being the coordinate of the bottommost row. |
The center of the piece is defined according to SRS true rotation. The piece centers for the L, J, T, S, and Z pieces are the stationary points of basic rotation in SRS. The center of the O piece in the north orientation is the bottom-left mino; for east, top-left mino; for south, the top-right mino; for west, the bottom-right mino. The center of the I piece in the north orientation is the middle-left mino; for east, the middle-top mino; for south, the middle-right mino; for west, the middle-bottom mino.
As I understand it, someone needs to make a unique interface program for each game that exposes the TBI to make bot programs plug'n'play. Kinda with a
Game <-> interface <-> TBI <-> bot
structure where the TBI is basically the protocol/connection for the interface and the bot to talk. The interface being able to make choices while the bot does nothing but take parameters and do calculations. Due to this disconnect between the bot and game, it is up to the TBI to pass all data the interface provides to it.Piggy backing off of ExileLord a bit, I think the interface should have the ability to query the bot for information the bot cares about while sending the bot game settings, and game state. As to whether the TBI passes all relevant game settings or just the
game name + game mode
, is left up to you guys to decide if the interface or bot should have to figure out these settings. I personally think it should be the interfaces job to hold and pass all the minor details to bot when it asks for them. It will be the bot's job to deal with missing parameters.I don't like rotation system being a start attribute because it's information only needed once and feels a bit out of place. I suggest adding two new messages from the frontend,
capabilities
to learn what info the bot wants, andsetup
to change the game rules/parameters. To compliment these new messages, the bot should be able to send a new one too.online
should come beforeready
to indicate its responsiveness but lack of supplied game settings. I'm thinking of a flow where B launches -> (B->F)online -> (F->B)capabilities -> (B->F)capabilities -> (F->B)setup -> (B->F)ready -> (F->B)start.In all games there should be a minimum amount of data that needs to be sent. For setup we need to check for compatibility with board size, mino shapes, mino bag randomization, and rotation system. For start data, we need board state, at least one queue pieces (active piece), hold status (holding piece, empty, or unavailable). The rest should be able to be inferred for a poor, but working experience. More info should always be better.
Hope I managed to make this coherent. Obviously everything is up for change.