Text 14 Sep Partypillars gif from yesterdays playtesting session!

Text 12 Sep 2 notes Tips on making action games

Today I will share some things I’ve learned over the last year about making action games. They will be both practical programming tips and some theoretical game design ideas. Most of these things I’ve learned and/or stolen from other indies and a few I’ve taken from personal experience. I hope you will learn something useful you can apply the next time you’re making a prototype or participating in Ludum Dare!

 

Have a tweening engine ready

image

There’s one library I always use in my games nowadays, and it’s TweenMax. You don’t have to use this particular one, but I highly recommend using a tweening engine. TweenMax has been working great for me: it’s easy to set up, it has an onComplete-implementation that makes it fairly easy to string different tweens together, and it has a big library of different easing options. Use this for all the beautiful squashing, stretching, tweening and fading you’ll be doing.

 

Make easily reusable function calls for your effects

Every time I make a new effect nowadays I just make it available as a global function that any object has access to. They look something like this:

manyBigHitEffects(obj);

The function manyBigHitEffects() is accessible globally by any game object, and it acts on the object being sent as the parameter. The function takes the object, calculates its center point, and spawns the effect on top of it. This is a extremely simple implementation, and at times you would rather have a function that takes x- and y-coordinates instead, but in most cases this is just as good, and simpler to read.

Example of the feedback given by an asteroid reaching zero health:

game.sfxExplode.play();

game.manyBigHitEffects(this);

this.kill();

image

Simple to code, and simple to read.

 

Whenever something happens in your game, show it!

If you find yourself writing code that involves the player or player objects, show the player what’s happening! If the player presses a button and a bullet is shot, have a muzzle flare and sound effect, if she hits an enemy with a projectile have the enemy light up and play a sound effect, if the player is in mid-air and then lands on a platform squash the player sprite a bit to show the force of impact etc.

image

All of these interactions will be better communicated if you add some “juice” to them, and with your newly created globally available functions, adding a squash effect to the player sprite is as easy as this:

game.squash(player, squashDuration);

 

Always have a sound effect

Go download sfxr right now, and whenever you need a sound effect in the game, make a placeholder and stick it in your game. Even if it’s not a 100% right it will be a lot better than no sound at all, and you’ll have an easy time replacing it later when you have something more fitting. Sound effects are by far the feedback that makes the biggest difference compared to the time invested in implementing them, so make some sounds and throw them in there!

 

Have all the actions be meaningful

Sid Meier has been attributed as saying that a game is a series of meaningful choices. In short this means that no choices should be obviously better than others and you should be able to anticipate what will happen to a certain extent so that you don’t end up choosing arbitrarily. This is especially true for strategy games, but it’s true for all action games on a very micro level.

In this game I chose to penalize the player pretty harshly for holding down the shooting button. Their movement speed is much lower, and you have a pretty harsh recoil, pushing your ship back towards the bottom of the screen. This forces the player to stop shooting when repositioning himself quickly, both if he’s too far from his target to hit it with projectiles, and also if he needs to dodge incoming projectiles quickly.

image

This adds another level of strategy to the game, and makes it a little bit less like a mindless schmup.

Another example is the fact that when the player’s projectiles hit an asteroid, the projectile adds a little force to the asteroid in the opposite direction, slowing it down a bit. This extra layer of interaction makes the player feel like his actions matter, like he has some influence over the seemingly unstoppable objects floating towards him.

 

Shake the screen!

Jan Willem from Vlambeer says this better than anyone, but this bears repeating. Screenshake adds a LOT to an action game, the feeling of impact is enhanced and it just feels powerful and cool! Do it! Then when you think you’re doing it enough, do it some more. You’re not done until some people feel nauseous while playing.

 

White hit frames

If your game involves shooting things, just take the sprite of the object that’s being hit, color it white, and flash it for a tenth of a second whenever it’s hit by a projectile. NES games were doing this 30 years ago, and it’s just as effective today! There is nothing as satisfying as seeing your enemies light up with a white flash accompanied by a punchy sound effect, except for seeing them explode in a myriad of effects and tiny particles of course!

image

 

Particularly useful effects and functions

Squash and stretch - Having functions available that can do a cool squash or stretch animation on a sprite or object can be super handy. I usually send in a power parameter and a duration in my own functions, and I like using elastic easing for these kind of effects. They are great for buttons and other HUD elements, but can also be super handy for in-game objects. Adding some squash and stretch to the character sprite during a jumping or landing animation adds a lot of juice with very little effort.

Particle effects - Being able to send in coordinates or simply an object and say “do this particle effect here” is incredibly powerful, and should not be used sparingly!

image

Fade - Just pass an object and a duration to this function, and it will fade out the object’s sprite until it turns invisible. Optional: add a boolean parameter called “kill” which kills the object on completion when set to true.

 

In closing - It’s all about feedback

