Tetris on Google Sheets

I made a game of Tetris on Google Sheets.

Where can I see it?

Here is a video.

Where to play it?

UPDATE: I was and then confirmed that the app no longer responds correctly to arrow inputs. This might not work. I might fix it one day.But if anyone feels adventurous, I welcome and appreciate the help. I will like you.

  • Go here
  • Make a copy of the Google sheet file and add it to your drive.
  • Open it
  • Read the instructions
  • Press “Start” and play

Do expect some wonkiness — read the bugs part please.

What was the story behind it?

I believe it was Q1 of 2018 when my PM (hey Dennis!) asked me to do this Apps Script project on Google Sheets. If you don’t know, Apps Script is the scripting language for Google apps like Sheets, Docs and Forms etc.

My first thought was to ask him to go and do what he must, to reach satisfaction posteriorly. But then, of course, I was getting paid to be a resource, so I thought if I think myself so hot, how good of a job I can do really?

I have to confess, App Scripts has a great documentation, and thus it is very fun to work with.

This first project was well received, and thus we moved on to a second more involved project. In this second project, we had to have multiple tables in one sheet and be able to insert an arbitrary number of rows and columns in any order in any of the tables without the formatting or the application breaking.

That was my gateway; at that point, I knew this would grow grotesque and I cannot maintain it sanely. Thus I refactored part of project 2 to make it less like an App Script project and more like any other app, with objects, abstractions, and nice methods like addRow or moveDown which would take care of all the references and named ranges for me.

As part of an inner joke and perhaps because of the influence of some libation one Friday evening, I thought to myself if I can make Tetris on App Scripts, and that is how it started. I kept video logs of my progress at first but then I stopped midway. The reason is that I was planning to demo this time lapse to the company on my upcoming second anniversary. Unfortunately, though I was laid off, you can still see those videos in this folder. I like the one where the script won’t stop.

How was the making?

The code

This is a more technical part so you could skip it if not interested.

I started by exploring the deal breakers, like a tile moving down and the ability to move them around. The plan was as follows:

For a single tile (the I):

  1. Make a colored range drop, a range is a set of contiguous cells on a straight line
  2. Add controllers for moving them right and left
  3. Devise stacking of the tiles on top of each others
  4. Devise the row clearing

Everything went rather okay here:

I put the tile in a three by three bounding box, to help me with moving it down and basically interfacing with the bounding box, instead of every cell of the tile.

  1. For making a tile fall, I had an infinite loop that will move down the range and sleep for a set time.
  2. For moving, I would have the code check a cell value and then move the tile to left or right accordingly.
  3. For stacking, a shadow sheet, called Board_ was writing 1s where a tile rests finally, but not while it is falling. As a result, if the buffer encounters 1s, it must stop. The buffer was the row immediately beneath the bounding box
  4. Row clearing was fun. I wanted to add a smol animation. Basically check to see if a row sums up to 24, which is the number of columns in the board, and clear that row if it does. Then simply copy and paste what is above to a row lower, which now is empty.

At this point I decided to add all the other tetriminos (or tiles). So I added all the shapes with their rotations on a new sheet called Tiles so I can copy from there and paste on my board. The three by three bounding box was great here, I could copy the box and paste it into the main board and see the tile appear and start moving down.

But here is where it blew up. The moving three by three bounding box would override the color on the stack below. If this is vague, imagine a stack of tetris tiles nicely fit together, and an “o” tile is coming down, that is the square piece, and it is two by two. Imagine there is room exactly for that “o” piece, i.e. two columns. But the tile has a three by three bounding box, and thus when the piece is entering the opening, so does its bounding box, and so, the extra column is ruining the stacked up tiles as it is moving down, by clearing everything in its trail.

Moreover, the buffer for the bounding box was just a straight line under the bounding box. But for shapes, like the “L”, that is not true when it is rotated. Then the buffer is uneven on the bottom of the tile.

This is VERY obvious now but for some reason, it never occurred to me then: if you treat individual shapes, as three by three squares(a bounding box), you will get the behavior of a three by three square, it does not matter that it does not look like a square.

