🏐 Ball Tale 🏐
A game by Siim Raudsepp
Final build link
What is it?
Ball Tale is a 2D adventure/metroidvania-ish platformer. You control a ball through uniquely themed areas. Each area has its own difficulties, puzzles to solve and bosses to beat. The game also features an upgrade system.
Heavily inspired by An Untitled Story
Project plan
The goal of this project is to have a go at making my own 2D platformer and testing what works/what doesn't.
The plan is to first work on getting some of the controls implemented, after which I will add a static world and enemies. Later I will add more abilities to the ball (for example a speed boosting mechanic), boss fights and some upgrades to be found throughout the world. Sometime down the road I will work on the soundtrack and sound effects. The art will be made as things progress. I would also like to add a nicer main menu to the game near the end.
Ideally I would also like to have some interactable NPCs in some areas that you could chat with to get some information about the world or buy items from, but initially it is out of scope of this project. I have also thought about adding some multiplayer functionality (high scores, VS mode), but it will be clearly out of the scope of this project.
The mechanics will be as simple as possible because I don't want the player to get overwhelmed by the amount of different things he/she can do at once.
Mechanics currently planned to implement in the game (during the project) are as follows :
- Rolling around
- Jumping
- Rebounding off walls
- A self-boosting mechanic where the ball is suspended in air for a few seconds and the player can choose a direction to be shot in with extra speed. I think this will really make up for some fun moments in combination with the physics
- A shooting mechanic(haven't really thought about the details yet)
Technologies/Software that I will be using :
- Unity - Game engine
- Audacity - Sound editing and possibly recording
- Paint.NET - Programmer art :)
- Reason - MIDI editing and recording
Milestone 1 (09.03) - The Ball
Goals
- Setup the Unity project and repository - (1h 30min) ✔️
- Create empty project in Unity - (15 min) ✔️
- Create repository - (15 min) ✔️
- A test scene with a few rectangles here and there to test the functionality, nothing too fancy - (1h) ✔️
- Add TextMesh Pro to the project - (This will take 5 minutes or 5 hours depending on how Unity feels about it) ✔️
- Implement at least 50% of the planned movement/controls: - (4h)
- The player can move left and right - (1h) ✔️
- The player can jump up - (1h) ✔️
- The player can bounce against terrain and will rebound (My initial guess is physics materials in Unity) - (2h) ❌
Progress
Setting up the repository and Unity project went really smoothly and I even got TextMesh Pro to import correctly on the first try.
After that I started to create a test scene. Initially I started out with just placing some rectangles on the scene, but then I remembered that using the tile map is the easier (you could even say the right) way to do it. I scrapped everything I had and re-implemented the scene. Adding collision to it was surprisingly easy, too. Just attach a Tile map Collider 2D component to the Tilemap gameobject and you're good to go.
Up next was adding the ball that the player controls to the scene. I hastily popped open the 2D components menu in Unity and saw that only Sprite was the only thing I could use to represent the ball in game. After some time playing around with it and having problems (like the ball wasn't perfectly round because I do not know how to make a perfect circle in P.NET), I decided to take a step back and do my homework. It turned out that 3D primitives also work in 2D nicely, you just have to add a 2D Collider and Rigidbody to make it work properly. There was also a problem where the ball was too dark, no matter what colors or settings I tried, but I quickly realized that it's a shader problem (I had no light source in my scene). So I changed the shader of the ball to unlit, after which I had the right color I wanted on the ball.
With that out of the way, I started implementing the controls. Moving left and right is implemented by changing the horizontal velocity of the ball. Jumping is implemented by giving an impulse to the ball. This gave me good enough controls to start implementing the main part of this game : bouncing around, although the gravity and some other parameters will have to be tuned at a later time.
I knew before that physics materials are used to implement this sort of behavior I am looking for, so I started with that. Turns out you just have to create a PhysicsMaterial2D and attach it to the player. It worked right away. After playing around with the settings some time I found that using {$ \frac{\sqrt{2}}{2} $} as the bounciness coefficient works nicely.
But there was another problem with the collisions when bouncing against the wall...
After researching the problem for 4 hours, I couldn't come up with or find a solution. Since the movement was already sloppy in other parts too, I decided it would be wise to start from scratch and implement player controls using raycasts. I found a nice tutorial on YouTube that explained and implemented raycast-based controls in depth. So I started off with that and right now I have the movement, variable height jumping and camera movement working, although the collision detection needs some work on the edges.
The bouncing implementation will be pushed to the next iteration, since I cannot use physics materials anymore to get it for free. I have done a bit of research into it and found a nice Wikipedia article on how bounces work in real life.
All in all, I am very delighted with my progress in this milestone. My only regret is that I didn't work on this more actively (instead of working only 3 evenings out of all the time), because it was only a day before the deadline that I discovered that I couldn't fix wall collisions.
Milestone 1 build link
Currently SPACE is used to jump, LEFT and RIGHT arrow keys are used to move horizontally
Milestone 2 (23.03) - The Environment
Goals
- Implement the self-boosting mechanic - (2h) ✔️
- Implement bouncing around and against walls - (4h) ❌
- Implement floating texts or signs to show messages to the player - (2h) ✔️
- Design a starting place and implement tutorial in it - (4h) ✔️
Progress
In this milestone my progress slowed down significantly. Mainly because I couldn't get the ball bouncing mechanics to work. After spending a few hours on that, I decided to move on and started implementing the self boosting mechanic. The implementation itself was rather easy, I just calculated a direction vector based on the input given and added velocity to the ball in that direction. But I also decided to add an arrow that shows the direction to shoot the player in. It was harder than I thought, because I had to get the arrow to rotate around the player. At the end I gave up and went with a hack : I created a sprite that extended through the player so that the middle would be at the center of the player.
After that I changed the movement controller to use CircleCast2Ds instead of raycasts to check for collisions (thanks Joosep). Doing that fixed the clipping issue but now the ball was standing on 1 pixel of ground and would not fall off. Couldn't figure out a solution to that one yet.
I also decided to add a sprite onto the player, but this turned out to be a little more difficult than I expected it to. Since I was using a 3D primitive sphere for my ball, the sprite I added onto it ended up being wrapped around the 3D object and it didn't look too good. The solution was to add a circle shaped sprite as a ball - it turns out you can do it from the Unity editor create menu.
Next off I started to make the signs to give information to the player. It was a rather straightforward generic implementation with the ability to change title and text per script.
But this part also presented problems to me : when you open the dialogue, the time scale of Unity is set to 0(by me) to prevent movement and other game mechanics still working. But this also means that the Unity built in collision events do not get sent anymore(I was relying on them to check which sign is the player colliding with). The solution for me was to not use the OnTriggerStay2D function for continuous collision, but check for enter and exit calls and open/close dialogues separately in Update().
Next up was making the tutorial level. I drew some simple grass in P.NET and added them as tiles to the tile palette. I also wanted to add some grass in front of the player so it wouldn't look so bland but I was hit with yet another issue : my only tile map had a tile map collider attached so the foreground grass also collided with the player. The fix was surprisingly simple : you can add multiple tile maps as a child to a grid object and they will work nicely together. This meant for me that I could have the main layer that deals with the collisions, a foreground layer that the player can move behind and a background layer for things behind the player. I can even add more layers if I feel like it, but for now those sufficed.
I'm not really pleased with the results of this iteration, as I had planned to get more done. This was a valuable lesson to me to not take on too much (or at least do a bit more research before planning my iteration goals). It's just as Raimond said : "Only plan the features you can surely get done for the end of the iteration" (or at least something along those lines :)). As for the bouncing mechanics, they will be pushed into the unforeseeable future, because I need to rethink can my game really make use of bouncing. Currently, I cannot think of any good use case for making the ball bounce.
Milestone 2 build link
Currently UP is used to jump, LEFT and RIGHT arrow keys are used to move horizontally, X is used for interaction and Z is used to boost yourself.
Milestone 3 (06.04) - Simple Enemies
Goals
- Create 2 basic enemy types : 1 that moves left/right on ground (like goombas from SMB) and 1 that flies left/right or up/down - (6h) ✔️
- Create a basic spike trap that damages the player - (3h) ✔️
Progress
I started out with making the 2 enemies : 1 flying and 1 ground. Since the ground enemy seemed more interesting to make, I did that first. I spent a few hours thinking of a good way to implement this so I wouldn't have to refactor too much later and then got something done that maybe resembled what could be called 'good code'. For the base I made a new type of raycast collider : a box. On this box I could easily build my enemies' code from my existing player movement code. That got done rather fast and so I moved on to getting it moving. That was surprisingly easy too, I just added constant velocity to it and let the collision with walls change it's direction.
Thinking that the flying enemy was as easy as that, I did that next. I used the same code for the flying enemy, only removing the gravitation and adding vertical movement support too. Movement using collisions worked out of the box and I wanted to add some more features : turning around in air and non-straight paths. I thought I could just check for some set max distance and reverse the velocity when the enemy was too far from it's starting position. But that didn't just work out because the enemy couldn't move near enough to the starting position and the direction got reversed again. To solve that I did a quick hack : created a Coroutine which disabled turning for some time. Not too happy about that but it did solve the problem. The code is below (PathMiddlePos is the starting position of the enemy at the start of the scene).
if (Vector3.Distance(transform.position, PathMiddlePos) > _unitsToMove && _unitsToMove > 0 && !_justTurnedAround) { moveSpeed = -moveSpeed; StartCoroutine(TurnAround()); }
For the non-straight movement paths I looked into extending the Unity editor. Turns out there are multiple different methods in the Handles class to get Unity-like position, rotation and scale controls. I only wanted to control movement paths in the editor so I used PositionHandles. To extend Unity editor you have to create a new class and add [CustomEditor(typeof(<classnamehere>))] before the class definition. I got the path start and end positions to work quite fast, but getting the enemy to move between those was harder than I thought so I just left it for some later time.
Up next was to make the enemies hurt the player on collision. The damage part was just checking for collision and reducing HP of the player. But I wanted to add a bit of invulnerability after collision so the game would be more forgiving. This turned out more time-consuming for me than I thought : when player didn't leave the collider the damage wouldn't re-trigger. I solved this by making yet another Coroutine and setting an animator boolean for some time to disallow damage triggering again and after that time I rechecked the collision. Below is an excerpt from my code.
IEnumerator PlayerDamaged() { _animator.SetBool("Damaged", true); var timer = secondsInvincibility; while (timer > .0f) { timer -= Time.deltaTime; yield return null; } _animator.SetBool("Damaged", false); }
I also wanted to add some kind of a reward for killing enemies, so I set up a simple currency system. But for that to work, some way to kill enemies was needed. I made a new collider on top of the enemies and checked if player collided with them and wasn't invulnerable. If not, kill the enemy and gib monies. A little upward boost was also added to get a more pronounced killing effect (as opposed to just falling through an enemy).
With all that out of the way I finally got around to making the spikes, but that was just making another sprite with a collider and damaging the player. All of this would have been useless if the player couldn't really die. For that I added in life checks when damaged and a simple death screen.
I also took into account some of the recommendations of other people attending this course. First I made the arrow animated to indicate that something is changing while you are charging, but I think this would need more work and a different kind of animation, because currently it is unintuitive.
In addition I changed the sign mechanics so walking away from them would also close the sign text in case the player didn't know how to close signs. This felt smoother gameplay wise too.
I also got some UI work done to show the health and currency to the player, but these are just placeholders for now until I start working on them later on.
I'm really happy that I got so much done this milestone. Although the milestone took over 2x as long as it should have, I got everything done. Also it feels like I have a personal Ludum Dare every 2 weeks on Fridays : since I always underestimate my progress I have to borrow time from friday mornings to get it done in time and since you want to get as many features in the work is done really fast, no time for thinking (which is fine in my opinion, usually the biggest problem is getting stuck in thinking how you could do it better).
Milestone 3 build link
Milestone 4 (20.04) - Things to do
Goals
- Add a shop interface (and shopkeeper) where the player can buy items using currency - (4h) ✔️
- Extend tutorial to support shop - (1h) ✔️
- Add a shooting mechanic - (3h) ✔️
- Fix player staying on edge - (1h) ✔️
- Change sign at the beginning that says to use X - (.5h) ✔️
Progress
I started off with implementing the shooting mechanic. The implementation itself was really straightforward (just giving the shot a direction and moving it in direction until reaching a set maximum range, I also added a cooldown between shots), but some funny bugs creeped out. Firstly, the shots themselves acted as collider for the player, so it was possible to jump to the sky using them. This happened because I accidentally set the shot to be on the Collision layer.
Secondly, it was possible to use the shots collision event to read signs from far away. Maybe this could be turned into an actual game mechanic, but for now it is unwanted so I patched it. It turned out that my little "hack" to read signs had a bug in it : anything colliding with the sign triggered allowing interaction with the X key :(.
The next thing was to add collisions with different objects in the world. This took more time than I would like to admit. After digging around in my code for an hour looking for the reason why my shots didn't collide with the walls, I found out that I had hard coded the radius of the circle cast. It was always 0.5 units (the radius of my ball :)). After fixing that it suddenly started working.
Since I also wanted to be able to choose for each object in the world how it reacts, I based my collider checking on layers. For this, Unity provides a helper called layermask, which brings a drop down list to the editor. From there you can select which layers are a part of your mask. To make use of this layer mask, I added a few helper functions that I found on the internet. One allows me to check a layer against the collisions layer mask and the second one helps to check against any layer mask.
public virtual bool IsInCollisionMask(int layer) { if (collisionMask == (collisionMask | (1 << layer))) { return true; } return false; } public virtual bool IsInLayerMask(int layer, LayerMask layerMask) { if (layerMask == (layerMask | (1 << layer))) { return true; } return false; }
Using these functions, it is trivial to give new objects the ability to be shot or to be collided with (or even add new checks using layer masks). I could have also made them into 1 function, but it really doesn't bother me.
One final problem I had with the shooting mechanic for now was that it reset the shooting direction upon jumping again. This meant that the player couldn't just stay in place and shoot while jumping. To fix this, I remembered the last direction and only changed it when the x velocity was bigger than a threshold.
Up next was adding a shop (and a shopkeeper) to the world.
At first, I started overthinking and tried to make a really complex and dynamic implementation. The initial result was that I over-engineered everything (at one point I had a gameobject that had a reference to another gameobject, which contained the component I needed, which had a reference to the field I needed). Everything just to hold upgrades in slots...
After some hours of struggle, I gave up and made the easiest thing I could think of. Now there is just a shop with 3 slots that each show the item and the price. It is possible to select the item and buy the current selected item. After buying, your money is taken away and the item's stats are given to you (currently, there are only health upgrades on sale). Also, if there are any items that couldn't be shown due to slot limits, they replace the old items place (basically and literally a queue). Currently, there are no animations upon buying something and nothing really notifies you what the item you just bought gives you. This is something I'd like to improve in there future.
I also changed the sign at the beginning that says to use X to interact: now it is a text with a bigger font and better contrast with the background.
Finally, I started working on fixing player staying on edge with only a little of it colliding with the ground. Initially I had fears that this will take many hours of implementing, but it wasn't so hard after all.
I went with the algorithm that was suggested to me during the project milestone presentations. The algorithm is as follows:
1) Cast 3 rays down : 1 from the left side of the ball, 1 from bottom center and 1 from the right side of the ball.
2) Based on which rays are hitting the ground do:
If done correctly, each frame will add a bit of velocity and the result will be that the player will fall from the edge.
To check for which combination of rays are colliding with something, I used a bitmask (there is also a nice article explaining various bit operations and how you can use them in your games here, but I didn't want to go so deep). This means I summed up the values ( isLeftColliding * 1 + isMiddleColliding * 2 + isRightColliding * 4
) of individual bits and checked if the sum was 1 or 4 (only 0 + 0 + 4 can produce the sum 4). All other combinations are currently unused, but maybe I'll find an use for them.
The initial implementation added too much force, so I was getting shot off edges.
After fixing this, it now works correctly. I even made the force changeable.
All in all, I am delighted with the progress I made this milestone. I got everything done, and also a bit extra in each thing I did. I also tried tracking my time this milestone. The results are below.
From here it can be seen that I spent about 6 hours longer than I had planned (~9.5h) on this milestone. The things that took most of the overtime were adding the shooting mechanic and adding the shop. This helped me gain some valuable insight into how long things really take (before I was just guesstimating the time spent, but now I have real data to look at). Using Toggl wasn't really as mentally taxing as I imagined. Maybe next milestone I could even subdivide the timers by what I am currently working on (mechanic or something like that).
One thing I uninstalled after day 2 was the Toggl firefox add-on: One morning it reminded me with a pop-up to start my timer today. But it wasn't the time to work on the project, so I pressed the X button to close it. I guess Toggl interpreted it as starting the timer and by the end of the day I discovered that I had clocked 9 hours on my timer. I had to delete that time period and the add-on after that. Shame.
Milestone 4 build link
Additions: C key is used to shoot and buy
Milestone 5 (04.05) - Boss
Goals
- Add a boss fight into the end of tutorial - (8h) ✔️
- Add boss movement pattern - (2h)✔️
- Add a way for the boss to interact with the player(take and give damage) - (2h) ✔️
- Design a fighting place - (1h) ✔️
- Add a health bar to the boss - (1h) ✔️
- Add a sequence taking place after the boss fight - (1h) ✔️
- Add the shooting mechanic as an upgrade sold in the store - (1h) ✔️
Progress
This iteration I started off with making the boss fight area. I opened P.NET and started designing tiles to make my area from, but then I realized that using the same tiles would make the area boring and making many tiles takes too much time. So I tried another approach: I used the grid in P.NET to draw the whole area and then I fit it so it matches the tilemap in-game.
After that I just added empty collision tiles where needed. This also had the benefit of making the walls perfectly straight, meaning that the collisions didn't break.
Up next was drawing the boss sprite...
...and then making it move...
Movement consisted of moving it diagonally and on collision with a wall, reflect it off the wall using Vector3.Reflect(_velocity, wallNormal)
Adding collisions and damage to the boss was trivial thanks to the physics framework I've built during the project. Adding boss patterns needed some thought, but in the end I decided to go with a simple state machine that has actions defined for each state. This meant it was easy to stop the boss from being damaged during non-vulnerable state and also add the ending sequence, where the boss sucks you into a vortex. Nothing more planned for now.
This milestone I did get much work done, but I feel that the quality of code suffered due to cramming all work into one day. The quality of code is almost comparable to that of a hackathon. I realize I created technical debt for myself in the future, but hey, at least it works right now :). Time spent can be seen in the figure below.
Milestone 5 build link
Milestone 6 (18.05) - Music, sounds and others
Goals
- Compose and add boss fight theme - (2h)✔️
- Compose and add tutorial theme - (2h) ✔️
- Compose sounds - (3,5h) ✔️
- Jumping sound - (30m) ✔️
- Shooting sound - (30m) ✔️
- Boosting sound with build up - (30m) ✔️
- Buying sound - (30m) ✔️
- Getting hit by something sound - (30m) ✔️
- Hitting something sound - (30m) ✔️
- Boss collide sound - (30m) ✔️
- Add all the sounds to the game - (1h) ✔️
- Add gamepad support(Xbox controller support planned, but I guess it works for every gamepad) - (1,5h)✔️
- Start working on main menu and pause menu ✔️
Progress
This milestone I started out with adding gamepad support, since it felt like that could be added in the planned time (others would take longer). After searching the web for a while, I found out from Unity wiki that Unity reports pressed buttons differently for every OS. This is not really a problem for me at the moment because gamepad support was planned only for the demo, but it could become a problem when I develop the game further. I will have to look into it in the future, to see if there are any well thought-out input managers that handle cross-platform with ease.
Anyway, I went with the Windows buttons. But for a game pad to actually use the controls I had defined, I needed refactor my input code to use axes and buttons instead of hard coded keys. This meant that Input.GetKeyDown(KeyCode.C)
became Input.GetButtonDown("Fire3")
and so on.
The movement was luckily already mapped to the horizontal and vertical axes by the past me, so I didn't have to change that part much. Only thing I did change about the movement was to use full speed movement, no matter how far the player pressed the analog. This was done because it felt frustrating to jump up and start boosting and not boosting as far due to not moving at full movespeed.
Next up was working on the sounds and music. Since I have played the piano for about over a year now and I own a digital piano that doubles as a MIDI controller, I decided to make the soundtrack to my life to this game myself. This turned out to be a really time-consuming task. I quickly realized how hard it is to choose sounds that satisfy the following conditions:
- at the right pitch;
- using the correct sample (for example organ,brass etc.);
- doesn't feel too off compared to other sounds;
- fits into the visual art style.
I made a few sounds and then moved on to composing a tutorial theme. I quickly found some samples that sounded good and made a baseline using them. After that I recorded a melody which was merged with the existing baseline. To iterate on different samples quickly, I just recorded myself playing using Audacity and then listened to the result. When I had chosen what to play, I re-recorded the theme in Reason to get rid of the background noise the microphone produced and then edited the recordings together in Audacity. Finally, I imported it into Unity and added relevant lines to the code to make it play when in the tutorial area. The same process was repeated to compose a theme for the boss fight and add it to the game.
I continued with making the sounds, getting a little frustrated, but in the end I got them done somewhat. In the future I would certainly like to revisit the sounds and remake them. In my opinion, making music requires a lot of iteration, even more so than writing your thesis or programming...
After all of the milestone goals were met, I started working on the pause menu and the main menu. Since I remembered watching a really good video about making UIs that are maintainable and well structured code wise here, I re-watched that video and tried my best to copy from the guy speaking. Nothing more was really done in terms of main menu and pause menu, the only thing being done was an initial mockup menu and some buttons wired to functions.
This iteration was yet another success. I got many new things done and even more bugs fixed. The only thing I regret was not starting the composing process sooner, but this was expected as I had my thesis deadline 4 days before this deadline. I didn't also use Toggl this time because I felt that constrained my creativity for the composing part.
Milestone 6 build link
Final Presentation Milestone (25.05)
Goals
- Finish main menu and pause menu - (5h)✔️
while(true){ fix_bugs(hours:3); // TODO : FIX BUGS }
Progress
I started off with making the main menu because that seemed more important. Since I the layout mostly done from the last iteration, I focused more on making it look cool. This consisted of adding some moving parts like the enemy and the ball jumping in the background. I also added falling stars using the Unity particle system. Final touches were added by adding blur to it and making everything in the scene except the stars black (a material with a black color was added to all sprites).
After that I finished making the buttons work and added some additional options. I also found a button highlighter script off the net, which I changed somewhat to fit my needs. The buttons no longer get scaled bigger, they change color instead and using mouse to select doesn't keep 2 buttons active at the same time. All of this is also usable with the gamepad.
The pause menu used the same framework (buttons with a blur in the background) but didn't have moving objects in the background.
A big part of this menu was also adding save game functionality. I used an Asset Store asset for this: Save Game Free. This gave me a comfortable framework to build my savegame system on. But this was not easy as serialization in Unity is not support as much as I'd like. For example, you cannot serialize a Vector3 unless you build a wrapper class that supports serializing it. Luckily the asset provided these classes and I mostly just described what to save and what to load.
After implementing the promised functionality, I continued with polishing the game to make it more presentable. One of the first things I added was to change the boosting animation to something that better communicates to the player that it means the time left, not the boosting strength.
I also added buttons to different signs and interfaces describing what to press.
This was all I did for this milestone. During the morning before the project presentations I also found a critical bug where the boss health bar didn't decrease in health whatsoever. Spent 2 hours tearing my head out, but in the end it got fixed. It was just a misuse of the Lerp function. :D
Final milestone build link
Post project presentation additions
During the project presentation I got a lot of feedback and found lots of bugs. Some suggestions were implemented, some were not. Some will be probably implemented in the future. Below is a list of changes I made after the presentation:
- Always display the current amount of money the player has when using the shop
- Added a bit of oomph to the boosting
- The boosting now remembers the last direction chosen so holding the directional button is no longer necessary to get boosted
- Fixed boosting being dependent on how far the analog stick was pressed
- Added descriptions to the shop describing what the current selected item does
- The boosting arrow no longer starts at the right side and then moves to the direction chosen
- Fixed a bug where some items could be bought even if the player had no money
- Added directional shooting while boosting
- A floating damage text now appears when the player gets damaged
- The death screen now properly shows what button needs to be pressed on the gamepad
- Added keyboard keys in addition to the gamepad buttons to the signs and interfaces
- Other minor fixes™
Closing Thoughts
The project turned out to be far more time consuming than I had expected. Even if I had planned to sink all my free time into this project, my bachelor's thesis took most of my time. But still I put like 15-20-25 hours of work into every milestone.
All in all, I'm happy that this thing works somewhat okay, even if the codebase is hacky. There were some times where I thought that soon this thing will become unmaintainable and adding new features will take longer and longer. But suprisingly the game held together and didn't fail on me(haha).
I also learned a lot about workflows for different assets (art, music and coding) and in the end I could iterate fast on everything I did. This came really handy a few days before the presentation where I wanted to get as much as possible into the game so I had to work fast and efficiently. In addition I got some much needed skill in time estimation and project planning. While this project is not as I envisioned it in the beginning, I find that the game I have now is even better than the original.
This project page/blog has also been a huge successs for me. Writing these kinds of blog posts about the inner workings of my game and the whole process has always been a dream for me (I myself like to read these kinds of posts). So with this project I also took it upon me to make that dream come true and do a "little" writeup for each iteration (this thing is longer than my thesis in word count lol). Some times it was really hard to motivate myself to do the progress writeup, but in the end I still got it done. Even right now, on the 7th of June, when the coursework has officially ended a few weeks ago, I finally found the motivation to write about the presentation milestone, the post presentation changes and the closing thoughts in-depth. I even made the demo video I promised to make (it can be see on the top of this page).
I do not know what the future holds for this project. I will probably continue tinkering with it a little but no plans for active development. Since I have the core mechanics down pretty well, I can now move on to making more content. If this game ever gets finished and released, I am planning to keep it freeware and open-source. So if anyone reading wants to collaborate on this, hit me up.
I would also like to thank my coursemates and the lecturer of this course, Raimond-Hendrik Tunnel, for the continuous feedback on this project. Your ideas helped make this game better than I would have ever done myself.
- Siim Raudsepp