Recently at the DEA headquarters, Steve implemented a fantastic level-switching mechanic which allows all potential levels to be loaded into RAM (basically how normal developers do it), except because of a few technical thingies that we pulled, we're able to have absolutely loads of maps, blistering with enemies, traps, props, and more, all instantly loaded into RAM and ready to switch. This will allow instant map switching and results in virtually zero load time at the moment (There are lots of empty maps here too (hence the blackness)):
Apart from that, I've started re-hashing the backgrounds within the levels. I've been able to deploy parallax backgrounds for a long time now, but now these need to be made resolution-independent, meaning that they will always originate and shape correctly regardless of whether the player is using an old monitor, or a brand-spanking new 40" HD TV. As of now, I've just chucked in some abstract floating shapes, which will be the basis for full backgrounds, such as forests, citites, planets, etc:
Tuesday, 1 November 2016
Wednesday, 25 May 2016
What can we learn from Mario Maker?
Mario Maker for the Wii U has been getting a lot of attention recently - and for good reason! It has a thriving community, threads dedicated to legendary levels, and an interface that is just absolutely stunning. It may even be appropriate to say that for something so simple in design, this may be the best level editor I've ever stumbled across.
(You should check out this guy's channel by the way. He puts up some awesome videos and he's a ninja at Mario)
So what exactly can we learn from it? Well, for a start, this is just so much more than an editor. Nintendo have created nothing short of absolute genius software here. Tiny little details are littered all over the place. Grabbing icons makes them rhythmically dance and play little sounds, giving some great feedback, and the whole thing looks so friendly and easy to grasp. There's nothing bland going on here. Perhaps one of the coolest things about this is how Nintendo will have had to inevitably re-code almost everything about Mario. The sheer scope of what is possible in Mario Maker creates situations that were never possible in any of the previous Mario titles. It's no coincidence that every object on the screen interacts seamlessly and perfectly - it's all been thoroughly thought out and devised and re-hashed over a huge period of development.
One thing here that I have massive respect for is Nintendo's processing allocation. Over the years, we see developers trying to create games with the best graphics, but with all this processing power available in new consoles, it's nice to see Nintendo use this processing power to create something much more interesting - a huge sandbox that can support hundreds upon hundreds of of complex objects which can interact in ways that Nintendo (probably) did not even foresee. The result gives players the ability to create Mario courses that don't just par with old Mario titles, but actually exceed them in most ways. Check out this example below:
As this video gracefully demonstrates, pretty much any object can be paired with any other object to create some incredible combinations. The interface of the editor is absolutely brilliant. Its simple drag-and-drop interface almost knows what the user wants to do before they do it and cuts out so much work for the creator. As you see the video above, it may seem like a Rube Goldberg Machine of this calibre would be an absolute nightmare to test. However, Nintendo have got you covered. The editor provides instant and seamless switching between the game and the editor:
Have you noticed how you can also drag something into something else to change its contents? You can also stack enemies on top of each other, or attach things together to create things never possible in previous Mario titles. For example, I've seen somebody place a Goomba, then drag a mushroom onto the Goomba to increase its size, then attach wings to the Goomba, and it just works right off the bat.
It is also worth mentioning the smart move played by Nintendo. Levels that people create in Mario Maker can easily be shared, so players are always trying other people's levels whilst sharing their own. This results in a thriving community and keeps the game constantly fresh and evolving. This could, however, lead to people spamming impossible levels. Nintendo aren't silly though, and they designed the editor so that in order to publish a level, you must first complete it yourself to prove its validity. Genius I say!!!!
It is also worth mentioning the smart move played by Nintendo. Levels that people create in Mario Maker can easily be shared, so players are always trying other people's levels whilst sharing their own. This results in a thriving community and keeps the game constantly fresh and evolving. This could, however, lead to people spamming impossible levels. Nintendo aren't silly though, and they designed the editor so that in order to publish a level, you must first complete it yourself to prove its validity. Genius I say!!!!
After keeping a watchful eye on this title for the past few months, we've decided that we need to strive to make our editor better. After all, an editor is essentially a piece of software that takes a very long time to build, but works as an investment, as every level you create afterwards will be created in a fraction of the time! In this day and age as a developer, there really is nothing better than keeping in close contact with your community and allowing your community to express their individuality and talent. We want to create a similar experience where users can share their levels with jet fast speed, teensy file sizes and total ease of access through hopefully integrating with Steam Workshop in the foreseeable future!
In our previous game prototype, we would simply press debug and the game would run for us to test. This created all kinds of problems, such as having to stop debugging, breakpoint, find the error, run it again, then rinse and repeat. After meeting a few long-term developers, they generally say that if your project seems tangible enough to need a debugging system and/or editor, it probably does need one. Because of this, we have created this new solution which runs the game by 3 separate states:
1.) Player Mode
2.) Debug Mode
3.) Editor Mode
Now, as we develop, we can switch between different control states and get fast and responsive information about the game world. This takes us away from the constant cycle of jumping from code to run-time and back again, keeping us in our creative flow without pauses. So, as the game is running in Player Mode, it essentially simulates how the game would look to a player, not allowing for any cheats or hacks, and displaying the full level of graphics.
In Debug Mode, it is very different. Debug Mode shows all of the collision rectangles, displays information everywhere about the game, allows us to tweak and toggle stats and inventories of entities, move them around, change the game rules, etc. At any point, we can switch back to Player Mode, and the game will continue to run with these new changes in place:
Switching between debug and real-time game-play |
Just in the same way as Mario Maker, using this system, we can really let our creativity flow. You could, for example, take a huge running leap, then just as you're about to fall, pause the game, switch to the editor, and add some floor under the player, then carry on your run and see if you get a good sense of undisturbed flow. We aim to have this 3-pronged system fully functional in the upcoming month!
Thanks for reading, and check out Mario Maker if you haven't already!
Adding hundreds of Squiddies mid-game - because why not? |
Tuesday, 24 May 2016
Embracing change
Thanks again for taking time to read this blog! Hopefully you can learn from a few of our mistakes and save yourself the pain and torment that we caused ourselves. I'd like to talk about scope and ambition, and why this is such an important topic. First of all, I'd like to introduce you to the team:
This handsome chap is me. I'm currently the game designer in charge of the aesthetic direction, story and game-play mechanics. I'm also doing the art and some of the music/sound design for the game. In programming, I specialize in the physics, geometry, collision, animation, interaction and hierarchical structure of code.
Name: Tom
Favourite Colour: new Color(255, 165, 0);
Hobbies: Long walks on the beach, Mojitos and Sex and The City.
This fine specimen is Steve. We've been besties since day one of university. Steve is an absolute programming maverick and can help consult me out of the most dire situations. He specializes in audio engineering, XML, file management, optimization, game flow structure and memory management.
Name: Steve
Favourite Colour: new Color(50, 205, 50);
Hobbies: Bare knuckle boxing, knitting, tap-dancing, horse impersonations, taxidermy.
We've learned a lot over the course of the past five+ years. For one, we learned that starting on your most ambitious title ever is not a good idea if you don't know how to code. Trust me on this one.
I've been making RPG maker games, board games and Game Maker games for over a decade, which has taught me a lot about design. However, when it came to programming something from scratch, I knew nothing up until university. Steve and I sat around in our little student hovel discussing game ideas. We wanted to create something really fun to play, but also something that wasn't ridiculously technical and over-ambitious, like Crysis for example. However, we were in for a shocker!
It turned out that making something as simple as the NES Mario début or even Tetris or Pong was well out of our scope, let alone the idea for this whole game. We were still figuring out how to draw rectangles on the screen and make them move. What would now take us a few minutes would take hours back then! When we finally did implement something we liked, such as a physics-based weapon, it was so horribly implemented that it just couldn't be worked with. So it's safe to say that we've re-hashed this project a good few times now.
My first EVER XNA game - all in a single CS sheet! |
The biggest problem with ambitious projects the the tendency to hit a brick wall. For example, if I wanted to hypothetically create an enemy that resembled a Lakitu in Mario...
A Lakitu, in case you've been living in a cave for the past 3 decades |
I could quite easily hard-code a fully functional Lakitu in an hour or maybe even less. I could code its movement patterns, behaviour, etc, and have it working pretty much the same as one you would see in a Mario title. Easy lemon something. However, everything in our game runs through specific hierarchies for a few reasons which I can get to a bit later. Because of these hierarchical dependencies, I would have to create a Lakitu which inherited from the Entity class that we devised. This class handles multiple death animations, gibs, responses to damage, bullets, passives, aura effects, has an inventory, complicated physics and more. To add that simple behaviour where the Lakitu swoops from left to right and pursues the player, occasionally dropping Spinies, is simple - but once I had to override the AI Director / Control Manager present in every entity, it soon became clear that this seemingly simple behaviour directly conflicted with the underlying code in the base it inherits from.
This presents us with a forked road situation. On one hand, we want to make a game with lots of enemies, so, for example, say an enemy has a reaction to a bullet, and that reaction is to die, we have to code the appropriate behaviour which causes the enemy to die. Now imagine we create 30 enemy types - We want all 30 to react in the same way to bullets, so do we write that exact same code 30 times? Hell no! We make a base class that has a method inside which handles bullet behaviour, and we only code it once, then we make those 30 enemies all inherit from that base class. It's simple enough, but once we start adding all the complex base behaviours shared by all enemies, we also limit what is now possible for child classes of the base to do, as they must now follow strict guidelines derived from the base class.
This presents us with a forked road situation. On one hand, we want to make a game with lots of enemies, so, for example, say an enemy has a reaction to a bullet, and that reaction is to die, we have to code the appropriate behaviour which causes the enemy to die. Now imagine we create 30 enemy types - We want all 30 to react in the same way to bullets, so do we write that exact same code 30 times? Hell no! We make a base class that has a method inside which handles bullet behaviour, and we only code it once, then we make those 30 enemies all inherit from that base class. It's simple enough, but once we start adding all the complex base behaviours shared by all enemies, we also limit what is now possible for child classes of the base to do, as they must now follow strict guidelines derived from the base class.
A huge problem that we run into from my personal experience, and the experience of many bloggers I read about, is that programming in itself is fairly easy. Once you understand it, you just create the logic and it does exactly as you tell it (eventually). The hard part with projects like these is doing it in the most efficient way and managing huge mammoths of code. This entails creating a harmonious balance of code that is:
1.) Optimized (runs quickly and efficiently + cheaper hardware can run it + more processing available to add more features)
2.) Cohesive (easy to change and work with + less/neater code on screen)
3.) Flexible (we want cohesive code, but we like flexibility that allows us to break out of these constraints if need be, so that we do not limit game-play variety)
As a general rule of thumb, the easier code becomes to work with, the easier it is to also fall into a false sense of security that your design will scale well. You have to hit a delicate balance between code that is nice to work with as developers, but that also doesn't require heavy CPU/GPU processing. If I was hypothetically creating a title for the PS4 which, when finished, ran as a constant steady 60fps, then why on earth would you bother optimizing it? It does what it says on the tin, and it does it well. The PS4 is not modular in design, so the frame-rate will not vary if it has a few to spare and is well tested. Optimization issues strike hard, like a vicious lemur, when your playability and frame rates inevitably take a hit, usually due to the huge budget next-gen graphics bla bla nonsense games. If the game was running at around 50fps, and you had not bothered with any optimization, then there would be an incentive to further optimize your code to hit that nice clean 60fps mark.
PC hardware is very different to consoles. If you have something running at 60fps on a PS4, you can guarantee with 100% certainty that the code will execute exactly the same on every PS4, whether it's a PS4 from Mumbai or Hong Kong, and that variation in game-play will be from only the inputs being fed to the game. People have such variation in PC specs that you're going to have to code in a way for PC that accounts for multiple screen resolutions, varying hardware and multiple control systems. Because of this, it's nice to get a rough idea of what PC hardware the majority of people are running. By creating a game that pushes the limits of graphics, you're limiting your audience to the "elite" players with the £2000+ Alienware PCs. On the converse, by dropping the bar too low, you're losing the interest of people who expect a certain standard of graphical quality. It's up to you in your design how you choose to approach this, but I'm one of those nerds who prefers a good frame-rate over nice graphics. Of course, if I had the money, I'd choose both.
Anyway, in regards to the cohesiveness / flexibility balance, there is no easy answer, but it certainly helps a lot to research design patterns. From my personal and fairly limited experience, I would say that you develop a "feel" for what works, and this "feel" can only be gained from hands-on experience - so get yourself involved in every programming jam and part-time project you can. In regards to code structure, would it be better to use a hash table lookup or a simple list? It depends on the context. Is it better to use inheritance or polymorphism? Depends on the context yet again! I can't tell you what works best, because if there was always a single best solution to all problems, then why would any of these tools exist?
What I would recommend is to not get wrapped up in these problems while you're entering the world of game development. You've probably heard this disheartening advice before, but it IS better to work on lots of small projects than to dive in head-first to the most ambitious project you could ever imagine. The beauty of this is that you don't hit these "brick walls". If you get stuck, you can probably find a really sloppy way of making it work. The code looks awful, for sure, but you've finished a project, you have something to show, and for the player, it does not matter how the code is structured when they are playing your finished project.
So to apply this in a real world example, let's say that you wanted to create an online twitch-based first-person shooter such as Quake or TF2. This is already a behemoth of a task. Let us have a look at just a miniscule fraction of some of the tasks involved with creating TF2:
1.) 3D models / rendering
2.) Shaders
3.) UDP networking
4.) Lag compensation
5.) Online user account management
6.) VAC Anti-cheat measures
7.) Menu systems
8.) Making eyelids move
9.) Making chins move
10.) Hats
12.) Hats
13.) HATS!!!!
8.) Making eyelids move
9.) Making chins move
10.) Hats
12.) Hats
13.) HATS!!!!
My face when I play TF2 |
Oh yeah, did I mention the engine they used? They freaking built it themselves. (The Valve Engine, in case you've been exiled to the sewers)
There's probably another thousand things that could go on that list, but for simplicity's sake, we shall stick with these few! Rather than cracking on with that stupidly ambitious first project, you should create seven separate games. Each game could use just one of these elements. One could be a simple 3D display of an animated model, the next could be a simple menu-based RPG, another could be a simple client-server architecture. This way, each project will eventually be completed with enough perseverance, and you won't feel like a failure for not completing one single mammoth of a project which encompasses all of them at once. This also helps target the indie programmer's main weakness: MOTIVATION!
This also gives you the freedom to use sloppy code. Sometimes sloppy code is good just to help you get used to the way things work. I mean, it's not good, it's awful, and you can be ashamed, but it's a small project so you can worry about refining it later. Once you have all these moving parts in order, putting them together is the next big task.
I have found that just because all the pieces work separately, it does not mean that they'll integrate nicely together. This is where prototyping comes in to play. One you have all the pieces of the puzzle working nicely, the next thing is to piece them together into a well-oiled machine. I would always recommend re-writing your code. This may seem like a big middle finger to your hundreds of hours of hard work, but this gives you the opportunity to perfect your art, and also reflect in sheer disgust at how messy your code used to be. You also have to remember that the most time spent coding something from uncharted waters is simply figuring the problem out in your head. The actual physical pressing of keys to write code is just a physical manifestation of your logical reasoning in your brain, and the code produced a reflection of one's thoughts, preserved until the end of man? Who knows? Went off on a bit of a tangent there. On each successive run though, I can guarantee that you will write cleaner code than before, and that you will do it significantly faster than the first time. It's all good fun. I love programming!!!! AHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHAHA!!!!!!
Since you cannot foresee the complications of your game (even if you think you can), it is a very smart idea to prototype. This is the process of putting all of these ideas together and then testing the product to see if your idea is actually fun or engaging. Along the way, you will also learn a million-and-one ways to structure your code better. Once you have tried a few of these ideas out and got a general feel for the game you want to make, it's again time to throw away all of your beloved code, no matter the sentimental value, and start over. I hope this has helped any newbies struggling with code structure and programming patterns!
This is our justification behind why we re-wrote the entire game engine. It's been a total pain, but we see it as a worthy long-term investment which will make future development of the game so much easier. I hope that some of you have at least got something from reading this and can hopefully dodge a few brick walls I hit myself.
This is our justification behind why we re-wrote the entire game engine. It's been a total pain, but we see it as a worthy long-term investment which will make future development of the game so much easier. I hope that some of you have at least got something from reading this and can hopefully dodge a few brick walls I hit myself.
The FEAR |
Tuesday, 8 March 2016
It is time!
The beginning of the year has been very special for us! After consulting my colleague (he's more of a friend than colleague), we decided that it's time to get to work on the official development of the official version of the official game. This means that we'll be scrapping the prototype that took us 4 years to build up! This may seem drastic, but it is absolutely necessary if we want the game to represent our vision, and we really want it to! No half-measures.
So what does this mean?
Well, it's a bit like building a house, minus the bit where you need physical strength. Imagine that you had a vision to build a house a few years ago. Imagine that you decided to teach yourself to build a house and built it on the fly, adding whatever little features you could think of. I'm sure that by the end, you'd have a pretty good idea of how you'd like it to look, but the foundations holding the house together would probably be a total shambles. Still, little things that you hadn't considered would be thrown in, like accounting for the 20ft x 10ft swimming pool you forgot to mention in the planning stages. You're essentially left with this terribly built house, but you know that you're onto something, and you can then build a house based on this design.
It's the same for the game. The prototyping stage was absolutely necessary to decide whether the game idea was even fun. After all, games are about having fun, which seems to be a little bit lost in today's generation of hyper-realism and expansive worlds. It also gave us a goldmine of knowledge and experience to draw from. Most of all, however, we simply learned that there were always more elegant solutions and better ways of designing our hierarchies and systems. Most of the time, we'd think that we'd created the best class hierarchy for weapons ever. The base class would handle all the animation, drawing, bullet creation, etc. Oh wait, what about sticky bombs? These need to be detonated by the player who placed them, so each bomb needs access to that player's input manager. Fixed! It's perfect! Oh wait, what about deflector shields? Vehicles? Grappling hooks? Teleporters? What about THIS? What about THAT? ARRGHGHGHOJJJLHGGDFKGHOHGODHELPME!!!! The whole thing got so convoluted and disgusting that it was enough to make any good software engineer cry. On top of that, the whole idea of inheritance was to save time in the long run, but we spent so much time going through it that it became a hindrance.
This puts us back at the engine stage. The game's all blocks and debug screens. It's not very pretty to look at now, but the prototype acts as a kind of investment. It took years of tweaking, and now the final version can be worked on like crazy without the huge iron walls of apathy. There's probably no such thing as a "perfect" design, and no matter how meticulous you are, you WILL overlook something. Because of this, we have capped a certain amount of weapons with enough variation to provide agency and fun for the player. Once this set of weapons have been created, every future addition can draw from their design.
This puts us in a situation where our game LOOKS worse to the outside observer, but to a programmer, it's a lush and green environment to work in. A huge feature of this new build is the debugging system. While it was a bit of a pain to build, the time we have already saved on debugging is phenomenal! We can see which hash buckets are checking for collisions, grab objects, pause time, toggle gravity, see stats above entities, and more. This stops us having to flick between game and code and helps us develop hypotheses about bugs much faster, ultimately saving us precious development time.
Just trust us! This is a good idea!
So what does this mean?
Well, it's a bit like building a house, minus the bit where you need physical strength. Imagine that you had a vision to build a house a few years ago. Imagine that you decided to teach yourself to build a house and built it on the fly, adding whatever little features you could think of. I'm sure that by the end, you'd have a pretty good idea of how you'd like it to look, but the foundations holding the house together would probably be a total shambles. Still, little things that you hadn't considered would be thrown in, like accounting for the 20ft x 10ft swimming pool you forgot to mention in the planning stages. You're essentially left with this terribly built house, but you know that you're onto something, and you can then build a house based on this design.
It's the same for the game. The prototyping stage was absolutely necessary to decide whether the game idea was even fun. After all, games are about having fun, which seems to be a little bit lost in today's generation of hyper-realism and expansive worlds. It also gave us a goldmine of knowledge and experience to draw from. Most of all, however, we simply learned that there were always more elegant solutions and better ways of designing our hierarchies and systems. Most of the time, we'd think that we'd created the best class hierarchy for weapons ever. The base class would handle all the animation, drawing, bullet creation, etc. Oh wait, what about sticky bombs? These need to be detonated by the player who placed them, so each bomb needs access to that player's input manager. Fixed! It's perfect! Oh wait, what about deflector shields? Vehicles? Grappling hooks? Teleporters? What about THIS? What about THAT? ARRGHGHGHOJJJLHGGDFKGHOHGODHELPME!!!! The whole thing got so convoluted and disgusting that it was enough to make any good software engineer cry. On top of that, the whole idea of inheritance was to save time in the long run, but we spent so much time going through it that it became a hindrance.
This puts us back at the engine stage. The game's all blocks and debug screens. It's not very pretty to look at now, but the prototype acts as a kind of investment. It took years of tweaking, and now the final version can be worked on like crazy without the huge iron walls of apathy. There's probably no such thing as a "perfect" design, and no matter how meticulous you are, you WILL overlook something. Because of this, we have capped a certain amount of weapons with enough variation to provide agency and fun for the player. Once this set of weapons have been created, every future addition can draw from their design.
This puts us in a situation where our game LOOKS worse to the outside observer, but to a programmer, it's a lush and green environment to work in. A huge feature of this new build is the debugging system. While it was a bit of a pain to build, the time we have already saved on debugging is phenomenal! We can see which hash buckets are checking for collisions, grab objects, pause time, toggle gravity, see stats above entities, and more. This stops us having to flick between game and code and helps us develop hypotheses about bugs much faster, ultimately saving us precious development time.
Just trust us! This is a good idea!
New solution with barely any features |
Subscribe to:
Posts (Atom)