Monday, November 17, 2014

Yet Another Addendum: 2D Platformer Collision Detection in Unity

This is yet another addendum to my previous addendum to my original article on creating 2D platformer collision detection in Unity using raycasting. There was a last remaining bug in the system in which the player would get snagged on a corner tile, effectively getting stuck until they jumped or moved in the opposite direction. This is still a huge improvement over just falling through the tile completely (which was the case originally), but still annoying and needed addressing.

You can see the bug in the video below. Just fast forward to the 1:07 mark and watch the Angel in the lower right corner.



It actually took me a long time to come up with a fix for this, even though now it's such a simple and obvious fix. Without reiterating all of the details of the collision system, I essentially cast rays towards the directions the player is moving. If the player is moving left, I cast evenly spaced horizontal rays from the box collider (4 in this game's case). To cover the corner of the box collider, I use a margin variable to cast ever so slightly out of the box collider bounds; refer to my previous posts on this for further detail.

This was causing the snagging issue because while the player's box collider wasn't actually colliding the tile (and it doesn't really appear to be either in the game), a collision was still being detected due to the margin. By itself, this isn't too bad, but we'd also get a y-axis collision detected, and this, along with a x-axis collision, would cause the snagging/jittering effect.

The ideal solution is to reduce the margin of the raycasts so that we're not casting outside of the box collider, and still guarding against corner collisions. Thus, we introduce diagonal raycasts from the corners of the box collider!

Here is the new code in all its glory.
Note the Move method and when we perform the diagonal raycasts. We only want to perform them when the player is moving through the air, by checking that the player is moving in both x and y axes, not in a a side collision nor on the ground. We then perform a simple raycast (always with the origin in the center of the collider) in the direction the player is moving. When a corner is hit, we simply stop the x-axis movement.

A simple solution to a problem that was haunting me for a while.



Wednesday, October 15, 2014

Duke Nukem 3D - Game Tutorial Through Level Design

Some of the best games use level design to teach the player the mechanics of the game and how to ultimately play, instead of relying on the dreaded tutorial that forces the player to play through before actually getting to the game. One of the classic examples of this is World 1-1 in the original Super Mario Bros. The intro to this level has been analized to death, so I'm not going to beat that dead horse. Instead, I want to look at one of my favorite games of all time, Duke Nukem 3D, and how the mechanics of the game is taught to the player through the level design of Hollywood Holocaust.

Before we dive in, we need to remember that Duke Nukem 3D was released almost 19 years ago (damn, we're all getting old :( ). The first person shooter genre was just being born out of prior games such as Wolfenstein 3D and Doom. Duke Nukem 3D, at the time, was a large leap forward in the genre, offering true 3D play as players could traverse the Y-axis through jumping and jetpacking and incredibly expansive, detailed levels and interactivity. Duke3d needed to let the player know this isn't Doom they were playing!

We're going to walk through just the first area of Hollywood Holocaust, and how the level design is used to teach the player about the new mechanics available to him, both as a player who's played Doom, and a player new to the FPS genre entirely.



The game starts with Duke jumping out of his ride (damn those alien bastards!). Immediately, Duke is airborne. He doesn't start grounded, letting gravity pull him down the Y-axis. This immediately tells the player that there's a whole new axis of gameplay available to you. You will not be zipping around just the X and Z axes. This is further emphasized by the fact that you land on a caged in roof top. There's only one place to go but down!

The player is left to roam the enclosed rooftop. The rooftop is seemingly bare at first, but rewards the player for exploring beyond the obvious path with some additional ammo hidden behind the large crate. Exploration and hidden areas is a large part of Duke3d's gameplay, and this is a subtle, yet effective way of communicating that to the player.



Next, the player will come across a large vent fan, taped off, with some explosive barrels conveniently placed next to it. The game literally cannot continue until the player figures out the core mechanic of the game, shooting. Not only is the mechanic of shooting being taught, but also the mechanic of aiming at your target. This is all done at a leisurely, comfortable pace for the player. Imagine if that there was an enemy guarding the air vent? For a player new to the genre (and back in 1996, it was very common to have someone play this game who's never played a FPS before, not even Doom), it would have been very overwhelming and probably a guaranteed player death.

Once the player figures out aiming and shooting, they also are taught another core mechanic of the game, puzzle solving. Solving little environmental based puzzles will be common going forward, so the player needs to be taught to be aware of their surroundings and understand it is interactive and interactivity will be key to success.

It's fascinating to me that the core of the game is taught to the player in such little time, with such seemingly simple level design.


Thursday, August 28, 2014

Using Jenkins with Unity

Going off my last post where I used a batch script to automate Unity builds, I decided to take it a step further and integrate Jenkins, the popular CI sofware, into the process. 

With Jenkins, I can have it poll the Demons with Shotguns git repository, and have it detect when changes are made, in which it'll perform a Unity build (building the Windows target) and archive the build artifacts.

What's great about this is that I can clearly see which committed changes relate to which build, helping me identify when, and more importantly where, a new bug was introduced. 

image

I currently have it set to keep a backlog of 30 builds, but you can potentially keep an infinite number of builds (limited to your hard drive space, of course). 

So how do you configure this? Assuming you have Jenkins (and the required source control plugin) installed already, create a new job as a free-style software project. In the job configuration page, set the max # of builds to keep (leave blank if you don't want to limit this). In the source code management section, set it up accordingly to whichever source control software you use (I'm using git). This section, and how you set it up, is going to vary greatly depending on which source control software you use.

Under build triggers, do Poll SCM and set the appropriate cron job syntax based on how frequently you want to poll the source repository for changes. 

Under the build section, add a Execute Windows batch command build step. You then script up which targets you want to build (you can use the script in my previous post as a template). 

Under post-build actions, add Archive the artifacts. In the files to archive text box, setup the fileset masks you want. For a standalone build it would look like "game.exe,game_Data/**". 

That's it! I do know that there is a Unity plugin for Jenkins that'll help run the BuildPipeline without having to write a batch script but I never had success in getting it running so I just went this route. 

Automating Unity Builds

I wanted a way to automate building Unity projects from a command line, but to also commit each build to a git repo so I can keep track of the builds I make (in case something breaks, I can go back to previous builds and see where it might of broken). This is my poor man's CI process.

Here's the script in all its glory.

As you can see, it's nothing special. Simply plug in the path to your project and where you want to the exe to spit out. Adding other build targets is trivial as well. Best part of this, it doesn't require the Pro version of Unity at all!

This solution is temporary. I'm going to wrap this in Jenkins so that it'll detect git commits then build and archive the game's .exe. More on that soon!

Monday, July 7, 2014

How to program independent games by Jonathan Blow - A TL;DR

On April 1, 2011, Jonathan Blow gave a presentation at UC Berkeley's Computer Science Undergraduate Association entitled How to program independent games. Thankfully, it's available on YouTube. This talk is insightful not just for the indie game dev, but for any software developer in general. Please take the time to view it.


This is a talk about productivity, about getting things done, more than anything. Programmers that get their computer science degree are often taught how to optimize code, but this generally comes at a great expense to productivity. Indie game devs have to wear several hats (if not all of the hats), so time is too precious to be wasted.

There are several examples Blow goes through to illustrate this, some of which I think are very weak arguments given modern APIs (I'm referring to his hash table vs. arrays argument), but the majority of them are spot on. One that stood out in particular is the urge to make everything generic, when it may not be necessary. More often than not, a method you're writing will be a one off, only used to perform some type of action on one type of object, so time is absolutely wasted trying to make that method work on an entire hierarchy of objects.

The biggest take away is simply this: the simplest solution to implement is almost always the correct one. Get it done. Move on. Fix it/optimize it only when you absolutely need to.

Monday, April 21, 2014

Creating a flexible audio system in Unity

Unity's audio system isn't without its disadvantages. One of it's major issues is that a single AudioSource can only play one audio clip at a time. You may say "well, that kind of makes sense" but why not fire a background thread for each play request?

Playing only one audio clip at a time can be a problem in scenarios where you have an AudioSource attached to a prefab, your Player for example, and you have multiple audio clips you'd like to be played in succession. Your player jumps, so you want to play a jumping sound effect, but within the time that jumping sound effect is playing, they get hit by something, so you swap out the audio clip and play a player hit sound effect, but if you're trying to use a single AudioSource, that'll cut off the currently playing jumping sound effect. It'll sound bad, jarring and confusing to the player. Most obvious solution is to simply attach a new audio source for every audio clip you'd like to play. That may get nightmarish if you end up having a lot of possible audio clips to play.

My solution has been to create a central controller that'll listen for game events to spawn and pool AudioSource game objects in the scene at a specified location (in case the audio clip is a 3D sound), load it with a specified AudioClip, and play it, and return the instance back to the object pool for later use. This allows you to play multiple audio clips at a single location, at a single time, without cutting each other off. You also get the benefit of keeping your game prefabs clean and tidy.

I'm always reluctant to share my code because I use StrangeIoC, which not everyone is using (though you probably should!) and the code structure may seem alien, but a keen developer should be able to adapt the solution to their needs. Let's go through a working example.

I've attempted to comment this Gist well enough so that people who aren't familiar with StrangeIoC can still follow along. The basic execution is


  1. Player is hit, dispatch a request to play the "player is hit" sound effect
  2. This is a fatality event, dispatch a request to also play the "player fatality" sound effect
  3. PlaySoundFxCommand receives both events
  4. For each separate event, attempt to obtain an audio source prefab from the object pool. If one is not available, it will be instantiated
  5. If the _soundFxs Dictionary doesn't already have a reference to the requested AudioClip, load it via Resources.Load and store reference for future calls
  6. Setup the AudioSource (assign AudioClip to play, position, etc)
  7. Play the AudioSource
  8. Start a Coroutine to iterate every frame while the AudioClip is still playing
  9. Once the AudioClip is done, deactivate the AudioSource and return it back to the object pool

With this system, you never have to worry about audio clips cutting each other off, everything is centralized, and you don't have to manually manage the different possible AudioSources. However, you do need to keep an eye on memory usage as we are pooling and saving reference to a lot of resources, which may hinder how well this system can scale. A possible improvement is to limit the number of AudioClips we save reference to in the _soundFxs Dictionary, and when that limit is reached, remove an entry. You could go as far as to figure out which sound effect are least used, and remove those first. 









Thursday, March 27, 2014

Reducing Your Game's Scale: Save It For The Sequel!

It seemingly happens to almost every designer, novice or veteran, AAA and indie. You have that grand game idea. When you close your eyes, you can see it being played before you. The expansive levels, the fancy weapons, the beautiful graphics and audio, all of the little polished details. Then you snap back to reality and (hopefully) quickly realize the scale of your dream game is simply too large.

Time to start cutting!

This may seem terrible and disappointing, but just because you're cutting features and making compromises doesn't mean the initial vision is completely lost. Firstly, you're helping to ensure that you actually get to release your game. This is the ultimate goal, and everything should be done to ensure this (oh, but do make sure you provide a great experience!). Take the ideas you're cutting, write them down somewhere, as they are not lost forever.

Save them for the sequel!

Obviously, Overtime had a much grander scale when I first started designing compared to what it's been boiled down to now. Even after I write this, I'm sure more things will be cut. Being a solo developer working on his first actual commercial release, the scale needs to be small to ensure I actually release something. However, everything that I am cutting I do want to see come to fruition, so it's being saved for a sequel game, which I hope I get to work on given that the first title is received well enough to warrant it. 

So don't fret, don't fear! Cut, cut cut. You'll see an amazing thing happen, something that you probably couldn't imagine be happening. Your game becomes better for it, and you actually increase your chances of releasing. Not a bad trade off at all. 

Friday, March 21, 2014

The Importance of Player Feedback & Subgoals: Playtest Results - 03/14/2014

I had a quick playtest session with some close friends the other day. I've been making good progress on the game (which is yet to be titled, but lets refer to it by its working name, Overtime). I'd just added vertical axis shooting which I wanted to playtest and I also needed to get some real world QA done as testing a local multiplayer only game is proving difficult.

Here is a clip from one of the recordings I took.


Importance of Feedback

My biggest initial take away is the importance of player feedback for even the smallest actions. From jumping to obtaining a frag, there needs to be feedback provided. The player not only needs to be given feedback to assure his actions are executed, but to be rewarded for the things he does and make them worth doing again. Feedback can be provided in numerous ways, from elegant sprite animations, to subtle or acute particle effects. A small, brief dramatic sequence to a frag can make the frag all the more rewarding, thrilling and special as so awesomely done in Samurai Gunn.
A player swats back another players bullet for a kill in Samurai Gunn.
I quickly added some rudimentary blood splatter particles the day before the playtest to help provide feedback, but I feel it wasn't enough and lost its novelty very quickly. I've since tweaked the blood splatter to project based on the direction of the fatal projectile, tiles around the player corpse become bloody, added  flying gibs and even created dramatic John Woo like slow motion effect when the player is killed. All of these small layers of feedback will hopefully make obtaining player frags more rewarding beyond just increasing a frag score. Simply firing projectiles at other players may be fun at first, but if the overall presentation of the actions is bland and boring, player won't be interested in playing for long.

Fragging a demon with a shotgun in Overtime


Importance of Subgoals

Currently, Overtime has only one goal, kill all other players. There is very little else the player needs to focus on or worry about. This is a problem, as the game gets boring quickly. Once you've killed the other players a handful of times, you've experienced all that there is to offer and lose interest in playing any further.

It could be argued that platforming (successfully negotiating jumps to make your desired mark) and ammo management (collecting ammo packs to ensure you always have ammo) are also subgoals, but I feel they are too subtle. This just may be the nature of simple deathmatch mode in general; I do plan to add other game modes which will add more exciting subgoals for the player I'm sure.

Samurai Gunn has environmental hazards and destructibles. This give players more subgoals, avoid accidental deaths and shape your environment to your advantage (you can destroy certain tiles to the point where they become hazards). Players in Samurai Gunn can also engage in defensive actions, engaging in mini sword fights to parry player attacks and swatting back player bullets. This not only gives players a grander sense of control over their ultimate fate, but an entirely different set of actions and required skills.

This was a great round of playtesting and really highlighted serious gaps in Overtime's design, which I'll need to address. The above GIF of Samurai Gunn does such an incredible job of summing up the entire game, its mechanics, the level of polish and feedback, goals and dimensions in just under a second of gameplay. If you need longer than a second to capture the total essence of your game, you should step back and start rethinking your design.

Friday, March 7, 2014

Addendum: 2D Platformer Collision Detection in Unity

NOTE: Please see Yet Another Addendum to this solution for important bug fixes. 


This is an addendum to my original post, 2D Platformer Collision Detection in Unity. The solution explained in that post was a great "start", but ultimately had problems which I'd like to go over and correct in this post, so that I don't lead anyone too astray!

The Problem

To summarize, entities could fall through collision layers under the right conditions. The most notable use case was corner collisions at low framerates (< 30FPS). 


In the picture above, the white lines represent the raycasts. The green box is the box collider. As you can see, that small corner gap is enough to cause the player to slip through the collision layer. As noted before, this issue was highly prevalent when the frame rate was < 30FPS (I capped the frame rate using a small script to take into consideration people with slower hardware). For the more astute Unity users, I can hear the screams of "FixedUpdate! FixedUpdate!" Just trust me that using FixedUpdate had no effect on this issue. I tried, in several different manners, and all resulted in the same problem.

The Solution

Originally, the rays were being casted from the edges of the box colliders instead from within the box collider. Why is this important? I'm going to borrow a diagram from Yoann's Pignole Gamasutra article.

Source: Gamasutra: The hobbyist coder #1: 2D platformer controller by Yoann Pignole
This makes sense, but why would I only have an issue at slow frame rates? To be honest, I still don't know. I'm guessing it had to do with the speed in which raycasts were executed (which you would think calling within FixedUpdate would fix, but didn't). 

Ultimately, I rewrote the system completely, ensuring the rays were casted from the center of the box collider, and when resolving the collisions, moving the entity to the point of collision. This solution completely removed all issues I noticed. 

This provides a much cleaner, robust solution. I can also more easily adjust the number of rays I cast, as well as allowing to cast the rays outside of a margin, if need be.















Tuesday, January 14, 2014

Single Camera System For Four Players

One design decision of Overtime I've been currently facing is "how big should the game maps be (single screen or multi-screen)?" Small maps allow for focused, more intense battles while limiting game mode possibilities, while larger maps allow for more gameplay and game mode varieties. Small, single screen maps would require only one camera to capture all players and playing environment. Larger, multi-screen maps would require multiple cameras (one for each player) that can follow a target. Since Overtime is a local-multiplayer game only, this also means split-screen cameras.

Why not have both? It's pretty trivial to have maps that anchor the camera to a single spot for small maps, while allowing split-screen cameras for larger maps. After some playtesting, I found the split-screen cameras pretty annoying due to the small screen real estate they provided for each player. I didn't want to scrap the idea of big maps entirely. So, is it possible to create a single camera that can follow up to four different targets? I soon realized that the type of camera I ended up needing is a camera in the style of a fighting game.

Fighting games, such as Super Smash Bros. or even wrestling games, feature single screen cameras that track multiple targets, zooming in and out as the targets get closer and farther away from each other, respectively. This is done by some vector math magic (it's not really magic, as you'll see).

So let's go through the requirements of the camera system
  1. Follow up to four targets, always having them within screen view at all times.
  2. The camera should always be focused on the relative center of all four targets.
  3. As targets move farther away from each other, zoom camera out an appropriate amount of distance.
  4. As targets move closer to each other, zoom camera in, clamping the zoom factor to a specified amount.
From that, we can immediately deduce we need to know the following things
  1. Based on all targets current positions, what are the minimum and maximum positions.
  2. What is the center point between the minimum and maximum positions.
  3. How far do we need to zoom to keep all targets within view.
So far, maybe you've realized that it's impossible for a camera to follow multiple targets; the camera must always be fixed on one point to follow. Obtaining the minimum and maximum positions will allow us to later find the center point between these positions, which we will use as the single point the camera will follow. By following this point, we know the camera will be relatively center of all targets. Here is the pseudocode for obtaining the minimum and maximum positions:

List xPositions;
List yPositions;
foreach target {
    xPositions.Add(target.x);
    yPositions.Add(target.y);
}
maxX = Max(xPositions);
maxY = Max(yPositions);
minX = Min(xPositions);
minY = Min(yPositions);

minPosition = Vector2(minX, minY)
maxPosition = Vector2(minX, minY)

We need to obtain the x and y coordinates of all targets, and store them in a List. We then find the maximum (x, y) and minimum (x, y) values of each to give us our final minimum and maximum positions (Unity has these Max and Min methods in the Mathf class, but you could implement your own easily if needed).

Let's add some diagrams to help visualize this better (the scale is all wrong, I know, but bare with me!).


The smiley faces represent our three players, and their positions. Following the above pseudocode, we come up with a min of (8, 7) and a max of (31, 14). This gives us the outermost coordinates of the area our players are in.

To find the center of these two positions is a trivial step. Simply add the Min and Max vectors, and multiply by 0.5 (favor multiplication over division for performance reasons).


((8, 7) + (31, 14)) * 0.5 = (19.5, 10.5)

Great! We now have the target position that our camera will use to follow. This position will update as our players move, ensuring we're always at the relative center of them. But we're not done just yet. We need to determine the zoom factor.

Quick side note about the zoom factor. When developing a 2D game, you normally use 2D vectors (as we've been doing so far) and an orthographic camera, which ignores the z-axis (in Unity, not really, but the depth is used differently as objects don't change size as the z-axis changes). If you were developing a 3D game, you'd be using 3D Vectors and a perspective camera. Perspective cameras have depth according to their z-axis position. However, determining the zoom factor for both 2D and 3D is quite similar, just how you apply the value differs.

We've already determined that the X and Y coordinates of our camera needs to be (19.5, 10.5), as that's the relative center of all targets on the X and Y axes. What you need now is a vector that's perpendicular to the X and Y coordinates we calculated above. That's where the cross product formula comes in. The more astute reader may be screaming "you can't perform cross product on 2D vectors!" right now. Yes, you're absolutely correct, but bear with me.

The cross product of two vectors give us a vector that's perpendicular (at a right angle) to the two.
Source: Wikipedia


The diagram above shows the cross product of the red and blue vectors as the red vector changes direction, with the resulting perpendicular green vector. Notice how the magnitude of the green vector changes, getting longer and shorter based on the magnitude of the red vector. This is exactly what we need, a vector that's perpendicular to our camera's (X, Y) target position coordinates, whose magnitude changes appropriately based on the angle.

As mentioned before, you can't perform the cross product of 2D vectors. So instead, we'll pad our 2D vectors with a z coordinate of 0.

(19.5, 10.5, 0) x (0, 1, 0) = (0, 0, 19.5)

x is the symbol for cross product. We use a normalized up vector  as our second argument so that the resulting vector is of maximum distance. Using the Z value of 19.5, we can now set the zoom factor. Since orthographic cameras don't technically zoom in the same sense as a perspective camera, we instead change the orthographic size, which provides the same effect.

Now let's assume that the perspective camera of your 3D game needs to act very much like a 2D platformer (always facing the side, never directly above or below). Instead of altering the orthographic size (because that doesn't make sense for a perspective camera ;) ), we use the results of the cross product to set the z-axis directly. This will move the perspective camera accordingly, give us our desired zoom effect.

Here's a video demonstrating the camera movement for two players.


Wednesday, December 18, 2013

Model-View-Presenter architecture for game development, it's not just for enterprise.

I'm an absolute stickler for a good architecture. Nothing irritates me more then spaghetti code with deep coupling between classes, god classes and a lack of any type of modularity. When I begin to develop any application of any type, I immediately start to think how it's going to be structured. Thankfully, there are tons of battle proven patterns to choose from the family of MV*. My favorite as of late has been Model-View-Presenter (MVP).

I don't want to go too deeply about what MVP is and how it differs from other MV* patterns (such as the classic MVC), but here's a quick diagram stolen from Wikipedia.


The key takeaways are that views are dumb and easily interchangeable, presenters contain the business logic, a presenter updates ideally one (but can update more) view, application state lives in the model objects (which are as equally dumb as views). That's all you should really need to know to follow the rest of this post, but please read up on MVP more if you're not familiar with it and understand the difference between MVC.

When I first began game development, I had a hard time structuring my code. I initially couldn't grok how to apply all of the golden rules of regular GUI development to games. Recently, it started to click. You can apply a MV* pattern to games, very easily in fact, and create a clean code base that's organized, maintainable and can be easily changed (we all know how volatile a game's design and feature set can be!). So lets talk about how an MVP pattern can be applied to a Unity code base.

I'm not going to provide any specific code in this post (there's good reason why as you'll see later). This is strictly theory.

Let's say we have a player prefab. Normally, you may just write a bunch of specific scripts to do one thing and one thing only (hopefully) and attach each different script to the prefab. While this does work, I find it chaotic, especially when other scripts need to start talking to each other or one script needs to have its behavior changed slightly for one specific type of prefab. To do things the MVP way instead, we're going to apply a two scripts to the prefab called PlayerView and PlayerPresenter.

PlayerView will represent the View portion of MVP (well, duh!). PlayerView will contain zero game logic. It will strictly be responsible for handling the visual representation of the player, accepting input to pass along to the presenter, and exposing important properties that you may want to have adjustable in the Inspector view of the Unity editor, like health, walking speed, etc. PlayerView will listen for input from the player and pass along the input to the view's backing presenter via events and passing the presenter model objects with the necessary data.

PlayerPresenter will represent, can you guess it, the Presenter portion. Now earlier I said presenters contain the game logic, and in a lot of cases this is true, however I'm going to throw another pattern at you (I'M GOING DESIGN PATTERN CRAZY). Instead of putting all of the game logic for the player in PlayerPresenter, we're going to make use of the command pattern, or a variation of it. PlayerPresenter will be responsible for creating the necessary model objects (based on data from PlayerView) and sending those model objects to Task objects, which handle the actual game logic.

Model objects are very dumb. They simply encapsulate data to pass around. A bunch of properties, nothing more.

Task objects live to do one thing, and one thing very well. They accept model objects from the presenters, do a bunch of work, calculate player score or create a projectile object to spawn, for example, and if necessary sends the results of the work back to the presenter to update the view with. This creates extremely modular, reusable game logic that can be accessed from any presenter that calls it. This allows us to create flat class hierarchies as well, which is a great thing. We could let the presenters handle the game logic and perform the actual work, and in some cases you may, but that game logic isn't easily shared elsewhere and you risk either creating deep class hierarchies to share the logic, or repeating code.

So let's step back and see how a real example would play out. Let's go through an example of a player pressing the shoot button to fire a rocket from his rocket launcher.
  1. PlayerView receives a shoot input signal, notifies PlayerPresenter
  2. PlayerPresenter receives notification of the input, creates a SpawnProjectileModel model object of current player position, direction and weapon type (rocket launcher for this example) to send to the SpawnProjectileTask.
  3. SpawnProjectileTask receives the model object sent from PlayerPresenter, and spawns a new rocket launcher prefab with the data provided via the SpawnProjectileModel model object. 
  4. PlayerPresenter receives notification from SpawnProjectileTask that the rocket spawned successfully and notifies PlayerView.
  5. PlayerView updates its AmmoCount property to deduct one, which updates the ammo count graphics. 
  6. Done!
This may seem like a lot of steps and indirection to deal with to just fire a rocket, but you can easily change the games look and behavior without a ripple effect. Changing the player from a bad-ass marine to a human-hating robot requires you to only change the View class. Enemies can call the same SpawnProjectileTask as the player does and if the game logic should ever need to change, simply update SpawnProjectileTask and both Enemy and Player pick it up without having to touch either. 

Now the reason I didn't provide any actual code and stuck purely to theory is because there is a fantastic framework for Unity to do everything I described so far (plus more), StrangeIoC, which has excellent code samples and diagrams in the documentation and I felt it does better justice. StrangeIoC is an inversion of control, MVP framework. It's fairly new, but I'm using it for Overtime and I don't think I can code a Unity game without it. It's continually evolving and if anything I've talked about in this post is jiving with you, I highly suggest you give StrangeIOC serious consideration. Hopefully, I've convinced you to start considering a MV* type architecture for your next game. 


Tuesday, December 17, 2013

2D Platformer Collision Detection in Unity

NOTE: Please see my addendum regarding this solution, which is ultimately flawed as presented in this post.

Unity is a 3D engine that comes with built-in physics engines (PhysX for 3D, Box2D for 2D). However, if you're aiming to develop a 2D platformer, you'll quickly find that it's extremely difficult, I'll go as far as to say impossible, to achieve that "platformer feel" using these physics engines. For your main entities, you're going to have to roll a variation of your own.

Furthermore, if you attempt to use the supplied character controller package for your player in a 2D platformer, you'll also quickly discover that the collision detection and overall controls just don't feel right, no matter how hard you tweak it. This is primarily due to that the character controller package uses a capsule collider, which makes pixel perfect collision detection on edged surfaces problematic. So once again, you need to roll your own controller and collision detection system.

Since Unity is a 3D engine and regardless of the type of game you're developing (3D or 2D), you're game is being developed in a 3D space. You probably can achieve some canonical tile-based solutions for collision detection (perform check-ahead on the tile the player is heading into, and determine appropriate collision to take, if any, or example), but it's best not to wrestle against the engine. The best solution I've found is to use ray casting.

Ray casting seems to refer to different things (see Wikipedia), but the ray casting I'm referring to is the method of casting rays from an origin towards a direction and determine what intersects the ray, if anything. We can use this method to handle collision detection, casting rays from our player in both the x and y axes to learn about the environment surrounding the player and resolve any collisions.

The basic steps of the algorithm is as follows:
  1. Determine current player direction and movement
  2. For each axis, cast multiple outward rays
  3. For each ray cast hit, alter movement values on axis
I want to note that a lot of the following code is originally based off of the fantastic platformer game tutorial found on the Unity forums. However, I've heavily modified it to fix some bugs, mainly with corner collisions, which we'll go into depth.

Here's the entire class that performs the ray casts for collision detection.

It's important to note that this class is called inside of a separate entity controller (BasicEntityController) that handles calculating acceleration and creating the initial movement Vector3 object. BasicEntityCollision takes the movement and position Vector3 objects and adjusts them based on any possible collision detected from the ray casts.

The Init method does some one time initialization of required fields, such as setting reference to the controlling entities BoxCollider, setting the collision LayerMask, etc.

The Move method accepts two Vector3 objects and a float. moveAmount is, as the name implies, the amount to move before collision detection, as calculated by BasicEntityController. position is the current entity position in the game world. dirX is the current direction the entity is facing.

Move will determine the final x (deltaX) and y (deltaY) values to apply to moveAmount after all collision detection. Move starts the ray casting along the y-axis of the entity, followed by the x-axis of the entity, but only if they are moving left or right; we won't cast x-axis rays when the entity is idle. We then set the finalTransform based on deltaX & deltaY and return it so that the entity can finally use it to Translate!

Let's dive into the two key ray casting methods, yAxisCollisions & xAxisCollisions. First, note that both methods perform at least three different ray casts along the entities BoxCollider, on each axis. This allows us to get complete coverage for the entity.

Each line represents a ray cast.

yAxisCollisions starts by determining which direction the entity is currently heading along the y-axis (up or down), and calculates separate x and y values to be used to create the Ray objects to be casted along the box collider (from left to right, top or bottom). yAxisCollisions calls two different for loops based on which way the entity is currently facing. If we are facing towards the right, it'll start the ray casts on the right side of the entity, else it'll start on the left side of the entity. This was done to prevent a bug that saw the entity falling through the collision layer when moving to the right and downward due to a gap that was being created (because we break the for loop after the first ray hit we encounter) when the entity would collide with the corner of a tile.

When Physics.Raycast returns true, that means a ray cast has hit. We obtain the distance of the hit from the ray origin, and calculate a new deltaY to apply to the final move transform. We pad this value slightly to prevent the entity from falling through the collision layer accidentally.

We pad the deltaY value slightly to keep the entity above the collision layer, to avoid accidental fall throughs.

With our deltaY calculated, we move on to the x-axis (again, only if the entity is actually moving along the x-axis). xAxisCollisions is very similar to yAxisCollisions, but simpler. We don't worry about which direction the entity is facing, instead we worry whether the entity is either moving on the ground or currently in mid air. If we are moving mid air, there's a high risk of landing on the corner of a tile, which we could fall through. To help prevent that, we cast a larger range of ray casts along the x-axis (4 instead of 3) with the outer 2 rays that are casted slightly outside of the box collider width. When a hit is detected on the x-axis, we simply set our deltaX to 0 and return it.

When moving through the air, we cast a wider range of rays slightly outside of the entity's boxCollider width.


And that's the magic behind using ray casting to perform collision detection. The finalTransform will be sent to the entity to be used with the Translate method. Here's a small video clip showing the Debug.DrawRay calls. When a ray is hit, it's colored yellow.


For further reading on the topic of a 2D platformer controller for Unity, there's an excellent blog post on Gamasutra by Yoann Pignole that goes into great detail.

You can also see a more complete implementation of the collision detection code at the following Gist.

Friday, December 13, 2013

Overtime Developer Log 0

Overtime (working title) can be best described as a Unreal Tournament demake. For my Ludum Dare 26 entry (http://mindshaftgames.appspot.com/games/LD26/ld26.jsp), I asked myself “what if Unreal Tournament was made for the Atari 2600?”. The game, while very simple (hey, I only had 48 hours to make it!), was a lot of fun. I decided to take the game idea a bit further and ask myself “Okay, but what would Unreal Tournament look like if it was made for the Super Nintendo?”, and that’s essentially the game I’m looking to create.

Most of my game development experience is in either XNA or ImpactJS, but I decided to use Unity this time around, mainly for the multi-platform support, but I quickly learned there are tons of other benefits to using Unity too. That said, I had to learn how to create a 2D game inside this 3D engine. Luckily, there are fantastic 2D plugins to help with creating and managing sprites, to which I’m using 2D Toolkit. The biggest hurdle (initially) was how to handle collision detection and platformer style physics. While Unity can handle these problems out of the box, they are ill suited to achieve that true 2D platformer feel in my opinion, so after checking out a few articles and tutorials on the subject, I rolled my own using the battle proven raycasting method. 

Early tech prototype


With that in place, I began working on a prototype of a basic deathmatch mode inside a small, single screen arena. I unfortunately don’t have any videos of the initial playtest, but the results were very positive, resembling the intense, twitch based experience of a Unreal Tournament deathmathch or even a Super Mario Bros. Battle game. Thus, I felt it was worth fleshing out a full design and moving forward with it.

On a sidenote about Unity, I found it initially difficult to create an organized code base (a common complaint about Unity scripting, I’ve discovered). I scripted my prefabs in a somewhat traditional Entity based system, very similar to how ImpactJS is structured. I made some decent progress before deciding to rewrite the entire game using StrangeIOC (http://thirdmotion.github.io/strangeioc/), a MVP-like inversion of control framework. Ignoring the benefits of inversion of control alone, it does help enforce excellent code structure, separation of concerns, event handling, all while preventing deep class hierarchies. If you’re a Unity developer, I would check it out.

This is the game in its current form. 
Gameplay footage


Some (boring) screen shots



I only have one playtest map setup but there are a few weapons available, support of split-screen cameras, players can double jump, energy (ammo) packs, level triggers (one which causes an earthquake) and first blood & double kill checks, to summarize. There are more weapons I need to implement, as well as the expected game modes of CTF, team deathmatch, but I also have other unique game modes in mind. For assets, I’m currently using open source sprites I find and I’m using bfxr to generate all sound effects. Once I’m further along development, into an alpha stage, I’m hoping I can capture interest from actual sprite artists and composers. 

Moving forward with development, the two big questions I have to consider are do I include network multiplayer and do I include bots? These are two areas I have no experience in, and I’m risking blowing the game out of scope. Regarding networking, from what I’ve gathered so far on the topic, I should make a decision to include it or not now, rather than try to shoehorn it in later (many things need to change, from instantiating objects, to communicating player input). Since I’ve already made fair progress on the game already, and already went through one total rewrite, I know I’d have to rewrite a majority to get networking involved, since I’ve foolishly waited too long to consider it. Thus, I’m leaning towards not including networking. Yes, this does come off as “lazy” on my part, I admit. In my defensive, multiplayer indie games generally don’t have a large enough pool of players after immediate launch to sustain a multiplayer community anyways (see Gun Monkey).

Bots are something I do want to include, though it’s a huge engineering effort. I essentially need to create Quake 3 Arena level of sophisticated AI (you can read Jean-Paul van Waveren’s thesis paper on Quake 3’s bots http://fd.fabiensanglard.net/quake3/The-Quake-III-Arena-Bot.pdf) in order to make it work. It’ll be a lot of work, tons of trial by fire, but I’d love to be able to provide a singleplayer experience as well, since I’ve personally spent the majority of my Unreal Tournament time playing against bots! Outside of finite state machines and very basic behavioral trees, AI is a new frontier for me, but I’m eager to face it. The biggest problem I see ahead is getting bots to navigate their environments.

So that’s my current progress right now. I’ll probably be tackling bots next before continuing to implement all of the planned weapons and game modes, because I hate huge problems nagging at me and would love to solve it right away. Plus, it’s becoming increasingly difficult to playtest a multiplayer only game! I’m only working on this (barely) part-time, so progress will be slow, but hopefully at a steady pace.

Friday, October 18, 2013

* R E D T H R E A D H I J A C K *

One of the most influential books I've ever read as a developer is Masters of Doom. It's an inspiring story for any game developer or entrepreneur.

Jeff Atwood just made an equally inspiring post about id Software's story, You Don't Need a Million Dollars. He's right. When I was a filmmaker so many years ago, the same message was drilled into me. There are no barriers anymore for aspiring creative minds to create something great. Sure, you may have that full time job, but there's always time afterwards to chase the dream, and the resources available now are unprecedented. I want to say overly so, as to lose the whole "art through adversity", but I've been told that's too cliche to say...

Take the following excerpt from Masters of Doom;

Carmack turned red. “If you ever ask me to patent anything,” he snapped, “I’ll quit.” Al assumed Carmack was trying to protect his own financial interests, but in reality he had struck what was growing into an increasingly raw nerve for the young, idealistic programmer. It was one of the few things that could truly make him angry. It was ingrained in his bones since his first reading of the Hacker Ethic. All of science and technology and culture and learning and academics is built upon using the work that others have done before, Carmack thought. But to take a patenting approach and say it’s like, well, this idea is my idea, you cannot extend this idea in any way, because I own this idea—it just seems so fundamentally wrong. Patents were jeopardizing the very thing that was central to his life: writing code to solve problems. If the world became a place in which he couldn’t solve a problem without infringing on someone’s patents, he would be very unhappy living there.

I've always felt the exact same about patents, but we have to consider the world we live in today. Patent trolls are real, and if you don't protect yourself and your business by filing patents, you may find yourself waking up from your dream very, very quickly. Understand why Carmack said this in the 90s, and understand why anyone should file a patent today.

Oh wow, this thing still works??

It's been awhile, seven months to while. A lot has happened during those seven months. I did some game jams (http://mindshaftgames.appspot.com/games/LD26/ld26.jsp), switched technologies, and started developing a game that will truly be my first real, full release.

After Ludum Dare 26, I began to really think about my next game, which I wanted to be my first real release. A full, complete, polished game that people would (hopefully) pay money for. This required me to really start growing my game design and project planning skills. I had an initial idea of doing an elaborate Metroidvania game in ImpactJS (can you immediately see the impending failure?). I created a bunch of design docs and even prototyped something in ImpactJS but ultimately killed it. It was too ambitious and to be honest, there was another genre of game that I simply would like to play much more. We'll get to that in a minute, but let's talk about ImpactJS more.

ImpactJS is a great, fantastic game engine. As new as HTML5/JavaScript game development might be, ImpactJS showed me that it's a very viable solution for developing a tile based 2D game. Not only can it be deployed to the web with no plugin (sweet!) but to mobile and even as a desktop .exe through Node Webkit , which I got up and running and was very impressed with; the performance is incredible.

All that said, I ultimately decided to switch (back?) to Unity. There are few reasons why I did, the main one being the JavaScript language itself. Firstly, I greatly enjoy first class functions (I truly feel functional programming is on the rise due to its implications with concurrency, but that's another blog post in itself), but if you give me the choice of a dynamic or static language, I'm taking the static language. And for the scale of the project I had envisioned, doing it in a dynamic language seemed crazy. Doable, absolutely, but crazy.

Also, Unity handles a few things better, primarily networking, split-screen cameras and gamepad controllers. ImpactJS can technically handle gamepads through the Gamepad API (which I did get implemented and working in the prototype), and networking through WebSockets, but right now, all of that is a lot of trouble and kinda hacky. Also, no split-screen camera support is a deal breaker, and while I never tried to actually implement them, from what I gather from the ImpactJS documents and source code, it doesn't seem possible.

And to be completely honest, the other reason for switching to Unity was simply because I tried doing a 2D platformer Unity in the past, but ultimately failed to figure out collision detection properly and couldn't grasp how to doing things "The Unity Way", as I've coined (just look a few posts back). That nagged the shit out of me. I had to go back and figure it out. It was a defeat I couldn't leave alone. I ultimately did begin to grasp the concept of using Raycasts to detect collisions, and started to understand the Component-Entity system that Unity enforces. It must sound crazy that this was a driver for me dropping ImpactJS, but there was a problem that I couldn't initially solve, and it bugged me to no end.

Also, with my original Metroidvania idea, I was aiming not only desktop, but mobile, and ImpactJS didn't provide ideal performance on Android through CocoonJS. This is my own individual findings, and it could be due to my shitty code, but I've experienced better performance in Unity, so that was another deciding factor. All that said, I've ultimately decided to drop porting to mobile with my new game design.

So what exactly have I've been developing the past several months?

 *drumroll*

I don't have a title yet. *fart sound*. However, imagine if Unreal Tournament was developed for SNES. That's essentially the game I'm out to make. A 4-player arena platformer. This genre has seen a recent influx with games like TowerFall, Gun Monkey, The Showdown Effect and Atomic Ninjas. I've only played Gun Monkey and The Showdown Effect so far, and watched many videos of TowerFall (I will buy and play the PC release when it comes out!), but they seem to offer a much different experience than what I'm aiming to provide. I want to recreate that intense, 90s/early 00s competitive FPS experience, but in 2D platformer form. I've done an initial playtest with some close friends recently, and I seem to be on the right track! There was tons of shouting, screaming, and intense action.

I want to get into further technical details of what I'm doing in Unity, as well as some creative details, but I'm going to save all that for future (near future, I promise) posts, because there's a lot to talk about. Even though this is exactly what this blog may seem like so far, I hate opinions, give me facts with insights. I'll be sure to give you plenty of facts with some crazy insights. I hope you find it useful.

Monday, March 18, 2013

We have Impact

I've decided to kick Unity to the curb. After using it for a few weeks, attempting to create a very simple 2D sprite based platformer using 2D Toolkit, I've come to the conclusion that it's not the best tool set to use for that type of game. There's simply too much wrestling involved with the Unity engine to complete even the most simple of tasks, for example tile based collision detection. Perhaps it's my inexperience, but when the toolset I'm using is hindering my productivity and progress, rather than boosting it, I tend to reevaluate the situation.

So the hunt for a new game engine/framework/toolset/etc began! There were a few criteria that I needed to have satisfied.
  1. Deployable to the web (option to mobile is nice to have as well)
  2. Good documentation and community support
  3. Remove the need to write the majority of boiler-plate, 2D game engine code, yet allow me to extend it as well
I had my eye on ImpactJS for awhile, and after determining what my needs were, it seemed to be the best choice (even with the license fee). And so far, it absolutely has been. You can see what I've managed to cobble together in only about two weekends worth of time. I'm going to reserve a full "review" of ImpactJS for another post, but I'm extremely happy with ImpactJS. Worth noting, I also get to use my favorite IDE, IntelliJ IDEA! Nice :)

Oh! And I've decided to join One Game a Month. My March entry will be a simple Lode Runner-like (linked above). Obviously, it's very much a work-in-progress as of this posting, but I fully expect to have it finished, and somewhat polished, for the March deadline. 

Tuesday, February 26, 2013

Get to the script

Related to my last blog post regarding accessing setter methods of a prefab script, originally, I was accessing the script through a class field of type Transform, which was attached to a enemy bullet prefab. To get access to the script, I needed to call GetComponent from the returned reference by Instantiate. See the Gist below.



From what I've been told by internet anonymouses, GetComponent is an expensive call to make, especially given the high frequency that fireBullet gets called. A better alternative? Change the class field type from Transform to the script class (EnemyBullet, in my case).



Now you avoid the GetComponent call and get a direct reference to the script. This works in my case because the Enemy class only really needs reference to the EnemyBullet script of the particular prefab. It doesn't use the prefab's transform or other components. If you have a case where you're accessing multiple components of a particular prefab, then you can't avoid the calls to GetComponent. However, figure out which component you use the most and set that as the class field type, to reduce the number of GetComponent calls you make. 

The Unity Way, or....THE UNITY WAY!

When you use a complete "out-of-the-box" game engine like Unity, you're going to be forced into using it in ways that you may not like. Seems obvious, right? You're going to have to do things that may seem counter-intuitive and just deal with the design decisions made by the Unity team. You"ll need to do things "The Unity Way". If you're coming from a different game development environment, regardless of what it is (C++/DirectX/SDL, XNA, etc), there's going to be a great learning curve when starting with Unity. 

A good example of this is how you instantiate prefab objects in a scene. Instead of using the new operator to instantiate a new object (or making use of a factory method), you instead must make use of Unity's Instantiate method. Now there is some sound reasoning for this. When you instantiate a prefab, you're actually instantiating all of the multiple components that make up a prefab as well. The Unity documentation explains it well. You can think of the Instantiate method as a somewhat non-traditional factory method that creates and returns your complete prefab instances, so that you don't have to "new" up the code and piece together the prefab by hand.

There is a downside to this. What if you want to change a script parameter of the prefab at instantiation? Hmmmm..., the Instantiate method doesn't support parameter passing, unlike a traditional constructor would. Instead, after you instantiate the prefab, you have to obtain a reference to the attached script, and modify any fields through setter methods. 



The above Gist is from my Enemy script. My enemy prefabs travel at a random velocity. Because of this, I need to be able to adjust the speed at which the bullets they fire travel at as well; I was running into scenarios where when the enemy fired a bullet, they both might end up traveling at the same, or near the same velocity. Instead of simply passing speed + BULLET_SPEED_MULTIPLIER as a constructor parameter upon instantiating, I need to do things "The Unity Way". 

So I do things "The Unity Way" and I change the fields of my script through setters instead. Not the end of the world. OR IS IT?!?!?! When I went to test my BULLET_SPEED_MULTIPLIER, I noticed that the bullet speeds were unaffected. Why? Because I was setting the enemy bullet speed in the Start method of my EnemyBullet script.



If you read the Start documentation carefully, you'll find out that "Start is called just before any of the Update methods is called the first time". It seems that the execution path is essentially (ignoring several other methods being called in between, I'm sure):

fireBullet -> Instantiate -> setSpeed -> Start -> Update 

The lesson of the story is to be careful of what fields you set in your Start method, because that's the value that will be used regardless if you used a setter method immediately after instantiation. It could be argued that this bug would have happened even if I was using a constructor, because Start would have gotten called by the Unity engine later on anyways. I would then counter argue that I probably wouldn't have even used Start to initialize key variables, if I was using a constructor ;)