Player feedback is the single most important part of making an action game that feels good. One of the mistakes I’ve made in the past is that I put up too big of a mental barrier between what’s the theoretical core gameplay (the rules of the game), and what’s “just graphics” or “polish”. The fact of the matter is that the feedback of your game is a big part of the core experience, even if the rules of the game could just as well be represented by white hitboxes colliding with each other. Don’t neglect this essential part of creating an action-packed experience!

Photo 2 Sep 1 note Made some new smoke/dirt effects for Partypillars.

Made some new smoke/dirt effects for Partypillars.

Photo 26 Aug 3 notes Just sitting here, generating amazing bugs. Don’t code before you have your coffee, kids!

Just sitting here, generating amazing bugs. Don’t code before you have your coffee, kids!

Text 14 Aug 1 note Partypillars on OUYA

I just wanted to write down my initial experiences porting Partypillars to OUYA using CocoonJS.

Partypillars is a 4-player local multiplayer game built using ImpactJS and Box2D. It also supports controllers using the Gamepad API defined in the W3C spec.
Around a month ago I made it available on itch.io, and a couple of days ago I took a stab at porting it to OUYA with CocoonJS. There were just a couple of hurdles I had to jump, one of which was a especially annoying to debug.

CocoonJS

Getting the game to run was surprisingly easy, the only hitches I had were due to my own inexperience with Android and OUYA, but basically it’s very easy. First you have to make a zip-file that includes the index.html file, the media folder, the game.min.js file and any other external .js files you’re using (I always use TweenMax.js for my projects for example). Then you go to CocoonJS, make an account and start a new project. When you choose “compile project” you check off OUYA and throw your zip-file in there, and after a couple of minutes you should have a fully functioning OUYA-ready .apk. Just put it on your webserver, browse to it using your OUYA browser, download the signed debug file and then you can install and run it from manage->storage->downloads.

Controllers with CocoonJS

My first real problem appeared here when the game was already up and running. None of the buttons on the controller worked. The only response I got was from the analogues (which I had thankfully mapped to the same as the d-pad). After trying some different configs of buttons I started to realize that it wasn’t that the buttons were mapped differently, I was not getting any button presses from any of the controllers whatsoever.

I started browsing the documentation of CocoonJS, already suspecting that someone had fucked up the implementation of the Gamepad spec, and after a small dead end I found the problem.
The W3C spec is pretty clear on how you’re supposed to implement controllers: each controller object contains an array of buttons, and each button is an object that holds two variables, on bool called ‘pressed’, and a float called ‘value’. The ‘pressed’ variable is true if the button is pressed (duh!) and false if not. The ‘value’ variable holds a number between 0 and 1 which shows how hard the button is being pressed, with 0 being not at all, and 1 being all the way in. CocoonJS however has opted to not implement the ‘pressed’ variable at all, and letting the button object instead BE a float that is between 1 and 0. Essentially, I was checking variables that didn’t exist.
After I figured that out, I wrote an OUYA exception in my controller code, and I could finally interact properly.

ImpactJS bitmap fonts

Now for my other problem: my bitmap fonts weren’t working properly. I assumed this had something to do with the way Impact implements bitmap fonts, and again after a couple of dead ends I just asked Dominic (@phoboslabs) who wrote the engine what he thought the problem was.
Dominic answered right away as per usual, and he seemed to know exactly what the problem was:
After setting a breakpoint, copying the two arrays into a separate file in Sublime, doing some creative multicursor editing and essentially hardcoding the width and indices of the font, everything worked perfectly!

Play the game on itch.io in the browser or download the OUYA compatible .apk from there! OUYA version works well most of the time but is not optimized and I have noticed some crash bugs at times.

Link 11 Aug Partypillars - Local Multiplayer Mayhem (HTML5)»

I posted an update to the devlog and a new build of Partypillars at krisjet.itch.io/partypillars/

The newest build has a lot of graphical improvements, some improvements to character movement, a round system and a new crown indicator for the player or players who are currently in the lead.

I have some pretty big changes planned for testing for my next build, so I can’t promise that it’ll be next week, but I’ll try my best!

Link 28 Jul Partypillars by Krisjet»

A new update for Partypillars is out! Now with a proper fullscreen button, a “join game” to make it easier for you controller types out there, and some other UI stuff. It’s also possible to play team mode with uneven teams now, like 2 versus 1 or even 3 versus 1. Go play!

Link 18 Jul Anatomy Of A Successful Attack « Aztez – A Game of Conquest and Brutality»

Super juiceful… I mean useful write up about different juicy techniques to make the impact of an attack in a game more satisfying. All of this stuff can be used in hundreds of different ways of course.

Link 17 Jul Give your sprites depth with sub-pixel animation»

Found this cool tutorial about sub-pixel animation on makega.me! Useful info for pixel artists.

Link 11 Jul Partypillars by Krisjet»

I just posted my birthday game from last year, Partypillars, on itch.io. I also added much needed controller support, so grab some friends and controllers and have a blast!


Design crafted by Prashanth Kamalakanthan. Powered by Tumblr.