Iteration 1 – Week 2 Reflective Journal

This week, I needed to catch up on some tasks missed from the previous week and ensure that my game was ready for testing next week. I am pleased with how the prototype has turned out as it has the majority of the features that I put into my Minimum Viable Product. The main features that I missed were a wave of attack system and being able to upgrade your monsters however, the game is playable without these at the moment. I want to add these during iteration 2, as they will provide an extra level of depth to the game and make it interesting to play more than once.

Over the past two weeks, I wish I had been able to create more art assets for the game. I am most disappointed that I didn’t get around to creating a spritesheet for the enemies, as this means that for testing I will have the Phaser placeholder image so I will need to let my testers know that they are the enemies. Generally speaking, I tend to have days where I cannot concentrate or get any work done, followed by days where I can do two to three days worth of tasks. This means that my production diary looks a little odd, as I skip some days entirely as I just didn’t have the motivation to work on those days. Personally, I would rather I spent those days resting, so that I could attack my productive days better, rather than sit staring at the screen in counter-productive frustration.

My major achievement for this week was my collision detection system. Admittedly, it does break when a new object is added during the same frame a collision happens but in the majority of cases it functions as expected; I put a lot of work into figuring out how to identify which objects were colliding, but now that I have a basic functional system I can push it further in iteration 2 to remove the crash. I also wish to make the system more efficient than looping through all of the enemies and the monsters that the player has summoned.

Iteration 1 – Week 1 Reflective Journal

At the beginning of the project, instead of spreading all my tasks over the course of two weeks, I initially planned for only one week of development time by mistake. This meant that even if I got a significant chunk of work done on a particular day, I was technically behind on my planning. To rectify this, at the beginning of next week I am going to re-organise when I want each task completed to spread out the remainder of my work. My issues with planning were made worse by the fact that I had to take nearly two whole days off from development time, as I fell ill with a nasty cold. Consequently, I spent the rest of the week trying to catch up with what I had missed on those days and my planning from last week was pretty much ignored from that point on.

Despite my illness and problems with improper planning, I still managed to achieve a good chunk of what I had set myself to do. I completed approximately half the tasks that I had assigned, which makes sense as I had given myself two weeks of tasks to do in a single week by mistake. The main tasks that I am behind on are write-up and allowing the game to start however, I have lain the foundation to begin on these parts in earnest next week.

Overall, this week was rather rocky, particularly due to the loss of development time and incorrect planning. I am please with how far into the project I am, but I would prefer to be ahead of schedule, rather than on the edge of being behind.

Iteration 1 – Production Diary

Monday 4th:

I had planned to set up the GitHub repo, start on the UI elements, and create a basic start screen.

To start creating the UI elements, I made a button class that I can use anytime I need to generate a button. I did this because the game will have a pause/play button, and a menu that the player will use for summoning towers. By have a pre-made button class, I can simplify how much code I need to do in the future. I had hoped to have a few more UI assets completed today, but I didn’t get round to it. I plan to catch up on the asset creation later in the week.

For the start screen, I placed a button in the centre (missing its asset) that the player can touch and it will load up the first level. I would like to possibly add an options menu in the future, but I’m unsure at the moment.

I started on a basic tower selection menu, that will pop-up over the game screen to allow the player to select and upgrade their towers. The menu currently doesn’t do anything, but it’s there.

Tuesday 5th:

Today in the morning I had planned to work on the monster base class, the altar that the player will protect and start on an example level. In the afternoon I wanted to make the unit summoning menu functional, and start on my collision detection system.

Instead, I spent the day in bed, feeling sorry for myself with a nasty cold and headache 🙁

Wednesday 6th:

Originally, I wanted to work on the path following system today, and create the maths functions for upgrading and purchasing towers. However, the majority of today was a repeat of yesterday, spent in bed, trying to recover.

In the evening, I had started to feel better, so I decided to attempt to catch up on some of the work that I had been unable to complete.

