You are on page 1of 17

TUTORIAL

:

A TOWER DEFENSE GAME
<by ATHANATOS>

This is what your game should look like in the end. Please don’t copy or distribute this tutorial in any way. Feel free to use it, and to copy the codes for your game, as long as you are the one who has done the work, not me. And please DON’T make simple rip-offs for competitions. I’d hate it if someone else would win $1000 while I have done the boring part of the making of it. Make sure it remains your own game, and else, please give me credit too. Thank you for using this tutorial.

1

target (set to noone). The laser will be a simple drawn line. We also add a variable. If you have GM Pro. It can be made with GM Lite and Pro. I made the TD game ‘Interceptor’. and now I’ve included an upgrade system. we make two sprites for towers: one for the laser and another for the bullet-firing tower. The wave system has also been updated. And finally. which will indicate the enemy that is being attacked. so you don’t have to build them yet. They automatically attack the enemies in range. That’s easier if you want to test if they work. We give them both a depth of -2 and we make the laser tower the parent of the bullet-firing tower. Therefore. Next. That’s why I wrote this tutorial for the people who want to make their own TD game with Game Maker 6 or 7. with the origin in the center. Towers The first thing you need when you play tower defense games is of course: towers. In the first steps of the tutorial. we need a variable to indicate whether the tower is firing or not. you need some basic content:  Towers page 2-5  Enemies page 6  A path (or more) for the enemies page 7-8  A building system page 9-13  A wave system page 14-15  An upgrade system page 16 Also. we’ll assume that the towers already exist. you can make sprites that can rotate nicely. When you make a TD game. Since then. Laser towers This tower will fire a continuous laser at the nearest target. OK first. I have received some messages about how I had made it. we make two objects.A few weeks ago. please read the Final Words on page 17 when you’re done. which will be: firing (set to 0). one for each tower. NOTE: this is a new tutorial: the examples are made largely with GML and have more comment added. Now you have one wave at a time. I’ll describe two kinds of towers: laser towers and bullet-firing towers. we’ll add these variables:  Range = 200  Rate = 3  Damage = 10 2 .

= -3. You can change them if you like. That’s because when the laser fires.own_health < 1 target = noone. it must increase until we think the tower can fire again.target.x. if point_distance(x. First. } } 3 .target. Now it’s time to make the script which will make the tower attack enemies within range.target. sound_play(sd_laser). we use the following script: //Draw a laser beam and the tower { draw_sprite(sprite_index.4).ob_enemy).y. For this. Now it’s time to make the visible laser beam.x. firing = 30/rate firing = 0. firing rate (shots per second). If that’s the case. If it isn’t. else if firing = 0 firing = 1.y.target. the target can be reset. the firing sequence is started.y) > range target = noone.0. we check if the target is in range.y). it looks like you shoot through it. we check if the firing variable is larger than 0. If you temporarily decrease the depth. Otherwise.y. we check if there are any enemies at all.own_health -= damage. draw_line_width(x. if target. instance_exists(ob_enemy) if target = noone target = instance_nearest(x. if (target != noone && firing = 1) { draw_set_color(c_red). __________________________________________________________ //Check if enemies are in range and activate firing if needed { if if if if { firing > 0 firing += 1.x. } } if firing = 1 depth else depth = -2. Then. target. Price = 20  Name = ‘Laser tower’ These variables indicate the range. not instance_exists(target) target = noone. the building cost and the real name for the tower. the depth will be set to -3 if the tower is firing. draw_set_color(c_white). and another tower is in the way. Next. This is calculated using the rate. And finally.y. if not instance_exists(target) target = noone. the laser will fire above the tower. damage.

