Almost exactly one year ago I began production on what I consider my dream project – a 3D platformer akin to the greats I loved growing up. My biggest obstacle however was my lack of programming knowledge as I mentioned in my other blog post about transitioning from UDK to Unity. I had played many other projects and seen the great things that they had implemented, but I knew I could never do this unless I learned to program. Not only was the language itself foreign to me, but an even more important element escaped my understanding: the logic. So I began to dissect the existing code base or “starter kits” from the asset store and see how it all worked. I was in luck as I was learning as the logic behind the code began to make sense almost immediately. Before long I knew what I wanted to do and how I could go about it, so now it was just a matter of putting that in to code.
Unity Answers/Forums and GameDev Stack Exchange proved to be invaluable at this point as it almost always had the answer I was looking for. Even if it wasn’t identical, it gave me a point to jump off from. For example, I barely knew what a Raycast was and how to use it; especially with all of the information that it could return and be used for various things. So approaching this project/starter base without this knowledge, I found myself intimidated by trying to implement new features. Of course having all of these ideas about what I wanted to do didn’t help…
Taking the first step to actually adding a new feature proved to be the largest one I have since taken. Between the intimidation of not knowing where to start and the (then vague) understanding of coding that I had, I finally mustered the courage to just jump in and start. I believe the first feature I wanted to implement was a wall jump as I felt it would both be simple enough to implement while being an important ability for the gameplay I had in mind. As I already went in to detail of how I approached implementing various abilities, let me just say the way I handled these abilities back then shows my inexperience. In this example I used a trigger area in front of the player and then rotated them exactly 180 degrees after kicking the wall. Did it work, absolutely. Was it pretty/fun/practical, not so much. I eventually updated this to fire a Raycast upon kicking to get the reflect angle and rotate the player toward it. Now this felt much better, but it still required objects to have a specific tag to kick off of them. So months later it evolved again, only now I use that same Raycast to get the angle in relation to the players Vector3.up and if it is within a certain threshold (as in the wall is between 80 and 100 degrees), the wall kick executes. Not only did this feel better and give a more accurate result, but it did it with minimal overhead: just the single Raycast. That would prove to be the story of my life with this project. Many features I would expand on, or use a more efficient method to make them happen that I feel as though I rewrote nearly all of my original code up to this point, at least twice.
Granted, that original code did give me the drive to want to continue with this project as I began to see it become the vision that I originally had in my mind. So much so that once I added features (that worked), I kept wanting to add more, and more; it was an addiction for a while. Wall kicking led to an attack ability, which led to swimming, and then more enemy abilities, and then ledge grabbing, etc. This was the trend for a while and led to a few features that I wanted to implement but couldn’t get to work the way that I wanted them to (sliding down slopes like in Mario 64 for example). Rather than waste days/weeks/months(?) on something that wasn’t crucial to gameplay, I decided to carry on with the premise and game design itself. After all, I already had nearly every gameplay-centric feature working as I planned; and it felt fun to just run around using these abilities.
As with every project, gameplay plans would evolve and change along the way. From the hero itself changing to what they need to collect and why they are collecting them. In-fact I can’t promise that things won’t change more as development continues. For example I had never planned on using powerup cards to grant additional abilities until I found an asset on the asset store where the character had many different costumes/looks. Rather than let them go to “waste”, I decided I could use them as a Mario 64-style powerup system and open up entirely new gameplay scenarios in the levels.
I had my code base, I had my primary abilities, and I had my gameplay so now I needed levels to use them in. For the longest time I just ran around my test level playing with these features to make sure that things were fun (and worked as expected). I had began to plug away at the first scene, adding models and making sure that they matched-up to the terrain, however this level sat that way for the longest time. After finally planning some additional levels out in Adobe Illustrator (albeit roughly), I began to gray box these out as well. I now have about 3 partial levels, but I would soon find my way back to the first scene after finding the “gimmick” that I wanted to use in it. I began to add details, enemies (who went through their own changes), pickups, and of course, the “gimmick” items that led to revisiting and completing the scene. Now here it is, playable and ready for a public release in a demo to finally get all of this work in to the hands of gamer’s for feedback.
I have always been a nostalgic person, so I like to look through the archives I have for this project to see how things have evolved. My next post will likely be for doing just that; showing how the first scene (now titled Wind Turbine Valley) has evolved since development began. Of course I will need to hold back from shaking my head at how I coded/designed things a year ago, but that’s how I got this project to where it is today; on the verge of a public playtest release. And after all, isn’t that gratifying feeling of seeing your project mature and evolve why we all do this in the first place?