Prototype 2: Torch Lighter
In which we learn who lights the torches and I learn the pains of building 3D third person platformers.
Get it: here
Well ladies and gentlemen that is prototype number two in the book. If we go to the timekeeper we will see a tweet from yours truly showing Torch Lighter went live on the 28th, bang on schedule. You will note that this blog post did not, but you try writing a lengthy wash-up / announcement after coding for 12 hours on a Saturday!
Torch Lighter is a score attack based third person platformer, in which our as yet unnamed heroine tries to light all the torches present on a map before run-of-the-mill heroes turn up to fight “evil-doers”. I explained the premise more in my announcement post so won’t go into too many details regarding the plot here.
I aimed with this prototype to match the content of my first game Captain Bandana, I wanted a platformer of 10 levels in which the player sprints around lighting torches with some light story elements and multiple abilities. I demonstrably failed to get that, there are seven main levels in the game (with a hidden bonus 8th level), no additional abilities beyond running and jumping and absolutely no in game plot putting me somewhere behind Megaman 2 on the great video game story scale.
I am nevertheless incredibly proud of the game, it is a complete experience offering a level of replayability not found in my previous prototypes and is the most technically complex of any the games I have yet made. The platforming is tight and controllable, working well for the game and the scoring system offers players incentives to keep moving (which fits in well with the concept of clearing the level quickly to stay ahead of the “real heroes”).
(If you are uninterested in the technical minutia of programming I suggest you move on to the design and building section)
As I eluded to in my last blog post it was a much more challenging prototype than Sunwalker despite its relative visual simplicity. My time was split around 60/40 writing code versus designing and testing the game. First I had to build a third person controller that offered a smoothness of motion and tightness of controls for precision platforming. I built that out of my study of the Unity Standard Assets ThirdPersonController.
I butchered portions of code into something I rather narcissistically called the TyasThirdPersonController. I coopted their ground detection code (which was on point!) and the flags they built into their AnimationController while discarding the animation based motion they utilised. Unity offers a robust physics solution using RigidBodies and Mesh Colliders and initially I tried to use a method RigidBody.ApplyForce for movement, but I found it took too long the the player to accelerate and decelerate leaving a hero that felt like they were running on ice the whole time. Instead I opted to manually move the player without the RigidBody method, while still utilising the gravity and collision detection that it offers.
The other main coding challenges lay in game flow. I had to write a new level loader, based on one that one of my best mates wrote for an earlier project we worked on. I altered it to use a coroutine which essentially allows other process to run while the loading takes place (the idea being that I can do animated loading screens at a later date). The new LoadController handles basic level loading and has been built to be highly reusable. It is in essence a parent class, which allows me to very quickly make game specific loaders. For example the TorchLightLoadController handles tasks such as resetting the UI, setting new time limits, providing references to any game objects that need them to function. All functions specific to this prototype, while still using the shared code base of the parent LoadController. If you are interested in learning more about inheritance based programming I suggest you start here.
Designing and Building
As I mentioned earlier I originally aimed to build 10 levels for Torch Lighter. The idea was that each would be built to represent a different archetype of a level wherein torches might need to be lit. Coding the game logic took a lot longer this time around and I found myself quite behind schedule by Wednesday the 25th with six levels still needing to be built. I decided then to cut down my work load, reducing the ten planned levels to seven. This left me with four to build in three days, a much more manageable task.
More than that I felt that 10 levels would be stretching the mechanics in the game thin. I had no time to code additional elements such as moving/collapsing platforms or enemies, or to add extra torch lighting abilities and the basic score driven run and jump gameplay loop only remains entertaining for so long. With that in mind I was happy to remove certain planned levels and focus in on the best ideas I had.
Design for each level had to take three factors into account: Uniqueness, Scoring and Player Movement. I wanted every level to feel unique with the exception of the final level which contains elements from multiple earlier ones, and the hidden bonus level which was more of a fun callback than a new piece of design. Levels 1 and 2 are very basic, teaching players the mechanics and how to light torches in order to maximise score. Level 3 is a linear vertical tower, levels 4 and 6 are open, level 5 is a tribute to Crash Bandicoot and so on.
Design also needed to take into account Scoring. Every level had to be able to be completed as part of a single scoring combo. That means every torch and key is no more than 4.5 seconds away from it’s nearest neighbor. The design of the score system is very simple, 10 points a torch, multiplier goes up with each torch lit and if a torch isn’t lit or a key isn’t collected after the five seconds the multiplier is lost. It is this scoring system that provides a hectic sense to the game, a constant need to be moving and smartly choosing which torch to light next.
Finally I learnt from Sunwalker about the need for player scale. I was constantly bearing in mind how tall the player character was (around 2 metres) and how high the player could jump (2.5 metres). I should have figured out how far the player could jump as well, but was able to build from gut feeling most of the time. With these metrics in mind I was able to build the platforming challenges of each level knowing that the player could run and jump through them most of the time.
Lastly was the system of keys and the hidden bonus level, a callback to my first prototype. I decided very early on to put in a hidden link to my earlier game and thought that gating access with keys would encourage player exploration (additionally top scores can only be gotten by accessing this final level with it’s many sweet sweet torches). I designed each level with a hiding place in mind for its key (with the exceptions of 1 and 2 which had been built earlier). The hardest platforming challenges of two of the levels gate off keys, for the rest they are simply tucked away (except level 1 in which the key is obvious to teach the player they exist in the game).
By bearing each of the above three factors in mind I was able to design a number of satisfying levels (and two which have frustrated my attempts to get a perfect score in the game). Yes it is possible to beat the whole game in a single combo, no I haven’t been able to do it.
One lesson well learnt from Sunwalker was properly structuring levels in the Object Hierarchy in unity:
By properly grouping objects under shared parent objects it was much easier to move around or rescale each feature of the level individually, and made it much easier to duplicate and reuse different elements within the levels.
My project scope was way out of whack on this one. I aimed to add far too much to this prototype, to a level of polish that would have been impossible to attain. I had to discard multiple levels as I didn’t have time to build them all or get them to the standard I wanted.
I spent an evening on the above level centred around Booster pads. Initial implementation worked well and they were a lot of fun to use but they were very unreliable, sometimes sending the player far too far, and sometimes leaving them very short of the target. In the end I had to abandon an evenings worth of work and had only a single booster pad to show for it in level 3 (note the wall you hit is there as I had to ramp the power up a lot to make sure the player would always clear the gap).
I think I need to spend a little more time designing the prototypes early on, estimating how long features should take to add and thinking about what really needs to be in the game and prioritising that. The score system for example wasn’t built until the 24th, and was a core part of the game. Better scoping of the initial project with estimates on how long features will take to implement should make these prototypes much smoother to build.
I am very happy with the amount of reusable scripts that have been added to the shared-scripts library I’m building. The inventory has been expanded and altered to be reusable, I have a CountDown class that is easy to use, an entire reusable scoring system and level loading.
Finally I got much more comfortable with timer based control coding. The multiplier, various parts of the UI and the main game timer all use CountDown timers something I’ve not really used much in the games I’ve designed in the past. As I attempt to implement more complex behaviours in my prototypes this knowledge should be very, very useful.
A big thank you for reading this entry. It’s pretty long and I appreciate your time. I hope you find these break downs interesting, if there is any area you are interested in finding out more about then let me know and I’ll try to write it up. I’m pretty sure I know what the next prototype will be, it should be a little easier to build (famous last words) and hopefully will involve less last minute crunch! Thanks again!
Happy trails and I’ll see you down the road!