which can be transformed. In the collision event with an enemy. we don’t fire a laser. is that they often go too fast. I recommend making an enemy object already. with the diameter of the speed you want the bullet to go. This is especially a problem if you don’t have GM Pro. Now it’s time to adapt the tower. you can make a long-shaped bullet. Also give it the variable damage If you haven’t already made an enemy object. but it doesn’t indicate an instance. but bullets. The damage is done in the very end. In the Create event. and adapting it later. Next. you can change other stats as well. add the following actions:  Set variable own_health for other object relative to -damage. to summon the variables. if an enemy is nearly dead and the damage is too much. The script in the Step event is slightly different. Then we change the variable name to ‘Cannon’. Then we check if a laser beam must be drawn. we add the function of creating a bullet. It is a bit more difficult. the target’s instance is destroyed. This is when masks are useful. To make bullets hit easier. This time. we draw the beam first and then damage the target. so that it still hits. or they ‘go through them’. we make a bullet object. One big difference between lasers and bulletfiring towers is that bullet-firing towers need another object – the bullet – to damage their targets. But the index still exists. If you do that. If so. The reason bullets can go through enemy objects. we make a mask for the bullet object. and play a sound. Don’t forget to set the origin in the center.) Bullet-firing towers Now it’s time to make a bullet-firing tower. because if you have Pro.  Destroy the instance (self) If you want. You should give him the variable own_health (you decide the health amount) and set the depth to -1. That way. That’s why I made a script for this. you can test the towers if you want. because bullets can miss their targets. Although it has the laser tower as its parent. so when we need to fire. which is a black filled circle. which will get errors in the game. we still need to do every event again. One of the questions I got was about making towers shoot at moving targets without missing. the code becomes like this: 4 . you can also add an effect or explosion or something like that. and giving it the appropriate speed and direction. with depth -1 and the mask set. it’s time to make one. we first use the action Call Parent Event. But you need it to configure the bullet. because. If you want. (By the way.Here we draw the sprite at its position. After that it can just be a simple object which moves across the screen.

target.y. For the drawing event. } } } As you can see. The file tdtutorial1. yy = target.direction = point_direction(x.ob_enemy). dist. some additional variables had to be used.direction*pi/180). //Create a bullet ii = instance_create(x. we simply use the ‘draw sprite’ action to draw the sprite and prevent the tower from using the laser’s drawing functions. and it heads to the point where the enemy should be at the moment the bullet should be nearest to the enemy.y. 5 .xx. This can only be a problem if the enemy turns left or right. ii.target. In this file. if point_distance(x. if not instance_exists(target) target = noone. ii.y. there are some enemies that move into random directions and jump back if they are dead or outside the room.direction*pi/180).yy).speed*dist*sin(target. using its speed and direction.x.x. xx.speed*dist*cos(target.x+target. ii.y)/24.damage = damage. xx = target.target. Also. Now we have two towers. yy. the script becomes a bit longer.gmk shows what your game should look like now. if firing > 0 firing += 1. if instance_exists(ob_enemy) { if target = noone target = instance_nearest(x. because of the bulletcreating functions. if firing = 30/rate firing = 0.y. The result is: a bullet is created when the tower should fire. dist = point_distance(x.speed = 24.ob_bullet). else if firing = 0 { firing = 1. we’ll talk about better enemies.__________________________________________________________ //Check if enemies are in range and activate firing if needed { var ii. Next.y) > range target = noone.y-target.target.y. which should work nicely.

