tetris clone – Terminally Incoherent http://www.terminally-incoherent.com/blog I will not fix your computer. Wed, 05 Jan 2022 03:54:09 +0000 en-US hourly 1 https://wordpress.org/?v=4.7.26 Designing a Tetris Clone: Part 2 http://www.terminally-incoherent.com/blog/2010/06/24/designing-a-tetris-clone-part-2/ http://www.terminally-incoherent.com/blog/2010/06/24/designing-a-tetris-clone-part-2/#comments Thu, 24 Jun 2010 14:08:15 +0000 http://www.terminally-incoherent.com/blog/?p=5759 Continue reading ]]> Wait, what? Part two? Where is part 1? Did we miss it?

Oh, wait… Never mind. I found it.

The story here goes like this: back in 2007 I had this crazy idea to make a Tetris clone. I was also frustrated by shitty “deveopmentstructive” environment I was working in a the time, and I wanted to do something the right way. You know, design it and then code it. Of course I would be cutting corners in the design process but I at least wanted to have some UML diagrams to show off. The other day I picked up this semi-abandoned project once again and coded it up over the weekend. Please keep in mind I have not been working on this software for the last 3 years. I worked on it for about a week (1-2 hours per day give or take) back in 2007, then I abandoned it. Last the weekend I picked it up again and built it from scratch abandoning everything I did in 2007 except for that initial blog post which was actually a pretty decent spec document if you looked at it in the right light.

The end result is not very pretty, but a fully playable and passable little game:

This is how the game looks right now

Here is what I learned from this project:

Don’t over-design it

Software engineering is a good thing. You should not be winging major projects and coding them digital cowboy style. You should be working in a group and from design documents. The group dynamics and good project management make this work. But if you are working alone on a hobby project, you can design yourself out of the whole thing. That’s what I did in 2007. I started by drawing UML diagrams and kept drawing them for a solid week. I agonized over encapsulation, and I was trying to pre-solve a lot of non-existing problems in my head and on paper without actually writing a line of code. In fact, I didn’t even have a clear idea what language/framework I would be using. I ended up with a pile of unfinished diagrams, no code written and a headache.

I had this sudden realization: this was supposed to be a fun weekend project and I’m sitting here agonizing over some stupid design document and totally not enjoying it. This is why I abandoned it altogether. I wasn’t having fun, so the whole exercise was pointless.

My second attempt was different – I went in with the intent of having fun so I pretty much just sat down and started writing code. No design on paper, no idea how I was going to do it. Just decided to figure it out as I go. The result of this was a finished (albeit a bit ugly and shaky) Tetris game about a day and a half later. In fact I the thing was playable (well, interactive – I could move a rectangle on the screen with my keyboard) within the first 10 minutes or so. Which brings me to my second point:

Make it playable as soon as you can

When designing games it is usually a best idea to have something that is playable or at least interactive right away. Don’t start by building a framework or a class structure of some sort. You can do that boring stuff later. Jump right into the heart of the project. The goal is to have something that you can sort of mess around with the first day. You know – a placeholder sprite moving around the screen or something. Start simple, then add complexity on top of it. Added benefit of this is that your simple game engine is easy to modify and re-design on the fly as needed. If you spent 30 hours engineering it on paper, and then you realize it doesn’t do something important forcing you to drop half of your intricate design it may be quite frustrating.

If you don’t do this, you will drown yourself in minute details. That’s what I did in 2007. I tried to design the whole game in my head first and I got lost in the detail. This year I started with just a single rectangle moving around on the screen and built the game around that and it was fun. I was riding the positive feedback loop the whole time. It is very rewarding when you can make some changes to your code, launch the game and see if and how they work right away. You actually see your game grow and take shape right in front of your eyes. In 2007 all I saw was a mountain of work, and the fun part (actually tweaking and testing the game while playing it) was a dim light at the end of a long dark tunnel. No wonder I dropped the project.

This is possibly the most important lesson for hobby projects ever – and it is so simple too. Make it fun now, leave the boring stuff for later. If you notice that are doing a lot of work so that you can get to the “fun part” you are probably doing it wrong. Just skip straight into the fun part.

Some design work does help though

