The Game
This game is titled ‘Turn Them Green Please’ where the player shoots a ball across an isometric game stage with the goal of turning the red block tiles to green. Any tiles turned to green would award the player points, which award additional shots. It can be played on Itch.io using this link
As of this release, the game is endless with randomized levels. I like the concept of this idea, but the execution definitely feels like a ‘minimum viable product’ stage. I want to revisit it at a later date while cleaning up its code.
Some Background
I chose this game concept as a way to focus on learning and getting more comfortable with Isometric Tile rendering of 2D assets.
Phaser was chosen as a framework for inputs and rendering graphics, but the isometric projection logic and all the physics were done by myself as part of the learning objectives.
When considering the scope of the game, I limited it to a flat plane with raised blocks, so that I could focus specifically on the more simple cases and some depth buffer checks.
The additional challenges of isometric sloped elevation and terrain was hence carefully reserved for a future Game A Week project, in order to reduce the risk of this project’s scope and keep it simple.
What Went Well?
Effective risk assessment and scoping of the gameplay concept
For this factor, I think my ability to stay very focused on the core learning point of getting comfortable with basic isometric rendering and physics, and not get distracted into other rabbit holes, is good.
I chose a game concept that was a simple as it could be that would require a minimum amount of work to be made ‘decent’ for gameplay. I also chose to release it a bit early once it met that minimum viable product stage, so that I can use my time to move onto different projects which will tackle more things I want to learn.
Another example of successful risk assessment was how earlier on, I did struggle a bit to find how to make ‘roll over tiles to change their color’ gameplay loop fun, as the first iteration would win the stage based off the percentage of tiles turned green.
This was just not fun during playtesting, but I am glad that instead of trying to make it fun, I chose instead to pivot the idea to something more tested and proven to work where the objective was just to ‘hit a certain amount of an object to continue’. I took the idea from Peggle but adjusted it to make sense with this gameplay loop. This was a good way to ‘cut my losses’.
I also chose not to implement or experiment with audio, because I was not confident that I had the experience and resources to implement them in a way that would not be annoying, with the scope I have. I need to build up my experience and my audio library and revisit adding sound again at a later date.
Improved code organization compared from last week
I chose to split up more functions and data into relevant independent classes and those classes into separate files while I prototype earlier.
TypeScript makes it easy to create multiple different files for different classes and I was able to effectively balance quick and rapid prototyping of functions inside a main file, while taking them out of the file into their own files at a productive pace.
I accomplished my learning goal
The main goals of becoming much more comfortable with isometric rendering was met. I didn’t copy any code or follow any tutorial too closely. The main resources I used was a few screenshots from Introdution to Isometric Movement in Games in order to get the definition of the coordinate system and the tile size, and the depth example from the Phaser examples titled Isometric Blocks.
In the end, however, my code ended up being quite different and honestly in a way that I understand and can work with much easier. I did not have to do the half offset when converting to and from my coordinate system, and instead it was applied by multiplying the isometric height and width with respect too coordinates.
I also ended up being comfortable enough to create my own functions to convert to and from the Isometric and World coordinate spaces, as well as the understanding in order to calculate my physics model relative to isometric space and only realizing to convert it back to world space only for rendering.
Being able to understand what I am doing enough and be confident enough to be able to reject a tutorial or example’s suggested way of doing it in favor of my own preference is good. I can’t wait to explore isometric rendering stuff again but with the additional challenges of occlusion and more complicated height depth perspective.
What Could Have Been Better?
Lacking Polish
The game lacks a lot of ‘polish’ and ‘juice’ that could benefit it easily. Examples of this is the lack of UI, the lack of camera zoom and ‘drama’ when hitting the last block, the lack of screen transitions, the lack of sound effects and other game flow things.
When developing the game, I chose to scope down and avoid the potential complication and bugs of polish due to a lack of experience in that skillset, opting instead to revisit this same game and concept to expand on outside of the ‘Game a Week’ scope.
This factor is also why the next game on the list is going to be very focused on polish, menu and UI related features, being in the idle game genre, as I have identified it as a weakness of mine.
Still not fully serializing data or adding runtime editing tools for hot reloading
For this factor, I created a separate TypeScript file that holds an exported class that contained nothing but static variables which represents various data variables such as the points needed to gain a life, the starting number of shots, how many random blocks should be generated. This is a good improvement over last week’s game, where I was storing these static variables without much organization.
Despite this, I did not implement the additional important step of reading and saving these values to a json file (or other data file) that can be tweaked and adjusted by the designer during runtime. This meant that the project still needed to be redeployed to test changes, which hurts the game design and discourages iteration.
Next week’s project onwards, we must implement the runtime hot-reloading of data driven elements from the very start as a priority.
Still took too long to get to the gameplay loop
For this factor, I am not entirely sure if it was an oversight or just a result of lack of experience. I was aware of how last week, the game really comes together once the player is able to ‘win’ and ‘lose’, and hence a game project needs to reach that state in development as soon as it could for a mechanical game.
I wanted to reach that state with this game early too but had trouble coming up with the overall game concept and implementing the isometric physics and rendering related requirements for them as early as I would have liked.
The gameplay loop only came together on Saturday, and by then it was the late stages of the game’s development in the week and code would need to be refactored to accommodate new features and polish.
If the game’s gameplay loop was completed much earlier in the week, the pace of development and features to focus on polishing and refining it could’ve been done better.
Ambiguous responsibilities of code
There were a few variable names or functions that were confusing because it was unclear which class was supposed to be responsible for which feature. For example, my tile’s grid class was managing and tracking which tiles were green and which were not… but the tile itself was also tracking that information.
This creates the infamous ‘spaghetti code’ problem where variables and classes kept being passed around to update information in different places, making it hard to keep track of who is altering the data. Its almost just as bad as having global variables everywhere.
I will need to be more careful in my planning to ensure that the responsibilities of classes and functions are more independent and clean.
What have we learned that we can apply moving forward?
Implement runtime GUI for editing variables and hot reloading them
I need to start using something like dat.gui so that I can customize variables while playtesting. The next project must implement this early, but the hustle pace of development makes it hard to ‘get around to it’ otherwise.
Rush to the core gameplay loop as soon as possible
This is just too important to neglect. It doesn’t even matter if the gameplay loop would change, but the player being able to ‘lose’ while having a goal is something that needs to be reached urgently in development.
It doesn’t matter if the code is messy, confusing and bug prone if this point is reached extremely early in development, as we can then refactor and organize our code in a coherent and easy way using the first iteration of the gameplay loop as a base. It also helps with motivation and further planning if we can clearly play something, anything, in the game.
Bug Bounty Board
Keeping track of the bugs encountered into a separate list as soon as they are found and hence fixing them based off importance would be good practice moving forward.
Comments powered by Disqus.