we’ll use health bars. First.Enemies Making enemies in tower defense games is quite easy. That’s why we give the enemies a second variable: health_def. There is a simple system to make that. the enemies have very little health. All are a bit difficult.y-13. As you can see. and how to make it visible. draw_set_alpha(0.c_lime. the default health amount. draw_set_alpha(1). We need that to draw the relative health of the enemies.c_red. we’ll make sure the enemy follows a path.y). c_black. One important issue is that the enemies must move behind each other. draw_healthbar(x-12. In the next chapter. which is the same as the own_health variable once the enemy is created.x. We’ll need this piece of code to draw them for every enemy: __________________________________________________________ //Draw the sprite and a healthbar { draw_sprite(sprite_index.image_index. Let’s start with the basics. or place them at the same spot. Change the colors if you like. it must be destroyable (it must have health). This is optional. The enemy object we’ve created is really simple. Next. I’ll discuss the making of a nice path. any sprite we set for the object will be drawn. or place them all at the same spot at the same time.1).own_health/health_def*100. Check the Game Maker Help if you want to know how this works. Second. But in this tutorial. you could also show smoke or spark effects if the health is half the starting amount.1. not all at the same time. but make the enemies wait for each other. There are several tricks to do this: place them all in a row at the same time as soon as the wave starts.8). There are only a few things to set with enemies. with the correct sub image.0.x+11. But as the game continues. } Now we have a transparent health bar above every enemy.y-16. But we’ll talk about that in the final chapter. or fill in your own coordinates or make the health bar move the other way or up-down. but not at the same time. 6 . you want the enemies to become harder to defeat. Now let’s make it a bit more complicated. it must follow the appropriate path. At the beginning of the game.

For now they are just markers to help you to build up a background using tiles. let’s make the markers. you could make a bridge for the path. Create a path and set the right coordinates for the path. Tiles Now it’s time to make some decent graphics for the background. or a few trees. Anyway. using the same system. These are simple objects. one in each level. In the example there’s only a tile set for the path. and you’ll get something like this: 7 . Tips for creating a path:  When you begin constructing. You can make a tile set for this.  If you want to make smooth turns.  Make the path not closed. these things will be more important. we can begin constructing the actual path for the enemies. But then you’ll need to make multiple marker objects. for which you won’t need difficult sprites. you need a few components:  Objects that will mark the path and prevent tower building on the path. For that. that’s up to you. The actual path Now that we have a visible path to rely on. the enemies follow a visible path.Paths In most tower defense games. indicate the level room to show as a background. add one point in front of the turn and another behind it. which is not visible Markers First. By doing this. Adding more scenery can also make great levels. Remember to make them invisible. For example. you set the xcoordinate of the first point at -32) and make it end after the end of the visual path. There’s also a background for the level. or to make the actual paths. But in the next chapter. Make it start outside the room in front of the start of the visual path (example: if you start at the left of the room. one for every part of the path.  Tiles to give the path a better look  The actual path. precision 4. you can make the path exactly like the visual path. or a river etc. Then set smooth curves for the lines. Another option is to use the markers to draw the path.

path_speed*dist*cos(target.direction = point_direction(x. yy = target. If you do this.damage = damage.y-target.target. ii. Compare your game with the file tdtutorial2. complete with a path. ii. Since the enemy has no speed if going through a path. so don’t make it in the Create event) instead of just speed.y.ob_bullet).xx. 8 .x+target.y)/24. So don’t erase the }-markers at the end.direction*pi/180). the piece of code about creating a bullet will be like this: __________________________________________________________ //Create a bullet ii = instance_create(x.x. you would only see the path that is made of tiles. and mention the variable path_speed (this is a built-in variable.yy).’.direction*pi/180).target.y. this is only a small piece of the entire script. Remember. dist = point_distance(x. Everything else is still the same. we need to adapt the code.y.speed = 24. ii.damage = damage. It is just the code below the comment ‘//Create a bullet’ until the line with ‘ii. xx = target.Don’t mind who are your towers and who are enemies: just look at the path and the markers.gmk and check if you’ve done well. Now you have one level. In the game.path_speed*dist*sin(target. One thing you need to do: check the code of the bullet-firing tower.

Add the variable ii_select. add the variable money. In the Begin Step event. Give them a depth of -10000 and make the first button parent of the second one. Make two subimages in both: one for the default moment and one for when the mouse cursor is on top of it. set the image_speed to 0 and initiate the variable price. We’ll do so too. in which you can select and build towers. just like before. The controller object doesn’t need a sprite (although it makes it easier to recognise). When you play a TD game. draw the sprite with the appropriate image index and. in the Create event of the parent. and it will make the enemies appear in waves once we’ve finished the tutorial.Building towers OK – it’s time to make this stupid. If you click one. create a font for the text. set image_index to 1. you can see it’s stats. we make two sprites for buttons: one for each tower. no stats will be displayed. set the variable image_index to 0. the sprite will change if the mouse cursor is on top of the button. There are several buttons to build towers. Make it small. draw a text with the needed money. and upgrade them if you have the money for it. Creating an in-game menu Now it’s time to introduce a new kind of object: the controller. which is set to the price you want the player to pay for the tower. but make the font anyway. the appropriate tower appears and you can drag it to a nice spot. give it a depth of -1000. The next key part is: the building system to build the towers. Then. draws the menu background and text. with the value noone. there’s nothing challenging about a game in which there are towers already and you can’t build any: it’s very boring. there’s often a small window somewhere above or below the path. Of course. but readable. If it is noone. so it’ll be drawn first in any case. Finally. We are going to make all of this in our example game. This object checks important variables. and click again to build it. and change back if it isn’t. You can also draw text in the button images. Next. And in the No Button event of the mouse. Another often-used function is: the status window. When you’ve created it. because we’ll need it later. uncontrollable junk into a real TD game. If you select an existing tower. Now we make two objects for the tower buttons. Set the money to a nice start value (like 50). when the image index is 1. Most TD games use money to buy the towers. in the Draw event. This variable will indicate if the stats of a tower must be displayed. By doing this. First. 9 . Then. except for the buttons.