Despite what I said in the previous paragraphs it does usually help to have some idea as to what exactly you are building. In my case I had a list of 17 Tetris facts and rules that helped me to stay on track. I also made drawings when I was designing the functions that would flip the pieces around so that I could keep track of the coordinate offsets. Stuff like that – outlines, sketches, lists of features – they help immensely. So you shouldn’t probably jump in and code straight away. You should first do some research and write down some things you want your game to do. You can feel free to ignore this stuff later on, but I highly advise to gather some research materials in one place early on. Otherwise you will fall into the distraction trap like me.

Here is what happens: sometimes when I write code, I need to look something up. For example how to calculate Tetris scores or whatever. So what do I do? I google it or look for sample code. Firstly, it ruins your flow – it takes you out of the code-mode, and makes you stop what you are doing and go somewhere else. Once you find what you need it will take you a little while to get back to where you where before you interrupted yourself. Secondly, half the time you take a break to look something up, you end up browsing the web for a while doing stupid shit.

Some thoughts on the project:

I used Python and PyGame to make this game. Why? Because I like Python and since I was making a game, it seemed logical to use the popular game creation framework for that language. The combination of these two tools meant that I didn’t really have to worry about excessive boilerplate code, event catching, drawing stuff on the screen and etc. It was all taken care of so I could concentrate on the actual game.

Another screenshot

If you want to see the code it is here. Please keep the following in mind though:

  1. This is by no means a finished game – treat it more like a rough pre-alpha draft
  2. The game and the code are bit ugly – this is my first time working with PyGame and I’m still learning
  3. ???
  4. Profit

In retrospect I think I should have went with sprites for graphics. As it is right now I’m just drawing the blocks using built-in PyGame toolkit and the result is a bit flat and ugly. Especially the text – I don’t really like this font and I sort-of eyeballed the distances so things are not spaced evenly. My next steps would be to make nice backgrounds for the game. A nice grid, a backdrop with slots for score, lines and etc and block pieces with actual shading on them.

That and I need to do some testing. I think the speed is still a bit wonky. The game should gradually speed up with each level, but I still have not found a perfect magical decrement number. I keep making it either to large (so at lever 4 or 5 the game becomes unplayable) or to small (the speedup is so gradual you hardly notice it).

Feel free to mess around with it if you want. The code is under GPL so you can use it as you will. Any suggestions, tips and/or contributions would be greatly appreciated.

I definitely want to play with PyGame some more. My next project… Well, I really want to make a 2d, top-down or isometric RPG. But that’s a huge undertaking and I haven’t figured out any details yet. Do I want it turn based, do I want it real time? Do I want the combat to feel more hack-and-slash or tactical? Do I want a randomly generated dungeon crawl or something more linear with hand crafted levels, quests and story line. Actually no, I know that – I want a game with a storyline, but it will be challenging to pull it off. My brother is on board too – though in a non-programing capacity. Maybe he can make some sprites and backgrounds. I don’t know.

Anyways, this is just an idea right now – as in, “wouldn’t it be awesome to make this” type of deal. Once I sit down and think this through I will make another post about it.

Quick Edit: Someone just told me that there is a occasional glitch in the game. In some special cases the blocks do not drop down properly after a line is removed. So far I was unable to replicate the scenario myself but supposedly it happens at the higher levels where there are many blocks on the screen and you are removing lines from the middle of the stack.

Quick Edit #2: Ah, I think I figured out the issue. The problem happens when you remove two or more non-contiguous lines. Sigh… I think I need a drastically different data structure for storing the immobile blocks. Storing them as an unsorted array of x/y coordinates makes it a bit hairy to perform the whole drop-down-after-line-removal operation.

]]>
http://www.terminally-incoherent.com/blog/2010/06/24/designing-a-tetris-clone-part-2/feed/ 8
Designing a Tetris Clone: Part 1 http://www.terminally-incoherent.com/blog/2007/10/20/designing-a-tetris-clone-part-1/ http://www.terminally-incoherent.com/blog/2007/10/20/designing-a-tetris-clone-part-1/#comments Sat, 20 Oct 2007 15:13:14 +0000 http://www.terminally-incoherent.com/blog/2007/10/20/designing-a-tetris-clone-part-1/ Continue reading ]]> Someone told me that Tetris was a “hello world” of game programming. I whole heartedly disagree. Tetris may not be an awfully complex game, but it sure as hell is not trivial. The whole concept of a “hello world” is to show the simplest trivial example of functional code that actually does something. But if you think about it, Tetris is not all that simple. So I decided to actually implement the game to show that if you really sit down and try to put it together it is slightly more than just a hello world.