The main task that I got done today was creating a class for creating an Altar object. The main goal of the game is to protect your Altar, so it was important to get this object into the game in way that will allow me to summon a new one each scene without having to duplicate code.

When the player’s remaining health goes below a set threshold, I want the altar’s frame to change. I didn’t realise that I could use the simple setTexture method to change the frame of the sprite until after I had created single frame animations for the Altar’s different frames. In the future I would know to use setTexture instead, but as I had already written code to use animations, I left it as it was.

I also created the lose state for the game, by creating the take_damage function for the altar. To stop the game when the player’s health goes negative, I disable input and pause the scene’s physics. I started on the tower’s (monster’s) base class, creating a few properties that I feel may come in useful later such as health, attack_speed and level.

For the cost functions, I referred to my old maths notes from A level to find a suitable curve that would be fairly simple to graph. I used Desmos a graphing web app the adjust the curves until they were just right. On paper I rearranged the equations so that they had y on one side and could be used to return a value when needed.

My upgrade function is: 

Even though the graph has an asymtope at x = 10, it is still fit for purpose as I don’t want the player to be able to upgrade past level 10.

My cost function is: 

By using this function, I can continue to increase the cost of purchasing a troop without imposing a limit on the number of a particular type the player can have.

Thursday 7th:

My plan for today had been to create win/game over states, and start on an enemy attack system. Due to the fact that I was behind on other tasks, I was unable to begin work on these particular problems.

I glued together the images for the tentacle’s spritesheet using a tool by Leshy Labs that allows you to create a spritesheet just by uploading the individual frame images.

To create a path for the enemies follow, I looked at a Phaser tutorial that allows you to use interpolation to create smooth paths for your sprites to follow. It uses two arrays of values – one for x, one for y – that I want to read in from a Tiled tile map in the future. Currently, I am using placeholder arrays for testing, as I pass these arrays to the level base class from the instance of a level.

I also started work on the enemy base class, putting in a basic attack function, and attempting to create the update function to allow the enemy to move. I couldn’t test this yet as the game didn’t have a start button, but it wasn’t throwing any errors due to improper syntax, so I left it as it was and moved on to a different code task.

In the past, I had created a cooldown function for enemy attacks where the game would compare the current time to the time of last attack. I looked over my previous code to help in creating a cooldown function for the towers, so that they couldn’t spam attacks. I wanted to do this so that the enemies could pass through a few towers attack areas, forcing the player to spread their towers out across the path to the altar.

Monday 11th:

During the Game Design Document planning phase, I only created planning for the first week of development time. This was to allow me flexibility going into the second week in case of tasks that were incomplete, or bugs that may have popped up during the first week.

The key tasks that I had left to do at the beginning of this week were:

  • Complete a start screen
  • Spawn in enemies when the player hits start at set intervals or in waves
  • Work on unit placement mechanics
  • Put individual sprite frames into spritesheets
  • Add in a start/pause/play button
  • Collision filtering/detection
  • Add in currency the player can spend

I spent a good section of today planning out in what order tasks would need to be completed, to make sure that I could properly test each new section of code for bugs without having to rely on something else being completed first.

Wednesday 13th:

Today I focused my time on working on the start/pause/play button, as well as the tower summoning mechanic. I briefly started working on the base class for the first type of monster I wanted to implement – a tentacle that has a slam attack.

I started on the summoning system by looking at some of my past work to see how I had implemented touch controls in the past. I started out using the method from the Matter Game, however I found that it wasn’t working quite as I needed. It was suitable for swipe input, but I wanted a drag system instead. I decided to fix this another day, to allow myself to continue to work on other components.

To implement my pause/play button, I created a new PausePlayButton class. I couldn’t extend my previous button class as I used a sprite sheet for my new class, whereas the other class uses an image instead. I decided to use a state constant to check whether the game was paused, playing, or stopped. This was so that on my update loop, I could ensure that the correct frame of the sprite sheet was displaying based on what state the game was in. This will also help in the future once I make the button interactive.