if instance_position(mouse_x. add this piece of code: __________________________________________________________ //Check for money and other towers and create a tower object. A very simple example: use these actions: Set Color (you can decide which color it will be) and Draw Rectangle (use these coordinates: 256. Now it’s time to draw some text. But that changes now. you can show how much money you have. but we still can’t do much with them. { var ii. } First. By doing this. add the button objects and the controller to the room.Now you make a background for the menu. In any case.active = 0. By doing this.0. simple background for the menu. you can change the amount).y. Indicate that by using path marker objects. but create enough room for text. Then it checks if there is enough money to build the tower (if you want. or just a simple drawn box. After that. but replace the text 10 . Set a similar function for the other button object. draw it somewhere at the edge of the room. set a good text color. you can prevent the towers from being built inside your menu screen. They might look good. Then. Check the area in the room that is covered by the menu.639. Put your buttons somewhere in your menu (don’t forget to turn ‘delete underlying’ off) and place the controller somewhere at a visible spot. it checks if there is a tower object at the mouse position (ob_tower_laser is the parent of the towers here) to prevent multiple tower creation at the same time (like when you accidentally click twice. buttons etc. Then.mouse_y. or when you try to place two different towers at the same time at the same spot). This can be a sprite.ob_tower_laser) exit.111) and you’ll get a nice. if controller. ii = instance_create(x. or just some information). Also.money < price exit. and think about some text to put in the menu (like a header. Open the Left Pressed mouse event for the laser tower button. it creates the tower. Set the font. ii. Building the towers Now let’s return to the button objects.ob_tower_laser). draw a text with the following content: 'MONEY: '+string(money).

but we can still build on top of them. draw_set_alpha(1). Now we can build our own towers. in the Collision event with the marker object. There. the tower will do what it’s supposed to do. If it is active.y+15.y+15.0. Now we need to improve the drawing functions. That way we can only build at free spots.y-16. For this we have the following code: __________________________________________________________ //Draw a ghost of the tower and its range { draw_set_alpha(0. and if it is. Since towers are now immediately unmovable when they are created.5). we need to set it to 0 at the beginning of every step.x+15. draw_circle(x. Next.range.y. After the variable is created.x+15.[fill in the tower parent object]. we introduce another variable: coll_path (0). Add these actions (both towers): Test Variable (check if active is 0). Still. we change the Step event for both towers.y. To disable that. set it to 1. we set coll_path to 1. In many TD games. draw_set_color(c_white).1)  collision_rectangle(x-16. else draw_set_color(c_red). This indicates whether there is a path object at the position of the tower. and also with the tower parent object. adapt the Left Pressed mouse event for the parent only. The variable active shows in what mode the tower should be. aligning to a grid to make building towers more accurate. Then: Jump to Position (coordinates mouse_x. or movable.y-16. if the following expressions are not true:  collision_rectangle(x-16. mouse_y) and Align to Grid (no changes). Then close the block and add the Else action.[fill in the path marker object]. there are a few things that need to be adapted. after that a block start. This problem also occurs when you build on top of another tower. Next. the tower will move to the mouse position if inactive.1) Then. check if active is 0. when you are building towers. we can check if the tower should be active.ob_tower_laser in the function instance_create for the index for the other tower. we add the variable active to the towers (set to 1). You can also see whether you can build at the current position or not.1). we check this variable in the Left Pressed event (which means it must be 0). } 11 .16. Also. before we set active to 1. draw_circle(x. set the money of the controller relative to -price. Next.0. By doing this. We have path markers. you can see the range circles of towers.0). By doing this. if coll_path = 0 draw_set_color(c_lime).

selected = 0. we first set selected for all instances of the tower parent object to 0. we set selected back to 0. as soon as an enemy is destroyed. ). Now let’s change the Left Pressed mouse event. but we add some actions above it. we check if active is 1.y. If it isn’t.Use this code when active is 0. Now it’s time to do something with that. Now it starts to look like a real TD game. and then we check if selected is 0. Else.ii_select (the variable from the controller) to instance_position(x. there are really many variables) which will indicate if the tower is selected or not. but the player doesn’t know the stats of a tower. if mouse_check_button_pressed(mb_left) if not instance_position(mouse_x. he can see it. before continuing to the wave system. Go back to the tower parent and add the variable selected (0) (I know. you want to earn some new money.mouse_y. First.selected = 0. If we add another mechanism.y. But we can still add a few things to it. If it is.ob_tower_laser) if not instance_position(mouse_x.btn_tower_laser) { ii_select = noone. ob_tower_laser. we added the variable ii_select. In the Step event. } } This code checks whether mouse buttons are pressed and if the towers should be deselected.[fill in the tower parent object]. 12 . Now let’s shift to the controller object. Since you lose money buying towers. draw_circle(x. When selected is 1. When we made a controller object. That can be easily done by adding some cash to the money variable of the controller.ii_select to noone and end the block. We let the existing actions remain the same. } if mouse_check_button_pressed(mb_right) { ii_select = noone. Now comes a more difficult thing. draw a circle (using a code. then set selected for the instance itself to 1 and set the variable controller. Now we add a few actions to the Draw event of both towers. Then add a block start.mouse_y.range. That was rather easy.1). set controller. Tower status Now you can build towers. ob_tower_laser. add the following code: __________________________________________________________ //Check whether the tower should be deselected { if not instance_exists(ii_select) ii_select = noone. use the default code or action.

After that.gmk to check if you have done the right things. check if visible is equal to 1. set visible to 1. 13 .ii_select.price/2). The selling price is determined by dividing the buying price by 2. And else. but if you put one at the wrong position and don’t want it there.'Range: '+string(ii_select. To show these variables. There are just two things left to make: a wave system and an upgrade system. be proud of yourself. because we’ve had the worst part of the tutorial now. ii = controller. and make the button parent also the parent of this object. in the Left Pressed mouse event. we add some text to the code in the Draw event.2. it’s better to sell it. and it draws some variables. Well. set the variable visible (a built-in variable) to 0 if the variable controller. controller.ii_select.32.range)). Then. range. Then. controller. In the Step event. with ii instance_destroy(). { var ii. make an object for that button. About the selling price: we can build towers now.money += floor(ii. } This code adds the appropriate amount of money to the money variable of the controller. we need another button object.name). To do that.damage)+' HP').'Selling price: '+string(floor(ii_select. Now we can show the tower’s name. Next. Make a sprite for a ‘sell’ button. draw_text(400.48.price/2))).Remember all those variables which I introduced when we created the first towers? This is where it pays off. Place this text between the last line of code and the end of the code: _________________________________________________________ //Draw tower stats if ii_select != noone { draw_set_font(ft_header). it changes the font to the stats font. execute this piece of code: __________________________________________________________ //Check which tower should be sold and then sell it. damage and cost. draw_set_font(ft_hud).64. draw_text(400. draw_text(400. draw_text(400. rate. Then it draws the tower’s name. } The first action changes the font to a better font for headers.ii_select = noone.'Fire rate: '+string(ii_select. draw_text(400.'Damage: '+string(ii_select. Then. I recommend you compare your game to the file tdtutorial3.rate)+' shots/second').80. it destroys the sold tower.ii_select = noone.

} //Create enemies if needed if wave_time < 600 wave_time += 1.Wave system Nearly all TD games use a wave system to create enemies. To do this. 14 .ob_enemy). if wave_time = 600 { wave += 1. We’ll make a system that creates every enemy at the same spot. At such a value an enemy is created. you could see that I used a system that creates all enemies at once in a row. if wave_enemies > 0 { if wave_time = (ee-wave_enemies)*15+15 { instance_create(-32. Then it checks if the time has a certain value. and the harder it gets to beat them.0. because the towers often fired at targets far outside the room. } } } This script works as follows: first it checks if the wave time is 600. which is the moment it will move on to the next wave. The higher the wave. Both are set to 0. Wave indicates the current wave number. wave_enemies -= 1. If you have played Interceptor. but not at the same time. ee = wave_enemies. we’ll create them near the border of the room. wave_time indicates the time remaining until the next wave and wave_enemies indicates the number of enemies to be created. It also sets the time back to 0 and sets the amount of enemies that should be created. __________________________________________________________ //Check the wave time and calculate how many enemies should be created //Create the arrays for the next wave { globalvar ee. our game wouldn’t be finished if we hadn’t such a system.4). we create three additional variables named wave. wave_time and wave_enemies. wave_time = 0. Well. the more difficult are the enemies. The wave system will be controlled by – of course – the controller object. In the chapter about enemies I mentioned a few ways to create enemies every wave. Now we just need a script for the Step Event that will handle all this stuff. wave_enemies = min(5+floor(wave*0. which is limited by 16. To prevent that.16).