Now, I could just sit down and hack a working prototype relatively quickly but let’s do this the right way. Lets design it, rather than hack it.

Good place to start is to put the spec of the game down on paper. So, let’s just list everything we know about the game:

  1. the playing field is a grid of the size 10×20, 10×24 or 10×16
  2. all tetris pieces are composed out of exactly 4 blocks
  3. the pieces come in 7 shapes: J, L, T, Z, S, I and O
  4. each piece has an orientation and color
  5. pieces start at the top in the middle of the grid, and slowly fall downwards
  6. the speed at which the pieces fall increases with each level
  7. player can move the pieces left and right or rotate them (change their orientation)
  8. when a piece touches the bottom of the grid or top of another piece it becomes locked down
  9. there is a slight delay before the lock-down that allows the player to slide the piece into place
  10. if a full row on the grid is filled it will clear and add to the players score
  11. the original Nintendo formula for computing score is m(n + 1) where n is level, and m takes the value of 40, 100, 300, 1200 depending on the number of lines that were cleared simultaneously (40 is one line, 1200 is 4 lines)
  12. when a line clears, all the blocks above move down
  13. requirements for advancing to the next level depends on a game, but most start with around 40 lines, and the number gets progressively smaller to become 1 level per line around level 20-30
  14. some games implement gravity that makes blocks that do not rest on other blocs slide down causing chain reactions
  15. most games display the next piece next to the grid
  16. most games allow player to instantly drop the block down either via hard drop or soft drop
  17. some games implement a wall kick that allows for rotating pieces backed up against the wall

The 17 points above roughly describe the game and can be used as an initial specification. Remember, we are building a game that already exists in many different version, so we want to create something that is instantly recognizable as Tetris, but we do not necessarily need to include all the fancy features that were added to it over the years.

As they taught you in your software engineering class, pay attention to the nouns. They are your potential classes. Right now I see several really good candidates: Block, Grid and Piece. In fact, we could possibly define classes for each specific piece like LShapedPiece, JShapedPiece and etc… They would all be subclasses of Piece and would define the shape, color and orientation. Each of these classes would also implement rules on how the piece could be rotated. This way Grid class would only need to interact with a Piece class.

I actually can see a nice factory pattern forming here. Grid will call a Piece factory which will randomly generate one of the subclasses, and then return it as Piece. This may or may not be practical, but it seems like a good idea at the moment.

Also, the spec is just a rough sketch of the game. If we want to implement it, we must answer several questions and make some important design choices. For example, how big do we want the grid? Do we want to allow the player to rotate pieces clockwise and counter-clockwise or just in one direction (the later choice means you only need a single rotate button rather than two). Do we want to have hard drops or soft drops? Do we implement wall kicks or leave them out? We also need to pick several variables such as lock delay, the speed at which the pieces drop. We must decide if we want pieces to crawl (move one pixel at a time with specific velocity) or skip (move full block length down every n seconds).

We have a pretty good scoring formula, but just a very rough guideline on level advancement. That will need to change. Oh, and there is also that pesky matter of collision detection – somehow we will need to decide how do we detect that piece has hit a wall, or a locking element like floor or another piece.

We also need to pick platform and a language at some point, but that is not all that important at this point. Tetris can be written in any language, and while some might be better suited for this task than others, it ultimately won’t matter as long as we can use some graphic display libs and don’t have to re-implement a whole 2d display framework.

I’m going to address all these questions Part 2, and start drawing up some UML. I also want to look at actual game piece design – like sprites, and internal representations of a piece and a grid. I already have certain design in my head, but any suggestions are welcome. I also have a very specific language and framework that I’d like to use, but I’m not really designing with that language in mind so I’m not going to tell you yet. Good design should work in any OO language – and once we pick one, we can do necessary adjustments if needed.

Still, I’d like to see what language you guy would use for this. Let me know in the comments. If you suggest a good one, I might even change my mind. :)

[tags]games, game design, gaming, tetris, tetris clone, design, software engineering, factory pattern[/tags]

]]>
http://www.terminally-incoherent.com/blog/2007/10/20/designing-a-tetris-clone-part-1/feed/ 3