Help with game mechanics like match-3, but not quite

I used emthree to build a prototype, but realized that I was going in the wrong direction, then I tried to build the grid of the playing field using tilemap, but I ran into the fact that I didn’t understand how to spawn objects in tiles, and also so that they were of different lengths.

Here is my code for building a board:

local emthree = require "emthree.emthree"

    local blocksize = 64
    local boardwidth = 8
    local boardheight = 10

    local function create_block(board, position)
    	local id = factory.create("/spawner#block_spawner", position)
    	msg.post(id, "set_parent", { parent_id = go.get_id(), keep_world_transform = 0 })
    	return id
    end

    local function init_board(self)
    	self.board = emthree.create_board(boardwidth, boardheight, blocksize, { direction = emthree.COLLAPSE_DOWN })
    	emthree.on_create_block(self.board, create_block)
    	for x = 0, self.board.width - 1 do
    		for y = 0, self.board.height - 1 do
    			if not self.board.slots[x][y] then
    				emthree.create_block(self.board, x, y)
    			end
    		end
    	end
    end

    function init(self)
    	init_board(self)
    end

Then I tried to spawn objects on top of the created board, but that didn’t work either
I want to make a similar game and practice in this genre, which way should I look? I’m more interested in the approach of constructing such logic: a grid, randomly spawning objects, and not complete filling as in match-3.

In the game, an object spawns from below and lifts all the blocks up, I also wonder if there should be blocks. Then I tried to spawn objects on top of the created board, but that didn’t help either.
I want to make a similar game and practice in this genre, which direction should I look in? I am more interested in the approach of constructing such logic: grid spawning, randomly spawning objects that move blocks from above, and not completely filling the playing field as in match-3. Do objects have to have a physical body to lift each other up and fall down if there is nothing underneath them?

I am attaching a link to the reference

I really hope for your help, this is the 5th time I’ve tried to do something, but apparently my hands are growing from the wrong place.

I suggest to try and build this from scratch. Use a Lua table to represent the game state (the board, the spawned things etc) and use game objects with sprites for the visual representation of the board and objects. You spawn game objects using factories. Use Emthree as inspiration.

Start small! Don’t try to solve everything at once!

1 Like

thank you for quick response!
how can I control the coordinates of the board? like in chess, like e3e5, etc., in order to clearly understand in what coordinates the object spawned. In general, there is still confusion for me. Moreover, blocks can have different lengths and some block can occupy 3 cells horizontally, and not one.

There was a similar game (mechanics-wise) made with Defold on the MWDJ2023:

I would also suggest to make such game step by step:

Try to separate visual representation from input handling from logic handling. Start by defining smallest part of the game and writing down its design:

Grid is a 8x8 grid (or 8x10, etc, but usually 8 is the width).
Blocks can be: 1x1, 1x2, 1x3, 1x4.

  1. Implement Block Sliding Logic:
    a) implement picking correct block
    b) then allow to move it only horizontally
    c) make sure you can slide only within the grid’s row (between “walls”)
    c) make sure you can’t slide past other blocks in a row, if there are some
  2. Implement what happens on action.released:
    a) there should be a check if some blocks can fall down, so for each row, for each block in that for check if there is space for this block below this block (notice how when forming such statement you “write” for loops)
    b) if there is space, move that block to the row below (not visually, move that “block” in your grid (a Lua table)
    c) notice how this check should be done for all blocks from top rows to bottom rows
  3. Add row “fullness” check - if blocks in a row fill the whole row - remove all blocks from that row - and repeat step above
  4. Add game over conditions (if there is a block in the highest-1 row after all blocks fall, because if you spawn next line, which you will do below, you will touch the ceiling - but you can perhaps also check it after 5.)
  5. Add new line spawning (in the very bottom of the grid, but first move all blocks to the row above, starting from top to bottom)
    a) you increase difficulty by spawning more of bigger blocks in a row, because e.g. 1x1 blocks are always a life saver - you can slide them almost anywhere and many times you make a full row with them (I know, because I play a lot of games like this xD)
2 Likes

Thank you very much for such a detailed answer! I will try further, I hope I will be able to make the core mechanics of this kind of games. A game made at a game jam is something I want to repeat to learn how to work with tables in Lua.

1 Like

In case of any troubles, don’t hesitate to ask :wink: I can’t do it myself now, because of lack of time, but I will try to help as much as I can, I’m very interested in such a game :smiley:

1 Like

Is it better to build a grid like in emthree or use tilemap as an option? or neither at all and just use an abstract table like

self.grid = {
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},

	}
	for x = 1,10 do
		for y = 1,20 do
			tilemap.set_tile("/grid#grid", "layer", x, y, 1)
		end
	end
1 Like

Yes, I think your approach will be the best, you nicely separated logic from representation, so you can operate only on your table easily to do logic and at the end you can just set visuals (in this loop) :wink:

Will the “cats”/“blocks” be separated into tiles? If so, think of how will you "move them, when you will be “sliding”

2 Likes