add the function to subtract one life. when an enemy is at the end of the path. in the No More Lives event (Other events). Then.5. or some kind of sprite. check the file at the end of this tutorial. set the score to the wave number. In the Create event of the controller. like 10 or 15 and set the score to 0. set the number of lives to a nice amount. Now we have a wave system. Check the file tdtutorial4. That’s up to you. Finally. Draw the amount of lives somewhere in the menu.5)*10).1. you want to see in which wave you are and how long it takes before the next wave. There is only one thing we’re going to add here: an upgrade system. we get an amount of money equal to the wave number if the enemy is destroyed. which will make the game a little easier and more fun to play. times 10. you could either use a health bar. Now we add instead of 1: controller. Now you have a nice TD game. but that’s all. To draw the time.wave.gmk and compare your game to it. Now we are done with this simple wave system. it still wouldn’t be a real game). Then. In either case. like a clock. That will make the enemy health increase by the wave number. If you want to see how it’s done in the example. Next. By doing this. and we make sure the enemy won’t return to the start position if destroyed or at the end of the path. 15 . power 1. be sure to indicate that the time variables uses arrays. display the highscore table and restart the game.wave. we destroy the instance if the health is 0 and we adapt the function that adds 1$ of money to the money variable of the controller. we set the appropriate path for the enemy instead of moving some way. Therefore. we make it possible to lose the game (or else.Of course. we draw the wave indicator just below the money indicator at the same way. Instead. we set the enemy health variable (and the default health variable too) to round(40+power(controller. There are some things that we need to change: First.

ii = controller. make a new sprite for an ‘Upgrade’ button.price*0.range*1. since the button has a parent) is set to controller. I decided to add this to the tutorial as well. Since I got a lot of requests to explain how it can be done. Then. and multiplies the stats by certain amounts (the rate is limited.5). because a very high rate could make the game a bit weird). it still was very easy at wave 108. see how far you can get (with me.range = round(ii. Then go back to the upgrade button. if ii. use the same checking system as used in the ‘Sell’ button. 16 . ii.damage*1. it first checks if the level of the tower is smaller than 5.money -= price.10). in many TD games you can upgrade your towers. and execute this piece of code in the Left Pressed Event: //Check which tower should be upgraded and then upgrade it. but when visible is equal to 1. That’s all for the moment. The first thing we need here is another button.damage = round(ii. ii. Then it checks the money that is needed. Now YOU make sure the tower shows what level it has.rate*1. isn’t the same kind of system that Interceptor uses.Upgrade system As you know. and add it to this object.ii_select. It works a bit different and is actually a lot easier to make. make sure the button has only a Step Event and a Left Pressed Event. compared to impossible at wave 70 without upgrades).level < 5 if controller. however. The last example is tdtutorial5. Duplicate the ‘Sell’ button. ii.price*1. Now go to the tower parent object. This. ii. so have a look at it.gmk.ii_select. and add the variable level (set to 0). ii. After that.2.price = round(ii.rate = min(ii. it increases the level.1). { if visible = 1 { var ii.money >= price { controller. the variable price (which already exists. } } } As you can see.level += 1.1).4. In the Step Event. It can’t get higher. decreases the money.

I’ll at least reply. That makes more room for a menu.  Make multiple levels. like power-ups for towers. 17 .  Use your own sounds. and a new path for each of them. or superweapons (like EMP or FBA in Interceptor). you need more than this. or anything like that. so don’t worry about any errors. And please tell me if you have Lite or Pro. which vary in cost. actually only I am done here. for a new tower. and of course Interceptor. This whole tutorial has been made along with GM 7 Lite. Vector TD.Final words Well. damage and rate. range. If you need additional tips.  Make additional upgrades.  Make the rooms larger. like Onslaught. Good luck!!! ATHANATOS. you can play other TD games. I can give you some tips to make your own TD game:  Make more different towers.  Make more (different kinds of) enemies. ask me. Flash Element 1 or 2. or anywhere else. If you need some inspiration. You now have the basics for a nice TD game. because we are finally done! Well.  Make a main menu from which you can access all features in the game. That makes it easier to answer your question. take a well-deserved breather. If you want a game that scores highly on the YoYoGames website. but that’s not enough.