Thursday 14th:

Today was a check-in day at uni, so I wanted to use that opportunity to get some help with a couple of errors that had been troubling me over the past week.

I fixed a simple problem where my tentacle class was unable to inherit from my monster base class by simply changing the order in which they were loaded in the index file.

I created a SpawnerButton class that inherits from the Button class to use for confirming if the player is happy with where they have placed their unit.

Since I want to read in my enemy paths from a tilemap, I created two functions to read in the tilemap data, and convert the information from the objects layer into the arrays needed for the path creation functions.

During the university session today, I spoke to James about a way in which I could prevent specific objects from colliding with one another. For example, I wanted to be able to display a monster over the top of the summoning menu background, whereas they were colliding with each other and the monster was being pushed off of the menu area. He explained that I could set the background to static to prevent it from moving and set it to a sensor to prevent it from colliding with other objects.

The next task that I moved onto was changing the controls over. Built into Phaser was a drag input function, that allowed me to update the position of the sprite as the player moves it. Furthermore, there was a dragend function so I could have the confirm button pop-up whenever the player stopped dragging the sprite around.

                    this.input.on("dragstart", function (pointer) {
                        this.menu_background.setActive(false);        
                        this.menu_background.setVisible(false);
                    }, this);
                    this.input.on("drag", function (pointer, object, drag_x, drag_y) {
                        object.x = drag_x;
                        object.y = drag_y;
                    });

Saturday 16th:

For today, I updated my pause/play spritesheet, as there were white corners on all of the images. I also created a basic, plain, place holder tilesheet as well as a level that I could use for testing and debugging. I also changed the dimensions of the game canvas by 4 pixels. Originally, I had matched it to the Google Pixel’s dimensions however, I needed the screen dimensions to be a multiple of 32. Unfortunately, I wasted a lot of time over a mistake that I made importing the tileset into Tiled. Instead of setting the spacing of the tileset to 1px, I set the margin to 1px. Since I didn’t notice this problem immediately, I spent a while trying to diagnose the issue in another way, hence I didn’t get much more done today.

Sunday 17th:

As today was my last day of development time, I focussed on making sure that the game was playable all the way through to ensure that my testing tomorrow will go as smoothly as possible. A small change that I made was to move where I loaded in the animations from the altar class into the level loader, since I had more than one sprite with animations to load now. I also moved the spawner timer for the enemies from the Level_1 class into the level base class so that it can be access from new levels in the future. I fleshed out the game over state, properly pausing the scene. Before, I wasn’t pausing the physics correctly, as I hadn’t used the Matter specific way of freezing it.

Another problem I fixed was the enemies weren’t quite following their path correctly, this was due to the fact that when loading in the path, I was incrementing up to the number of items in the passed arrays, rather than iterating for each pixel in the width of the screen. Next, I implemented the enemies attacking the altar and being removed from the enemy array. I needed to add a new level property that tracked how many enemies had been spawned in. This was so that I could remove enemies from the array without infinitely spawning enemies in.

My main time sink today was creating a collision detection system. In Matter physics, you cannot determine which objects have collided with one another using functions built into Phaser, you can only detect that two objects have collided with one another. Initially, before I noticed that I couldn’t tell what was colliding, I looped through every enemy setting up collisions with all the tentacles. However, after realising that this wouldn’t work, I changed my approach. To figure out how I could tell what was colliding, I put in console logs for information on the two bodies that were colliding. I quickly realised that the only information that the event tracked was about the bodies themselves, not the objects that they belonged to.