To fix this, I chose to choose a “hinge” for every shape and every rotation, and copy and paste relative to that hinge. This worked. I chose the hinges as the first upper and then the leftmost one cell in each tile. It was a bit messy because I had to have custom offsets and ranges for each and every one. The same needed to happen to the buffers, now that the uniform bounding box was gone.

The highlight of this was when I realized, that if I put the hinges of every shape, as the nodes on a grid then my data structures will collapse in complexity and everything will be much cleaner. I have never felt this much tangible difference in handling code when one chooses a suitable data structure. The figure below illustrates what I mean by putting hinges on a grid.

Screen Shot 2018-09-16 at 11.19.47 PM.png
Every hinge of any tile type is on the same column.
Every hinge of any tile rotation is on the same row.

After some debugging it was ready. I just had to make the colors cuter.

Closing thoughts

Apps Scripts is great. I think it is very underutilized by some people that will really benefit from it. Apart from abstractions to make front-end component, it is possible to extend it, using itself to retain a memory.

I once used a sheet to store and retrieve values from just like a memory. A sheet can be a key value store that one can use to write anything in and wipe.

I sometimes fancy the idea of an MVC framework on top of Apps Script. If the script has no memory this is impossible, but we could save states in another sheet and read from and write to it. I don’t know how slow it would be, but, thought experiment.

Of course, there are those who use it as a database, definitely not better than a SQL database, but I will argue with you that it could be better than MongoDB for you.

Thinking back, I feel pretty arrogant and ashamed to have thought I am above Google Sheets + Apps Scripts; this is a complex system to build and document and its simplicity and intuitive interface does not at all hinder building very complex systems with zero deployments or infrastructure maintenance. The bottlenecking will probably happen if much faster applications are required,  but that is not always the case for most use cases.

I might be very delusional here, and people will say: “Well yes of course! I can’t believe you are rediscovering this”, especially that I am aware of communities doing awesome things with it, and especially that I have known people, self-proclaimed non-engineers, making amazing tools with this ecosystem (hi Diego!). Alas, I have never come across an application engineer, in my 2 years in grad school and two years in the industry that has told me, or even alluded to, how powerful Apps Scripts can be for most use cases.

Trust me, give it a try.

12 thoughts on “Tetris on Google Sheets

  1. Hey, Emin. Have you looked at using PropertiesService or CacheService to use as your key-value store? Should be much faster than read/write operations to the sheet.

    Liked by 1 person

    1. Thank you very much. I have not. A couple of times sheets broke where it would not stop the script from running even after refreshing (video in the drive). So I decided to stick to one process. But it can be good improvement.


    1. Hey Josh, sorry for the super late reply, I did not see the pending comment. What you need to do is to make a copy of the sheet first and then play with it. You cannot work directly on the sheet that I shared, unfortunately, otherwise, I would have to keep putting up new sheets. Thank you for your interest!


  2. Could you try using functions (i.e. SUMIF, IF, SUM) in google sheets to create a game such as pong? You can add custom functions, so I was thinking if you created one that changes the fill of cells. It probably is a stretch, and I don’t Know much about java and html, but I do know that to use functions in sheets and when developing are the same setup.


    1. Hey Max. I am glad that you are interested. My first thought is that, as far as I know, it is not possible to create a game with only formulae.

      The reason for that is, that when a game renders, frame by frame, it is the computer, changing the color of the pixels, or in our case the cells, giving us the impression that something is moving. In google sheets, I did this by having the program run forever and sleep a second or two every time, so for us humans it is slow enough to understand. Otherwise, it will be too fast. I don’t know of a way to delay execution on formulae. Formulae also will complain if they go into an infinite loop.

      That being said, my first ever automation was with excel and later excel macros. Now I am a backend engineer. So I will encourage you to try and see if you can make a game using only formulae and what problems you face.

      You don’t really need HTML or javascript to code this game. It is apps script, which much simpler to learn than javascript. So if you do get to that point to be needing to use apps script, don’t worry too much, just give it a try. There is very good documentation on it as well: https://developers.google.com/apps-script/reference/spreadsheet/


  3. Thanks for your feedback! Also thanks for showing me that part of the google developers hub! I had no idea you could use that for sheets. It will definitely make things a lot easier for me.

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: