Skip to content

Creating or modifying modes

Aymir Dmitrievich Danilov edited this page Sep 21, 2024 · 5 revisions

*Currently WIP*

Prerequisites

-- While you could copy everything from it, it's recommended that you extend from it.
local GameMode = require "tetris.modes.gamemode"
local CustomMode = GameMode:extend()

-- These 3 must be set.
CustomMode.name = "Custom Mode" -- Mode name
CustomMode.hash = "CustomMode" -- Identifier
CustomMode.tagline = "Mode made for prerequisites showcase" -- Sort of description.

-- Init function
function CustomMode:new(secret_inputs, ...)
  GameMode.new(self, secret_inputs, ...) -- Required if you're extending a mode, which is quite often GameMode. Otherwise, stuff could break.
  --insert mode init code here
end

-- This is always required.
return CustomMode

Static variables

--[string] Name of a mode.
GameMode.name

--[string] Mode ID.
GameMode.hash

--[string] Mode description/tagline.
GameMode.tagline

--[table of strings] Tags to sort a mode into
GameMode.tags

--[boolean/string, unsafe] This being assigned will make the replay select screen let you watch a replay
-- without a corresponding ruleset, if an override is flagged on a replay file.
-- I DO NOT RECOMMEND YOU SET IT TO TRUE UNLESS YOU KNOW WHY ARE YOU DOING THIS.
GameMode.ruleset_override

Some parameter variables

--[Randomizer:Object]
self.randomizer

--[boolean]
self.lock_drop

--[boolean]
self.lock_hard_drop

--[boolean] Instant drop toggle
self.instant_hard_drop

--[boolean] Instant drop toggle
self.instant_soft_drop

--[boolean]
self.enable_hold

--[boolean]
self.enable_hard_drop

--[integer] How many pieces in the next queue?
-- I do not recommend you ever modify it in runtime to something
-- higher than the one initially set up by mode's new function.
self.next_queue_length

--[boolean] If true, adds on top of the current gravity.
self.additive_gravity

--[boolean] NES-like lock behavior when on.
self.classic_lock

--[boolean] Whether to draw section times.
self.draw_section_times

--[boolean] Whether to draw secondary section times.
self.draw_secondary_section_times

--[boolean] BIG pieces
self.big_mode

--[boolean] This only affects on versions where half-block mode is implemented.
self.half_block_mode

--[xy coordinate] [v0.4.3.8 or higher] Offsets the piece on spawn.
self.piece_spawn_offset

--[boolean] Initial Rotation System
self.irs

--[boolean] Initial Hold System.
self.ihs

--[boolean]
self.square_mode

--[boolean] Toggles the spin bonus with a condition: The piece can't move in 4 cardinal directions.
self.immobile_spin_bonus

--[string] This will show up in your Discord Activity.
self.rpc_details

Some functions

--Update Functions
------------------

-- Runs at target fps, e.g. 60 times a second.
-- This is an internal update function of an gamemode. Don't modify it unless you know what it does!
function GameMode:update(inputs, ruleset)

-- This runs per GameMode:update().
-- If this returns false, anything after this function in GameMode:update() won't run.
function GameMode:advanceOneFrame(inputs, ruleset)

-- While the piece is active, runs at target fps, e.g. 60 times a second.
function GameMode:whilePieceActive()


--[[     Drawing Functions
|
| It's not recommended that you
| modify the variables in them, nor
| call the gameplay functions.   ]]
-----------------------------------

-- This runs first.
-- transforms specified in here will transform the whole screen
-- if you want a transform for a particular component, push the
-- default transform by using love.graphics.push(), do your
-- transform, and then love.graphics.pop() at the end of that
-- component's draw call!
function GameMode:transformScreen()

-- Draws a background. This usually doesn't need to be modified.
function GameMode:drawBackground()

-- Draws a frame. Normally, this shall be left alone.
function GameMode:drawFrame()

-- Draws the grid. Usually through grid's draw function.
function GameMode:drawGrid()

-- Draws the active piece.
function GameMode:drawPiece()

-- Draws the line clear animation.
function GameMode:drawLineClearAnimation()

-- Draws the queue. Usually this works fine.
function GameMode:drawNextQueue(ruleset)

-- Draws the scoring info.
function GameMode:drawScoringInfo()

-- Draws the Ready/Go sequence.
function GameMode:drawReadyGo()

-- Draws, well, whatever!
function GameMode:drawCustom()

-- Only runs if the game is paused.
function GameMode:drawIfPaused()

-- This by default calls GameMode:onGameOver().
function GameMode:onGameComplete()

-- Draws the game over part. By default, it starts with the field blacking out.
function GameMode:onGameOver()

--Callback Functions
--------------------

-- Runs at each attempt of either moving a piece or rotating it.
function GameMode:onAttemptPieceMove(piece, grid)
function GameMode:onAttemptPieceRotate(piece, grid)

-- Runs each time moving a piece or rotating it is successful.
function GameMode:onPieceMove(piece, grid, dx)
function GameMode:onPieceRotate(piece, grid, drot)
function GameMode:onPieceDrop(piece, grid, dy) -- A separate function just for vertical movement.

-- Runs each time the piece locks.
function GameMode:onPieceLock(piece, cleared_row_count)

-- Runs after GameMode:onPieceLock.
function GameMode:updateScore(level, drop_bonus, rows)

-- Runs during the line clear.
function GameMode:onLineClear(cleared_row_count)

-- Runs when line clear animation finishes.
-- Note: This might run before GameMode:onLineClear() if GameMode:getLineClearDelay() returns 0.
function GameMode:afterLineClear(cleared_row_count)

-- Runs each time a piece enters the grid.
function GameMode:onPieceEnter() end

-- Runs each time a piece is held.
function GameMode:onHold() end

-- Runs per GameMode:update() if there's vertical position difference in piece's coordinates, whilst holding down.
function GameMode:onSoftDrop(dropped_row_count)

-- Runs per GameMode:update() if there's vertical position difference in piece's coordinates, whilst holding up.
function GameMode:onHardDrop(dropped_row_count)

-- Runs when you exit the running mode.
function GameMode:onExit()
Clone this wiki locally