In order to determine what was colliding, I created two for loops – one for all the monsters and one for all the enemies. Initially, I loop through the monsters and check if one of the bodies matches the body of a monster’s attack radius. If more than one tentacle is detected, then the event is exited. If no tentacles were detected, then the event also exits. I repeat this process but with the enemies. If there is a tentacle and an enemy colliding, then the tentacle attacks, else the event is exited. I found the keyword “instanceof” very helpful, as it allowed me to determine if my variables for storing the tentacle and the enemy had already been filled, enabling me to exit the event earlier if two tentacles or two enemies were colliding.

        this.matter.world.on("collisionstart", function (event, bodyA, bodyB) {
            var tentacle = {};
            var enemy = {};
            for (var i = 0; i < this.tentacles.length; i++) {
                if (bodyA.id === this.tentacles[i].hit_box.id) {
                    if (tentacle instanceof TentacleClass) {
                        break;
                    } else {
                        tentacle = this.tentacles[i];
                        break;
                    }
                } else if (bodyB.id === this.tentacles[i].hit_box.id) {
                    if (tentacle instanceof TentacleClass) {
                        break;
                    } else {
                        tentacle = this.tentacles[i];
                        break;
                    }
                }
            };

When this system was complete, I was very pleased with the outcome. However, it does occassionally freeze up the game when a new object is spawned and a collision event trigger within the same frame. This is something I will need to aim to fix in iteration 2.

Monday 18th:

Today I fixed a few last minute issues from the night before just to tidy up my code and make the game better for testing. The main task I completed was showing the cost of summoning a monster to the player so that they were better aware of if they were currently able to summon an extra monster or not.

Professional Practice

During my GCSEs and A levels I took part in work experience at a small game developers in central London. There I learnt about different industry standard tools and documentation such as:

  • Asana – a team organisation web app that allows you to assign tasks to different members, categorise tasks and give them due dates. It also allows you to post updates, and upload small files.
  • Game Design Documents – a written document that helps in developing an initial idea, fleshing out areas you may have forgotten or not considered and getting ideas on paper to present. They can be given version numbers and evolve alongside a project as aims change.

 

For this project, I have decided to use these tools to help track my progress and flesh out my idea. I find writing a Game Design Document particularly useful for patching holes in my concepts, as well as ensuring that as many aspects of the game have been considered as possible. Even though I will be working alone, I like to use Asana to give myself small, achievable deadlines to ensure that I do not get overwhelmed by the size of the project. Also, it helps when I hit a wall in one area of the game, as I can move to another section and still be able to achieve my goals.

I would also like to do a case study for a game from the genre, if I have time to do so.

The in-progress Game Design Document can be found here. I will update it as I complete the document.

Tower Defence Game Design Document

Introduction

In my game, you play as a blood mage who must defend their summoning altar from an army of pesky do-gooders and knights trying to stop your plan to take over the world. To protect your interests, naturally, you summon an army of demons, monsters and more to obliterate your attackers. As blood is spilt, your power grows, giving you access to demons as strong as Satan himself.

Overview

This tower defence game allows the player to become the villain and be the one corrupting the world with monsters. The game will be split into rounds of enemy attacks. These enemies will follow a set path across the level map, that the player will be able to clearly see and follow. Before each wave, the player will have the opportunity to summon units to defend the pathway.

With each enemy defeated, the player gains a small amount of blood – this game’s currency – that they can use to summon more monsters in the future. The player can also spend blood to upgrade monsters that they have already summoned, to make them more powerful than before.

To complete the game without losing, the player must successfully defend against all the waves of enemies without letting too many through as the player will have a limited number of lives.

Game Mechanics

Themes

Tower Defence

The player must defend their precious blood altar from an onslaught of “good guys” trying to stop their grab at world domination. This brings in the tower defence theme: the player can summon units to different locations along the enemy route to destroy any enemies that come within range.

Corruption

Blood mages are notorious for summoning creatures of twisted origins, created through sacrifices on their altars. I wanted to give the player the chance to experience the power of the dark arts and to revel in the magic at their disposal.

Verbs

What actions can the player take in the game?

Summon Monsters

Pick a monster that you want to summon and place it if you can afford its blood cost.

Upgrading an individual monster to make it deadlier.

Dismiss Units

If a monster is no longer fulfilling its purpose, the player can banish them back to the void where they came from. This creates space that the player can use to summon other horrors.

When the player dismisses a monster, they will get a partial refund for the original summoning cost.

Pause the Game

The player can, at any time, choose to pause the game to adjust settings or exit the game.

The Story

Main Story

You were raised as a blood mage by the Cult of Cthulhu, destined to bring about the world’s end. Finally, after years of planning and preparation, your time has come. Unfortunately, the leaders of the world are none too happy about your plans to destroy it and have sent their finest warriors to defeat you, too bad you have all of hell on your side.

Endings

The game will end when the player has taken too much damage to continue to summon monsters, or when there are no more waves of enemies to defeat. If the player is defeated, the world will return to normal, and any monsters that they had summoned will escape to the void. However, if the player is victorious, the world will be overrun by the creatures that you have summoned.

Scoring

Whenever the player’s monsters kill an enemy, the player gains a new supply of fresh blood to use to summon more monsters. As you defeat more enemies, your blood stores fill, allowing you to summon stronger and more powerful minions than before. You can also use your supply of blood to upgrade your existing monsters by feeding it to them.

User Interface

At any time, the player should be able to see how much blood they have that they can spend to summon more monsters, especially if the player is able to summon during an attack wave. Furthermore, when the player is considering which monster to summon, they need to be able to see a variety of information about that monster, such as cost, damage per second, damage type, and range. If the player is able to summon during an attack, then the menu for monster summons must not cover the screen at this time, or the game must pause while the player considers their options.

Gameplay

Start of Round

At the beginning of each round, the player will be able to use their supply of blood to summon some monsters before the enemies begin to attack. Once the player is happy with their troop placement, they can opt to start the round. This will cause the enemies to begin to follow the path.

Between Waves

After a round has completed, the player will have the opportunity to summon more creatures, dismiss any creatures they already had on the map, and upgrade their monsters. This also gives the player a chance to take a pause and think up a strategy for how they want their units placed for the upcoming attacks.

Enemy Behaviour

The monsters that you summon will have to automatically attack enemy units within range when their attacks are not on cooldown, as this is the main mechanic of a tower defence game. Furthermore, the enemies must follow a set path across the map, through the field of monsters.

Sound Effects

I want to add atmosphere to the game through the use of eerie music and sound effects. I would like to be able to work with a sound design student at another university if possible, so I can work with people from other disciplines, and practise co-ordination within a small team who are creating different parts of the same project.

Graphics

Since the game revolves around summoning monsters and mythical beasts to do your bidding, I want to create a dark atmosphere to make the game feel like you are overrunning the world with evil.

I would like to be able to create most of the visual assets for the game myself where possible. I will design creatures and their attacks on paper, before transferring these ideas to a digital medium. I will use pixel art as it gives me the freedom to create simpler animations, that will require less frames.

Technical considerations

 

How can the player place units?

In some tower defence games, the player is only able to place units within the bounds of a grid. In others, the player can place units freely, so long as they aren’t on the enemy path, or overlapping with one another. Before I begin creating my game, I need to decide which of these two methods to use.

 

Future Additions

  • Time control: The player would be able to pause/play the flow of the game at any time, as well as speed up the pace of the game to make levels pass faster. This is a common feature in tower defence games.

 

  • World progression: As the player progresses further into the game, the time period could change. The player would start out facing knights and peasants, but as time passes, they may have to face guns, flamethrowers and more.

 

  • Different enemies: Inside of a wave of standard enemies, there could be a few more advanced troops, with greater armour or that move faster, to make each wave more interesting, and to encourage the player to vary their monster placement in response.

 

Statistical Data

For my next project, I would like to create a tower defence game, either for mobile or tablet. Initially, I was unsure of which platform to choose, due to the prevalence of successful games within this genre for both platforms. For example, the balloons franchise is popular for both devices, and is easy to play despite a small screen size. This is due to the player’s freedom over the camera, allowing them to span over the battlefield.

Another popular tower defence style game available on mobile is Plants versus Zombies 2. However, despite a well-designed UI, the game interface can be too small on mobile, making the game more comfortable to play on tablet. This is due to the fixed number of rows to each level, forcing the player to always be zoomed out a specific amount. The ability to scroll across the map left to right mitigates some problems, but if the player had greater control over the camera, there would be less issues with mis-clicks.

Due to the prevelance of concerns with being able to successfully navigate the screen for mobile tower defence games, I have decided to make my game for tablet, to allow for more elements to be visible to the player without making the screen crowded.

To find some statistical data to support creating a tower defence game for tablet, I looked on statista. Firstly, I wanted to see how popular tower defence and other strategy-based games were. This information could give me an estimate for the reach of tower defence games and how well received they are by the mobile user base.

I found this graph particularly interesting, as it places strategy or tactical games as the most popular free-to-play genre in 2014 in France. I couldn’t find as specific information for the UK market, however I believe that it is important to consider the popularity of genres in other countries. If I wanted to have my game translated in the future, the french market would be highly considered due to the high potential for the game to be popular with a large portion of the player-base.

 

The next graph that I found was about past and future revenue for different game genres on mobile. Interestingly, strategy games made the most money in 2016, and they are projected to almost double in revenue in 2023. This shows that strategy and brain games are profitable to make, which could be useful in the future if I decided to release the game.

This graph shows the popularity of different mobile game genres in the UK. Compared to France, strategy games are significantly less popular, only holding a 10% share of the market, although you could argue that this type of game is still popular among players. Furthermore, this data is for Android only, and it includes paid games. Finally, a game doesn’t have to appeal to the majority of the market to be successful, so long as it satisfies a niche.

 

Tank Game – Reflection

When I initially got the brief to extend or edit the tank game, my mind utterly blanked. To generate ideas, I decided to sit down and create a list of different properties of tanks, and what you might find associated with tanks. This is how I got my first idea for expansion of having a super attack. Different tanks have differing equipment, including better missiles.

Rather than have the player be significantly stronger than all the enemy tanks (or vice versa) I decided to equip the player with a secondary shot type. I believed this was a good feature to add as often the player would die from simply having a lower rate of fire compared to the enemy tanks through a sheer difference of numbers. However, I still wanted the game to have some difficulty to it, otherwise it could become boring to play.

While thinking on elements that go with tanks, land mines came to mind. These wouldn’t utterly destroy all tanks, so I gave them the same amount of damage power as a standard bullet. I didn’t want them to damage the player, as I was still having balance issues between the player and the enemies, despite giving the player additional firepower. However, if I wanted to take a more realistic approach, a landmine wouldn’t be able to tell the difference between friends and foes, so I would have to make the player also take damage from them.

I did struggle with extending the tank game, as they aren’t a game style that I would personally play. I feel like this exercise was good for taking me outside of my comfort game of making games that I would want to play, and putting myself in the shoes of what other people may want or expect from a particular genre of game.

Tank Game – Production Process

You can find my version of the game here

To add a twist to the tank base game we were given, I decided to add in a super bullet attack for the player and land mines. The super attack was available on the Q key, and it was an instant kill if it hit an enemy; however, the player could only use this attack up to 3 times before they ran out of super bullets. The land mines would deal 1 point of damage to an enemy and were randomly placed through the level.

To create the super bullet, I needed to make a new physics group, with a maxSize of 3, to prevent the player from using it an unlimited amount of times. I adapted the existing try_shoot function to create a try_shoot_special function. My reason for creating a separate function rather than extending the existing one was that I needed to get a bullet object from a different group, it needed to handle damage differently and there needed to be a counter for each super bullet fired.

function fire_special(bullet, rotation, target) {
    bullet.setDepth(3);
    bullet.body.collideWorldBounds = true;
    bullet.body.onWorldBounds = true;
    bullet.enableBody(false);
    bullet.setActive(true);
    bullet.setVisible(true);
    bullet.rotation = rotation;
    this.physics.velocityFromRotation(bullet.rotation, 500, bullet.body.velocity);
    var destruct_layer = this.map.getLayer("destructibles").tilemapLayer;
    this.physics.add.collider(bullet, destruct_layer, damage_wall, null, this);
    for (var i = 0; i < enemy_tanks.length; i++) {
        this.physics.add.overlap(enemy_tanks[i].hull, bullet, special_hit, null, this);
    }  
}

As the special bullet was incapable of hitting the player (as only the player could fire them) I didn’t need to detect who was firing the bullet, I only needed to cycle through all the enemy tanks. Furthermore, when a tank was hit by the bullet, I didn’t need to call damage tank, instead I skipped that step and moved straight to destroying the tank.

function special_hit(hull, bullet) {
    ...
    enemy.damage_count = enemy.damage_max;
    enemy.damage();
    kill_bullet(bullet);
    var explosion = explosions.get(hull.x, hull.y);
    if (explosion) {
        activate_explosion(explosion);
        explosion.on("animationcomplete", anim_complete, this);
        explosion.play("explode");
    }
    if (enemy.is_destroyed()) {
        enemy_tanks.splice(index, 1);
    }
}

I still called the is_destroyed() method of the enemy, to act as a safety buffer in-case an error had occurred elsewhere in the code that caused the tank to still be alive.

While implementing the land mines, I had to shrink the image size, as despite being pixel art, it was massive and filled the screen. I used some trial and error to calculate how much I had to reduce the landmine’s size by, but in the end I was happy with the result. I wanted the landmines to be randomly placed around the screen, so I used the Phaser.Math.RND function to scatter them as best as possible.

for (var i = 0; i < land_mines.maxSize; i++) {
        var land_mine = land_mines.get(Phaser.Math.RND.integerInRange(game.config.width * 0.01, game.config.width), Phaser.Math.RND.integerInRange(game.config.height * 0.01, game.config.height));
        land_mine.setScale(0.035);
    }

My main criticism with the landmines now is that they can spawn on top of walls. If I had created a collision between the landmines and the destructible walls, this would have resolved the problem, and created a unique feel to each play of the game by changing the landscape slightly every time. Another spawn problem I had was that enemy tanks all spawn in the initial game area, making the rest of the level map feel empty and boring, I could resolve this using objects in tiled, and spawning tanks at those locations, but this would mean the tanks positions were fixed, and would remove an element of randomness from the game.

If I was to continue to work on this game slice, I would add in the ability for the landmines to blow up walls to prevent the overlapped spawning. Also, I have the issue of tanks still being able to shoot even after they are damaged to the point that their turrets were blown off. I feel it would add more realism to the game if the enemies were incapable of shooting at this point. Finally, I would make it easier for the player to tell how many super bullets they have left, as they currently just have to remember.

Web Analytics – Event Tracking

Here’s a link to the project

To add event tracking into the Spider Chase game, I used Google Analytics – a free service that allows you to see user events in real-time before displaying more in-depth statistics after 24 hours have passed.

To use Google Analytics in your website, you must include this code generated by Google in the head of your HTML document:

It was surprisingly easy to enable Google analytics on my web-page, and the instructions from Google Analytics explaining how to do so were easy to follow. Whenever you want Google Analytics to track an event on your page, you must create a gtag that contains the information that you want to track. Each gtag is made from a category, action, label and value. I used the category to denote the game that was being tracked, so that if I used Google Analytics for any future projects hosted on the same page, it would be simple to differentiate between events being generated by different games.

The event action describes what the player was doing to trigger an event to be tracked. The four tracking calls that I put into this game were die, restart, start and win. Labels are used to describe any values that you are tracking, in this instance I wanted to know how many attempts a player had, and what their score was, therefore these were the labels I used. Finally, the value is used to return any specific data points you want to track, which analytics will automatically provide average values for from your data.

To make the creation of the gtags easier, I created a small wrapper function that took in the different pieces of data needed for the tracking call as parameters and used them to generate the gtag. I set the event category as there was only one game available on the web page. By creating a wrapper function, I also minimised the risk of human error creating invalid gtags, or sending values that were not the intended variables that I wished to track.

To generate some data for Google Analytics to process, I sent a link to my game to a group of friends to try out. After 24 hours, this table was available:

By adding together start and restart calls, I can determine how many times the game was played – 15. Out of these games, 9 were lost, 4 were won and 1 exited the page before the game ended. However, if you compare this table to the Event Flow graph below, it shows that two people actually exited the game before finishing their attempt.

This shows that when looking at statistics, it is important to examine data in different formats, to minimise the risk of false assumptions. Interestingly, there is a similar exit rate regardless of if the player died or won the game, furthermore, no one successfully beat the game on their first try. There was one player who continued to play the game several times, before giving up without finishing their last attempt.

If I were to add to this project, I would want to create additional tracking calls at the end of the player’s run giving their x position, as this may indicate how far through the level the player managed to get before being caught by the spider. This information could be used to determine if there is one stumbling block that all players fall at, or if the level is uniformly difficult.

Reflection on Phaser

In the past, I have never worked with someone else’s library of code or game engine; everything that I have coded was my code only, therefore I was intrigued to be using a game engine for the very first time. Phaser 3 is the latest edition of the Phaser game engine, which gives you tools to create games in 2D using JavaScript. It has 4 key functions, that form the basis of your games: config, preload, create and update.

 

When creating a game completely from scratch, you must code everything yourself, allowing you to optimise code for your game. The drawback is that you must code potentially complicated maths functions to have basic physics and collisions. By using Phaser 3, I saved a lot of time that would have been spent creating collision and physics maths, as I could instead simply turn gravity on/off and use simple lines of code to cause objects to collide. While I did save a lot of time and lines of code, the collisions were simplified in places. Sloped tiles did not register as so, leaving them working like stairs despite being smooth.

On the whole, I found using Phaser 3’s built in arcade physics a faster solution than how I had been doing collision for past projects. I would like to explore Phaser’s other physics systems in the future, to compare their limitations and to expand my knowledge of Phaser’s capabilities.

 

During the development of my game, I had some friends who wanted to give the game a go on their mobile devices. Since I was using a game engine, I presumed it would be simpler to put in than coding by hand, as we did in the snake game. Personally, I had the opposite experience to what I was expecting; I could not understand how to implement the controls that I wanted, as the examples and API docs were not clear on the subject. I didn’t have the opportunity to follow through on this feature, and I wish I had simply used the same coding method as the snake game, rather than attempting to use Phaser’s.

 

When I am programming, my favourite part is debugging broken code to make it work. I enjoy how methodical tracing back through you code can be, despite my frustrations from the program not working. In particular, I can have a laser focus on the bug until it is fixed, and I can often resolve the issue in a single sitting. While using Phaser, my love of debugging was somewhat challenged. The tracebacks were significantly longer, as they often went through the Phaser engine’s code, and error messages were generally less helpful, as they would occasionally only give line numbers in the engine, or were about inaccessible properties/parameters with different names that you had given them. Resolving errors would often involve referring to the API docs, which are sometimes frustrating to navigate if you type in the wrong keywords to the search bar.

 

In conclusion, I am looking forward to working with Phaser more, despite my frustrations with parts of how it works. Several of my complaints – such as slopes not sloping and debugging – will be resolved by exploring more of Phaser and getting to grips further with searching the API docs. I still enjoy coding from scratch, as I feel as though I learn more about the core components of how to make the game work, but using an engine can be far simpler, and often quicker to implement complex features.