Hello again interwebs!
So Ludum Dare wrapped up last yesterday, and I've been recuperating. Yeah recuperating sounds good. Sounds way more reasonable than failing to write promised blog entries out of laziness.
In all seriousness though, the Ludum Dare Jam was a blast and I'd like to the UVic Gamedev, Techtoria and the game developers of Victoria for hosting the event. And of course, Ludum Dare themselves for giving indies around the world an excuse to get ourselves of our butts and really crank it for a couple days. Events like this are a really great reminder of just how much you can get done in a very short time with a lot of effort and a good team.
Speaking of good teams, I have to especially thank Shane Gordon who provided all the art for this game. (Except the sky, that's Unity's default skybox.) I met Shane when we wound up sitting together in the main presentation room just before the jam started, then we broke off to brainstorm some, by which I mean one, concepts and before you knew it, we were working on a game. Shane provided fantastic pixel art and the right balance of detailed vision and quick stand in work that makes a jam game really work. So yeah, thank you Shane.
Now on to the game itself. I am happy to say this is probably the best game I've produced at a jam so far. I don't think I've been this satisfied since Jubble. The secret to a good jam game is good scoping, and this feels like the best scoped game I've done since Coffee Island Madness. I guess Soup Bubble was scoped well too, but it always felt like it was missing some of the more finishing touches. Coffee Island Madness had multiple end states with proper end screens and exactly as much content as content as I envisioned, where Soup Bubble just reset, including the music, which is a little jarring. Anyway, the new game was definitely better scoped than my previous jam game, What Do We Do Now IN SPACE, which never really had any joy to it. It played in a very static way that randomly changed, but I had so much more that I wanted it to do that the game felt lacking. Not so with this one.
So as I was saying, to succeed in a game jam, you need to figure out a project within the scope of what you can accomplish in a weekend. My game this time around has also solidified, for me at least, the archetypical process by which a successful jam game is created. Let's walk through it shall we?
Night one is the busiest having the biggest set of things that need be done, and the shortest amount of time to do them in. First you need your team. Game jams are experimental, so theres no need to be super discriminate about who you work with. Find someone else who wants to make a game and has a complimentary skill set and get to work. You can decide at the end of the jam if your teammates were helpful or good at their jobs. Nothing is really riding on a game jam, so take a chance and meet some people.
Of course, there are two easy ways to avoid this. Form a team before the jam, or work solo. Both have their drawbacks. As a person who has done the majority of my games solo, I can say with certainty that it's hard. You only have so much time, energy, and useful consciousness, and on top of art, programming, sound, and level design, you also have to add time management to your workload. Most jam teams are small and have instant communication between members that occurs within earshot of the rest of the team, so they effectively manage themselves autonomously. The solo jammer must estimate the time they will need to program every element of the game and still reserve enough time to create the art assets and enough sounds to not feel empty. And there's no winning here. Some part of the game will inevitably lose out to more important tasks.
As for pre-formed teams, this is a bit more of a personal experience thing, but I've found that I learn more and generally get a better project when I work with strangers. For one thing, you are forced to communicate from the get go. People working in a team of friends or co-workers can often have a lot of information that they assume their associates already know leading to misunderstandings later in the process. In a team of strangers, everyone needs to clarify the jobs, goals, responsibilities etc before they break off, because no one can assume anything. Besides that, you can work with your friends any time. Jams offer a kind of combination networking team building exercise that is directly relevant to your work.
The next thing you need on night one is an idea. Best tip here is to be discerning, but not picky. There aren't any hard and fast rules about aesthetics or how well a game matches the theme, so feel free to stretch, what's important is feasibility. You want an idea that will be fun, even if there is only one level, or only one screen. Avoid concepts that are too sophisticated and don't take anything that wouldn't still be fun even if it were only half completed, because, it will only be partially completed. But beyond that, take the first idea that seems doable and run with it. It will almost certainly be more than you can actually deliver, but we will deal with that later.
Now it's time to delegate responsibilities. First figure out your programmer. Every video game needs one. No programming = no interaction = no gameplay = no game. For the first night your, programmer needs to know what they are building, then get to work while the rest is figured out. The next must fill position is the artist. Video games are a visual medium, and you player's main source of information about your game will be sight. Find an artist, give them a rough idea of how the game needs to look, and get them grinding out early stand in assets ASAP, nothing super detailed, just enough to be identifiable.
Every position after that is optional or situational. A sound developer is highly recommended, but not essential. Sound rarely gives the player critical information that isn't also communicated visually, but it greatly enhances the feel of a game. Most games can be played on mute, but the experience is lessened. Sound can also be delayed. I almost always get the sound integrated on the last day of the jam unless I have a dedicated sound person on the team. It's often easier to time share someone who is doing sound for several teams, or to have one of your team members switch to finding or creating sounds after most of their work is done.
Also recommended is a dedicated overall game designer. I usually wind up doing the design as well as the programming on my own games, and consequently have to split my time between developing features, and a combination of testing myself, play testing with others, and parameter tweaking. That's a lot. Ideally, a designer could get a kind of break off build of the game that they could take around for play testing and modify the parameters of, freeing the programmer to create the next feature.
Lastly, level designers and writers. Both of these roles are incredibly optional. Writing and level design are mainstays of a content driven game, which is usually a risky prospect for a jam game. Content is only good if there is enough of it and it often winds up being a black hole that sucks the time and energy away from development. Generally a game that relies on content is a bad idea for a jam. But if you must have content, then it is extremely helpful to have a person dedicated to developing that content and thus freeing up everyone else. Beyond that, minimize the content as much as possible. If your levels need space, then only make one. If your levels are very short, maybe make a handful, but keep it under 5 or so. Everything you add will increase the need for play testing and iteration and those take a while.
So now that you have your team organized, it's time to get a working minimal prototype. The main thing to build is the player's main interaction with the game. If they have a character on screen, build working controls and figure out how the camera moves in relation to them. If there ore objects you need to be able to interact with, put one on the screen and make sure you can interact with it. Nothing has to look good but you should be getting an idea of what your game feels like and wether or not your main interaction is engaging.
Then go to bed. Many people will tell you that the most important resource in a game jam is time. It is not. The most critical resource is useful consciousness, time in which you are rested, focused, driven and capable of doing your task. The key to getting useful consciousness is to sleep. So everything on night one needs to be dome as fast as possible so you can go home and sleep. Generally a game jam starts around 6 with a keynote that takes anywhere from 30 minutes to an hour. this leaves you with about 3-4 hours in which to get an idea, get organized and get a basic prototype before you crash. And that's why night one is the busiest.
So how did my game this jam match with this schedule. Well, the keynote was quick, which is always helpful. As I said earlier, I met my partner for this jam during the keynote and we got to work almost immediately. We had a concept for the game, Jaws from the perspective of the shark, after maybe 5 minutes and a fleshed out idea of the gameplay after about 15 more. And before we headed home at around 10pm we had a prototype that answered the main design questions of the game.
How do you interact with the game? You rotate the shark clockwise or counter clockwise and press space to give yourself some forward momentum.
How does the camera interact with you? It doesn't. The camera is fixed and you cannot escape the screen.
What else is there? Stuff you can eat. That stuff gets destroyed when you collide with it. also stuff you shouldn't eat that hurts you when you collide with it.
Is it fun? Hell yeah! This is the first jam i've had where I actually lost a substantial amount of time because I was too busy playing my own game.
So was it perfect? Not quite. A few things were missing from the night one version. The test fish is static and there's only one, but it's disappearance is still triggered correctly, so there was a skeleton to build the rest of the interaction around. My memory is a touch foggy on wether the walls were in the scene yet and I can't actually tell from the video, but I think they're missing. There's also no enemy, but you wouldn't be able to tell the difference because there's also no health to lose on contact with them. There's probably a bit more development of the visuals than was necessary. Normally, the shark would only need to be a box at this point, but I had never worked with the animation systems in unity to this level of integration, and I wanted to be sure I could do it. What I'm glad we did have was the movement and the relationship with gravity. All in all though, this was about as good a night one prototype as I've ever had.
So after getting some shut eye, what's next? Day/night two is when the lion's share of your development will happen, so it's mostly just cranking out the features that your game needs. The specifics really depend on what you're making, but in general there are a couple reasonable milestones to aim for. By lunch time, try to have a play testable version. Art can still be boxes, and sounds can still be missing, but be playable and have at least one representative for each thing in your game ie 1 enemy, 1 power up, etc. Have a working version of your UI regardless of how ugly it is. And have the game completable. Be able to go from a start screen to the game play and back again.
In our case, by the middle of the day, we had invisible walls that kept the player on screen, black box fish that moved at a constant speed or in pulses like the player, red box enemies with the same movement patterns as the fish that the player would bounce off of, a random enemy spawning system, a labeled energy bar that increased when you ate a fish and decreased when you hit an enemy, and start screen that explained the controls and transitioned smoothly into the game and back when you died due to loss of energy. I think we also had an oxygen bar, but it didn't do anything yet. Shane had also created most of the assets, but almost nothing had been integrated into the game yet.
By dinner, you should have a clear plan for the rest of your game. You should have enough work to put in now to estimate what you can still develop and what will be too much work. With that in mind, cut a bunch of stuff from your concept and narrow down a few remaining features that are important enough to cram into the game. Here's a quick list of a bunch of things we opted to remove from our game:
- animations of creatures other than the player
- falling nets that slowed the player down, impairing their ability to get oxygen
- a player sprite that changes to match the direction the player is facing so that the shark is never swimming upside down
- depth charges
- edible humans on boats
- complex harpoon spawning patterns
So once you've cut a bunch of stuff, make a short list of things you want in the game by the end of the night. This should include all the features you plan to have in the final version as day 3 should be all about tying up loose ends and polish. Our list was as follows:
- Add the oxygen mechanic (the player loses oxygen while still and regains it when moving)
- Add a third movement pattern which included vertical pulsing or bouncing
- Add boats and divers which spawn harpoon enemies
- Add blood effects and smashed effect for boats
- Add make it so boats have a solid collision area on the bottom and a squishy area up top so they have to be attacked from above
- Add a squid enemy that rotates between forward pulses so that it moves in a way identical to the player
- Start integrating sprites
- Add a score system so players have something to accomplish
And once you have them, blitz them. As with night one, you want to get as much done as you can and then go home and sleep. And note that by this point on day 2, useful consciousness will be running out, so you will almost certainly fall short on your plans. Anything you can't get done, drop or push it till morning 3, but don't leave yourself more than about an hour's work for the last part. You will be very tired and very stressed by that point. Of the items listed, I only got the oxygen system, the bouncing enemies and the divers spawning harpoons to work. I kicked the boats spawning harpoons to the morning because they were just a variant on the divers that I knew could be made easily. I also knew that there would be some programming to add the background tiles, but since that would be accomplished through textbook nested for loops, it was safe to leave until integration time.
At the start of day 3 look over whet you wanted to get done, and what you've accomplished so far. Pick out the easy stuff to do and drop everything else. The time for feature development is pretty much over. Quickly knock off what you keep and move on to debugging, integration and polish.
So as of morning on day 3, I finished off harpoon firing boats and then started integrating Shane's art. This is where I hit the only significant bugs. As I was integrating the art, I had to also fix the collision boxes which had been sized to the early test assets with no real idea how large the final assets would be. Unity scales stuff anyway so we knew we would be able to get a size that worked, I just didn't know what it would be and the collision boxes weren't tied to the image sizes, so they had to be adjusted manually. When I came to the megalodon, the big square jawed enemy shark, I hit an unexpected snag. In Unity, there is no way I have yet found to make hard collision boxes only apply to certain other objects, so an object which would bounce the player would also bounce the walls. But the space between the screen edge and the walls had to be small enough that the player couldn't entirely escape the screen, so there wasn't enough space to fit the giant megalodon. Instead the shark would bounce off the wall and either repeatedly hit it until it stopped moving altogether, or bounced off so hard it made it to the other wall and bounced off of that in a positive feedback loop that only ended when the shark was moving so fast that it clipped through the wall and was destroyed. The only way to avoid this was to make the shark collision box a trigger region instead, meaning that it wouldn't have any solid substance. This created a new problem since the player could trigger the shark again without having left the trigger area yet and it looked sloppy to boot, so the megalodon damage was upgraded to an insta-kill. This way it was still broken, but no one would actually see it.
The other bug was a slight hick-up I created when I added the final assets for energy and oxygen bars. I stupidly entered them as sprites instead of UI images, so they didn't disappear properly with the rest of the game play assets. Because the bars themselves did disappear and the energy and oxygen bars were both mentioned in the instructions, I just opted to leave them that way and move on.
Meanwhile Shane was working on gathering/creating music and sound effects as well as giving the game it's title and creating a cleaner, art style consistent version of the instructions. My memory is a little foggy on the sound, but I think the swim sound and possible the final music were made/found on day 2, though not integrated until day 3.
The last bits of development on my end were programming the toiling of the background assets, adding the crunch effect when a fish or ship got eaten, and value tweaking to differentiate the fish and enemies from each other and make the game more challenging. Everything else got cut including the following:
- a smashed up ship version of the crunch
- boats having different collision areas
- the rotating pulse squid
- the score system
And then it was just a bit of fiddling at the end to get the game properly submitted before I had to leave the jam for another appointment. Day 3 was pretty much textbook, everything either got hastily thrown together or cut and the game that was left was polished to a satisfactory state. And that is how you game jam.
So what went well and what would I want to improve for next time. For me one of the best decisions I made this jam was programming individual behaviours rather than whole operating scripts for both the enemies and the non entity functions of the game like enemy and tile spawning. By separating things into individual behaviours and having most of the scripts driven by public parameters, the scripts could be easily re-used on different enemies with different parameters even if new enemies needed additional behaviours on top of them. For example, the clownfish, fishing boats, constant speed divers and megalodon all move using the same script. The divers and fishing boats each have an additional behaviour on them responsible for spawning harpoons. This is a pretty basic OO technique called composition, but it takes some presence of mind to see the opportunity for it and take advantage of it. Otherwise it's very easy to end up with a player that manages the entire game like I have in What Do We Do Now IN SPACE.
These behaviour scripts were also similar to each other in organization so variations could be easily made by copying and modifying the existing behaviours. The player movement was copied over and tweaked to use RNG rather than keyboard input to create the pulse swimming script, which was in turn copied and modified to create the bouncing script.
Another good decision was separating the random generation of fish and enemies from the selecting their location and direction of travel. The generator only chose which object to create and created it off screen. Each object randomly chose a position, speed and orientation in it's start routine so the parameters for these selections could be specified on each of the object prefabs.
As for improvements, my biggest mistakes were not getting enough sleep, and not looking at the submission system in advance. Almost all the stress at submission time came from figuring out where to host the game and fixing the resolution so it could would appear properly. Even though we got the game submitted on time, anyone playing through the link on the Ludum Dare web page would find that the sides of the screen got clipped off due to the resolution limit and the screen doesn't auto scroll to the centre. I had about 15 minutes to get that to work though, so as soon as what appeared was playable we called it and I was out the door.
Regrets? Well there are a couple things I want to fix. There are a bunch of fully programmed but not tested enemies and targets that I didn't manage to squeeze into the spawning system before submission and I really wand to fox the bar background displays so that the projects don't swim between them and the bar, but my biggest regret is not getting the score system into the game in time. With out it, it feels like the game can be lost, but is can't be won, or even succeeded at on any level other than not dying for a longer time. I'll probably fix these in the coming weeks, but in the interest of intellectual honesty, I like leaving the jam version in tact as a genuine display of exactly what was accomplished during the game jam. So I'll probably wind up with 2 versions on my website.
For now, you can play that genuine display of game jam awesomeness entitled "The Deep" right here.
That's all for this this post. I hope this has been enlightening. This blog will be going quiet for a little while as I'll be spending all weekend in Seattle for PAX Prime. But when I get back, it will be time for the second part of the Showdown retrospective analysis.
See you there!
Lambwattage
Wednesday, 26 August 2015
Saturday, 22 August 2015
Ludum Dare: Night 1
Good evening interwebs.
I gotta keep this one quick.
So the theme this jam is "You are the monster". And what monster is more classic than the mother of all killer sharks, Jaws. So I'm working with an artist I met at the jam on an arcade style game where you are a killer shark, eating all the peoples and trying not to get shot, netted, harpooned, dynamited, devoured, or krakened. You move by pressing forward on the spacebar and using A and D to rotate yourself. Already have the movement working, and it's pretty fun.
Here's a sample:
I'm feeling good about this one. Hopes are high. Will keep you posted.
G'nght!
I gotta keep this one quick.
So the theme this jam is "You are the monster". And what monster is more classic than the mother of all killer sharks, Jaws. So I'm working with an artist I met at the jam on an arcade style game where you are a killer shark, eating all the peoples and trying not to get shot, netted, harpooned, dynamited, devoured, or krakened. You move by pressing forward on the spacebar and using A and D to rotate yourself. Already have the movement working, and it's pretty fun.
Here's a sample:
I'm feeling good about this one. Hopes are high. Will keep you posted.
G'nght!
Thursday, 20 August 2015
Showdown Tech 1: Everything's a Square
Hello again interwebs!
So, when I started this blog, I intended it to be a dev blog for Stratagem (Showdown from here on out), but having restarted the game repeatedly and never having been sure what would definitely work and what would get thrown away, I never really shared the ins and outs of what I was creating. It's time I fixed that. So here begins a multi part series about of few of the design decisions and implementation details of Showdown. It won't cover everything, just the suff I think is worth taking the time to write about.
But first I want to summarize the design of the game so it's clear what I was trying to build. Firstly, Showdown is a twist on a turn based game. Rather than each player taking their turn on their turn the way titles like Fire Emblem or Advance Wars are played, in Showdown, both players make a single command for a subset of their units while their opponent does the same in a manner similar to an asynchronous strategy game like Diplomacy. However, the commands are still resolved sequentially, first one player, then the other. In the original specs, each turn would consist of 3 commands from each player, so when the moves were resolved, the computer would resolve player 1 move 1, then player 2 move 1, p1m2, p2m2, p1m3, and lastly p2m3. Since the player who's move is resolved first gets the benefit of knowing the exact position and stat of each unit at the time of the first move, the resolution order alternates each round, so in the second round would go p2m1, p1m1, p2m2, etc.
This alternating turn order is also the game's only uncertainty beyond the RNG in map generation. A move carried out in the same situation will always have the same result. The variable is always the other player's decision, which can be very predictable if you know your opponent well, and wildly unpredictable if you do not.
Another important component of the original design was a variety of units. There were six units in the paper prototype, 2 melee types, 2 archer types, and 2 cavalry types. Each command would only apply to a single unit. This approach evolved into one where units with similar properties could be given similar orders, ie two archers could be told to attack the same target. Since all units could move, movement orders could be given to all units simultaneously, but the set of available orders differed depending on the unit type. Archers had 3 different kinds of shooting orders while cavalry had no ready order. This was a major point of confusion and led to most players only using one unit at a time. Now for the sake of having a very minimal starting point and finishing before my deadline, I wound up only using one type of unit in the prototype, but the solution I'm about to explain works regardless of the unit type, so it doesn't really matter that all the units are the same variety of archer. The design still assumed that there would eventually be more units in the future.
To encourage more co-ordinated movement, I toyed with the idea of a formation orders, a set of orders used in place of individual orders whenever 2 or more units were being commanded. A vague order would be given to a whole group of units and each would unit would respond in its own way. At first it looked like even more complexity, but then I realized that the formation orders could be the only orders so that each unit was defined by the way it responded to each of the orders. This simplified the game in two ways. Firstly there was now no difference between the controlling one unit and controlling 100; the same order applies regardless of the number of units. Second, the pool of possible orders could be reduced to just a handful. In the version on my website, there are 4: move, attack, ready, and none.
With this view of units, individual unit types and capabilities are not nearly as important as a unit's location on the board. All actions have to be carried out in terms of location relative to the selected unit. Hence the design decision that this blog is focused on, everything's a Square.
What do I mean by this? Let's look at an attack order. In most turn based games, a player selects one unit and gives it an exact target. Often this can combine moving and attacking so that a unit moves into range of its target then attacks the unit directly. Attacks are an interaction between units, with location on the board as a limiting factor. Now try to imagine controlling 2 units at the same time with the same command. Movement is simple enough, both units follow the same path, assuming they have the same movement capacity. But which unit do they attack? They can only attack the same unit if they we close enough at the start that they will both be in range of the same target at the end of their movement. Both could attack the same tile relative to their final position, but this can easily cause one unit to have no target. As an interaction between units doesn't make sense.
In Showdown, actions are performed on squares. An attack order consists of a set of selected units and a direction. There is no movement to consider because movement is in a separate order. Each of the selected units sends an attack in the same direction from its current location. Since the action isn't targeted or specified in terms of one unit, it feels perfectly normal to affect an empty square. We've changed the semantics for the player from "shoot him" to "shoot that way", and made it much easier to resolve the results of an attack ord. The key is that an action is an operation on board locations rather than the units themselves.
Let's talk implementation. A Square in Showdown is a basically just a wrapper for a co-ordinate pair, specifying a single space on a 2D grid. We have horizontal and vertical co-ordinates, and the methods necessary to copy and compare them them.
public struct Square{
public static Square getNullSquare(){
return new Square(-1,-1);
}
public int x { get; private set; }
public int y { get; private set; }
public Square(int x,int y) : this(){ this.x = x;
this.y = y;}
public override bool Equals(object o)
{
return o is Square ? Equals((Square)o) : false;
}
public bool Equals(Square o)
{
return x == o.x &&
y == o.y;
}
}
The important part on the implementation side is the relationship between Squares. This is contained in the idea of a Direction. A Direction is a like a unit vector, containing the x difference and y difference necessary to move to an adjacent Square. A unit will only move one Square in a cycle, so a distance of several Squares is made one step in a Direction at a time. Let's have a look at Direction:
public class Direction{
public const int NONE=0;
public const int NORTHEAST=1;
public const int EAST=2;
public const int SOUTHEAST=3;
public const int SOUTH=4;
public const int SOUTHWEST=5;
public const int WEST=6;
public const int NORTHWEST=7;
public const int NORTH=8;
private int x;
private int y;
public Direction(int x, int y){
this.x = x;
this.y = y;
}
public bool equals(Direction d){
return x==d.x && y==d.y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public static Direction getDirection(int d){
switch(d){
case NONE:
return new Direction(0,0);
case NORTHEAST:
return new Direction(1,1);
case EAST:
return new Direction(1,0);
case SOUTHEAST:
return new Direction(1,-1);
case SOUTH:
return new Direction(0,-1);
case SOUTHWEST:
return new Direction(-1,-1);
case WEST:
return new Direction(-1,0);
case NORTHWEST:
return new Direction(-1,1);
case NORTH:
return new Direction(0,1);
default:
return null;
}
}
public static string getDirectionString(int d){
switch(d){
case NONE:
return "NONE";
case NORTHEAST:
return "NORTHEAST";
case EAST:
return "EAST";
case SOUTHEAST:
return "SOUTHEAST";
case SOUTH:
return "SOUTH";
case SOUTHWEST:
return "SOUTHWEST";
case WEST:
return "WEST";
case NORTHWEST:
return "NORTHWEST";
case NORTH:
return "NORTH";
default:
//Debug.Log ("undefined direction detected!");
return "ERROR: NOT A VALID DIRECTION";
}
}
public static int invertDirection(int direction){
if(direction==0)
return 0;
else
return (((direction - 1)+4)%8)+1;
}
public Direction invertDirection(){
return new Direction(-x, -y);
}
}
Each Direction contains an x, y pair, but x and y must each be integers in the interval [-1,1]. This guarantees that when applied to a Square, a Direction will specify the change in x and y to reach one of the 8 Squares adjacent to it.
As a quick note, Direction is often specified as an integer that can later be translated into a full Direction when it's time to use it. These integers can be used as a constants, allowing the constant names to be used for I/O which greatly simplifies both writing and debugging. Another great thing about integers is that they can be used for modular arithmetic. This makes it easy to rotate Directions while they're in integer form. Check out the inversion functions. While we can invert a Direction object using this function:
public Direction invertDirection(){
return new Direction(-x, -y);
}
We can also invert it in interval form by rotating it 4 directions ahead like this:
public static int invertDirection(int direction){
if(direction==0)
return 0;
else
return (((direction - 1)+4)%8)+1;
}
We just have to make sure we ignore the 0 direction and subtract one. Going nowhere backwards is still going nowhere.
So we have a locations, and a way to find one location relative to another, but if there isn't an actual spot containing a unit, it's all for naught. So let's talk about the Board itself. The Board doesn't actually contain any Squares. Instead, it contains a 2D array of GridSlots where each position is specified by an x,y pair, stored in a Square. Early prototypes used a 2D array of GameObjects, but this was changed for two reasons. The first is tied to into how orders are resolved, which I'll be going into in greater detail in a future post. Basically, partway through order resolution, multiple units need to occupy the same space, so a GridSlot can hold multiple units until each unit has found it's final position for the round.
The second reason is a bit of Unity specific abstraction. All of the scripting functions on a unit are located inside one or more MonoBehaviours. To access a function on a unit, one needs to first retrieve the behaviour through a GetComponent<ScriptName>() call. Since every call to a unit must go through a GridSlot, GridSlot provides a home for all of these calls. If the functions of a unit are moved from one behaviour to another, only GridSlot will need to be modified.
So now we have a Board containing a a 2D array of GridSlots. The location of each GridSlot is specified by a unique Square, and you can define a path from any Square to any other Square by listing a series of Directions. Now let's see how an attack order works.
Once again, an order consists of a list of Squares being given the order, and a Direction in which to apply the attack. To get the Squares that are attacked, we look up the unit at the GridSlot and ask for its range. Then we check the GridSlot one Direction from the source Square and check if the GridSlot contains a target to attack. If it does, we apply the attack to that Square, otherwise we step one Direction from that Square and check again until we either find a target or have taken range steps. Now we just repeat this for each square listed in the order, and we're done.
And there we have it, a system for managing attacks from a set of locations in the same relative direction regardless of what units are involved. Notice that we only ask units if they exist and what their range is. For now, all attacks are a straight line, but future versions can allow the unit to return any pattern based on the Direction.
Now the Square based design wasn't perfect. Remember how the original design was going to have each player make 3 orders? Well people who've tried the prototype are probably wondering why each player only gets one order in practice. This is because Squares are also used for selection. In each order, the Square containing the unit is used as the source for the next movement or attack. When creating an order, a player is only allowed to select a Square that contains a unit because the unit is responsible for displaying selection. This also avoids the possibility of assigning orders to an empty Square and the apparent ability of the player to select opposing units or obstacles in addition to their own units.
The problem arrises when movement is considered over multiple orders. If a unit is supposed to move to a Square, but gets blocked by an opposing unit, then the subsequent orders for the unit will find a different unit, or no unit at all, in the place they expect to apply an order to, so the unit will be left sitting there with it's orders failing or being applied to the wrong unit.
There are two ways to solve this: either orders must track units, or empty squares need to be selectable. I'm not sure which one I prefer for this game, but since both required a considerable overhaul of either the board or the selection system and the UI, I opted to reduce the orders per turn to one per player and kick this problem down the road. One order each is also a better place for a minimum viable product to start from for future iteration. There was nothing magical about 3 orders each and 2 or 4 might be better choices. Anyway, this is the top priority among changes to be made in future versions, if and when I get around to making them.
So that's the first look into how I designed and implemented Showdown. Keep an eye open for more of these. I have a lot I want to talk about, but first I need to Jam. This weekend is Ludum Dare, and hopefully I can give daily updates on whatever I wind up making there.
See you there!
So, when I started this blog, I intended it to be a dev blog for Stratagem (Showdown from here on out), but having restarted the game repeatedly and never having been sure what would definitely work and what would get thrown away, I never really shared the ins and outs of what I was creating. It's time I fixed that. So here begins a multi part series about of few of the design decisions and implementation details of Showdown. It won't cover everything, just the suff I think is worth taking the time to write about.
But first I want to summarize the design of the game so it's clear what I was trying to build. Firstly, Showdown is a twist on a turn based game. Rather than each player taking their turn on their turn the way titles like Fire Emblem or Advance Wars are played, in Showdown, both players make a single command for a subset of their units while their opponent does the same in a manner similar to an asynchronous strategy game like Diplomacy. However, the commands are still resolved sequentially, first one player, then the other. In the original specs, each turn would consist of 3 commands from each player, so when the moves were resolved, the computer would resolve player 1 move 1, then player 2 move 1, p1m2, p2m2, p1m3, and lastly p2m3. Since the player who's move is resolved first gets the benefit of knowing the exact position and stat of each unit at the time of the first move, the resolution order alternates each round, so in the second round would go p2m1, p1m1, p2m2, etc.
This alternating turn order is also the game's only uncertainty beyond the RNG in map generation. A move carried out in the same situation will always have the same result. The variable is always the other player's decision, which can be very predictable if you know your opponent well, and wildly unpredictable if you do not.
Another important component of the original design was a variety of units. There were six units in the paper prototype, 2 melee types, 2 archer types, and 2 cavalry types. Each command would only apply to a single unit. This approach evolved into one where units with similar properties could be given similar orders, ie two archers could be told to attack the same target. Since all units could move, movement orders could be given to all units simultaneously, but the set of available orders differed depending on the unit type. Archers had 3 different kinds of shooting orders while cavalry had no ready order. This was a major point of confusion and led to most players only using one unit at a time. Now for the sake of having a very minimal starting point and finishing before my deadline, I wound up only using one type of unit in the prototype, but the solution I'm about to explain works regardless of the unit type, so it doesn't really matter that all the units are the same variety of archer. The design still assumed that there would eventually be more units in the future.
To encourage more co-ordinated movement, I toyed with the idea of a formation orders, a set of orders used in place of individual orders whenever 2 or more units were being commanded. A vague order would be given to a whole group of units and each would unit would respond in its own way. At first it looked like even more complexity, but then I realized that the formation orders could be the only orders so that each unit was defined by the way it responded to each of the orders. This simplified the game in two ways. Firstly there was now no difference between the controlling one unit and controlling 100; the same order applies regardless of the number of units. Second, the pool of possible orders could be reduced to just a handful. In the version on my website, there are 4: move, attack, ready, and none.
With this view of units, individual unit types and capabilities are not nearly as important as a unit's location on the board. All actions have to be carried out in terms of location relative to the selected unit. Hence the design decision that this blog is focused on, everything's a Square.
What do I mean by this? Let's look at an attack order. In most turn based games, a player selects one unit and gives it an exact target. Often this can combine moving and attacking so that a unit moves into range of its target then attacks the unit directly. Attacks are an interaction between units, with location on the board as a limiting factor. Now try to imagine controlling 2 units at the same time with the same command. Movement is simple enough, both units follow the same path, assuming they have the same movement capacity. But which unit do they attack? They can only attack the same unit if they we close enough at the start that they will both be in range of the same target at the end of their movement. Both could attack the same tile relative to their final position, but this can easily cause one unit to have no target. As an interaction between units doesn't make sense.
In Showdown, actions are performed on squares. An attack order consists of a set of selected units and a direction. There is no movement to consider because movement is in a separate order. Each of the selected units sends an attack in the same direction from its current location. Since the action isn't targeted or specified in terms of one unit, it feels perfectly normal to affect an empty square. We've changed the semantics for the player from "shoot him" to "shoot that way", and made it much easier to resolve the results of an attack ord. The key is that an action is an operation on board locations rather than the units themselves.
Let's talk implementation. A Square in Showdown is a basically just a wrapper for a co-ordinate pair, specifying a single space on a 2D grid. We have horizontal and vertical co-ordinates, and the methods necessary to copy and compare them them.
public struct Square{
public static Square getNullSquare(){
return new Square(-1,-1);
}
public int x { get; private set; }
public int y { get; private set; }
public Square(int x,int y) : this(){ this.x = x;
this.y = y;}
public override bool Equals(object o)
{
return o is Square ? Equals((Square)o) : false;
}
public bool Equals(Square o)
{
return x == o.x &&
y == o.y;
}
}
The important part on the implementation side is the relationship between Squares. This is contained in the idea of a Direction. A Direction is a like a unit vector, containing the x difference and y difference necessary to move to an adjacent Square. A unit will only move one Square in a cycle, so a distance of several Squares is made one step in a Direction at a time. Let's have a look at Direction:
public class Direction{
public const int NONE=0;
public const int NORTHEAST=1;
public const int EAST=2;
public const int SOUTHEAST=3;
public const int SOUTH=4;
public const int SOUTHWEST=5;
public const int WEST=6;
public const int NORTHWEST=7;
public const int NORTH=8;
private int x;
private int y;
public Direction(int x, int y){
this.x = x;
this.y = y;
}
public bool equals(Direction d){
return x==d.x && y==d.y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public static Direction getDirection(int d){
switch(d){
case NONE:
return new Direction(0,0);
case NORTHEAST:
return new Direction(1,1);
case EAST:
return new Direction(1,0);
case SOUTHEAST:
return new Direction(1,-1);
case SOUTH:
return new Direction(0,-1);
case SOUTHWEST:
return new Direction(-1,-1);
case WEST:
return new Direction(-1,0);
case NORTHWEST:
return new Direction(-1,1);
case NORTH:
return new Direction(0,1);
default:
return null;
}
}
public static string getDirectionString(int d){
switch(d){
case NONE:
return "NONE";
case NORTHEAST:
return "NORTHEAST";
case EAST:
return "EAST";
case SOUTHEAST:
return "SOUTHEAST";
case SOUTH:
return "SOUTH";
case SOUTHWEST:
return "SOUTHWEST";
case WEST:
return "WEST";
case NORTHWEST:
return "NORTHWEST";
case NORTH:
return "NORTH";
default:
//Debug.Log ("undefined direction detected!");
return "ERROR: NOT A VALID DIRECTION";
}
}
public static int invertDirection(int direction){
if(direction==0)
return 0;
else
return (((direction - 1)+4)%8)+1;
}
public Direction invertDirection(){
return new Direction(-x, -y);
}
}
Each Direction contains an x, y pair, but x and y must each be integers in the interval [-1,1]. This guarantees that when applied to a Square, a Direction will specify the change in x and y to reach one of the 8 Squares adjacent to it.
As a quick note, Direction is often specified as an integer that can later be translated into a full Direction when it's time to use it. These integers can be used as a constants, allowing the constant names to be used for I/O which greatly simplifies both writing and debugging. Another great thing about integers is that they can be used for modular arithmetic. This makes it easy to rotate Directions while they're in integer form. Check out the inversion functions. While we can invert a Direction object using this function:
public Direction invertDirection(){
return new Direction(-x, -y);
}
We can also invert it in interval form by rotating it 4 directions ahead like this:
public static int invertDirection(int direction){
if(direction==0)
return 0;
else
return (((direction - 1)+4)%8)+1;
}
We just have to make sure we ignore the 0 direction and subtract one. Going nowhere backwards is still going nowhere.
So we have a locations, and a way to find one location relative to another, but if there isn't an actual spot containing a unit, it's all for naught. So let's talk about the Board itself. The Board doesn't actually contain any Squares. Instead, it contains a 2D array of GridSlots where each position is specified by an x,y pair, stored in a Square. Early prototypes used a 2D array of GameObjects, but this was changed for two reasons. The first is tied to into how orders are resolved, which I'll be going into in greater detail in a future post. Basically, partway through order resolution, multiple units need to occupy the same space, so a GridSlot can hold multiple units until each unit has found it's final position for the round.
The second reason is a bit of Unity specific abstraction. All of the scripting functions on a unit are located inside one or more MonoBehaviours. To access a function on a unit, one needs to first retrieve the behaviour through a GetComponent<ScriptName>() call. Since every call to a unit must go through a GridSlot, GridSlot provides a home for all of these calls. If the functions of a unit are moved from one behaviour to another, only GridSlot will need to be modified.
So now we have a Board containing a a 2D array of GridSlots. The location of each GridSlot is specified by a unique Square, and you can define a path from any Square to any other Square by listing a series of Directions. Now let's see how an attack order works.
Once again, an order consists of a list of Squares being given the order, and a Direction in which to apply the attack. To get the Squares that are attacked, we look up the unit at the GridSlot and ask for its range. Then we check the GridSlot one Direction from the source Square and check if the GridSlot contains a target to attack. If it does, we apply the attack to that Square, otherwise we step one Direction from that Square and check again until we either find a target or have taken range steps. Now we just repeat this for each square listed in the order, and we're done.
And there we have it, a system for managing attacks from a set of locations in the same relative direction regardless of what units are involved. Notice that we only ask units if they exist and what their range is. For now, all attacks are a straight line, but future versions can allow the unit to return any pattern based on the Direction.
Now the Square based design wasn't perfect. Remember how the original design was going to have each player make 3 orders? Well people who've tried the prototype are probably wondering why each player only gets one order in practice. This is because Squares are also used for selection. In each order, the Square containing the unit is used as the source for the next movement or attack. When creating an order, a player is only allowed to select a Square that contains a unit because the unit is responsible for displaying selection. This also avoids the possibility of assigning orders to an empty Square and the apparent ability of the player to select opposing units or obstacles in addition to their own units.
The problem arrises when movement is considered over multiple orders. If a unit is supposed to move to a Square, but gets blocked by an opposing unit, then the subsequent orders for the unit will find a different unit, or no unit at all, in the place they expect to apply an order to, so the unit will be left sitting there with it's orders failing or being applied to the wrong unit.
There are two ways to solve this: either orders must track units, or empty squares need to be selectable. I'm not sure which one I prefer for this game, but since both required a considerable overhaul of either the board or the selection system and the UI, I opted to reduce the orders per turn to one per player and kick this problem down the road. One order each is also a better place for a minimum viable product to start from for future iteration. There was nothing magical about 3 orders each and 2 or 4 might be better choices. Anyway, this is the top priority among changes to be made in future versions, if and when I get around to making them.
So that's the first look into how I designed and implemented Showdown. Keep an eye open for more of these. I have a lot I want to talk about, but first I need to Jam. This weekend is Ludum Dare, and hopefully I can give daily updates on whatever I wind up making there.
See you there!
Saturday, 8 August 2015
Snip Snip!
Oh interwebs!
Did you really think I was going to cheat you out of the big moment?
I would never. Here we go:
BEFORE:
THE BIG MOMENT
AND AFTER
AND JUST FOR REFERENCE
Here's what I looked like around the time I started this blog:
So there it is, 3 years of analysis paralysis, redesigns, reboots, platform changes and painstaking development all in follicle form.
Did you really think I was going to cheat you out of the big moment?
I would never. Here we go:
BEFORE:
THE BIG MOMENT
AND JUST FOR REFERENCE
Here's what I looked like around the time I started this blog:
So there it is, 3 years of analysis paralysis, redesigns, reboots, platform changes and painstaking development all in follicle form.
The Long and Short of it
Greetings interwebs!
Well, we've come to it at last. I got rather shy about updating this blog, so this is probably coming completely out of left field, but it's happening all the same.
Stratagem has been released.
I'll give you a bit of background while I let this sink in. The project I was on with my most recent employer was completed a couple months ago, and my employment with it. My next goal is to get into a larger game company, there are several here in Vancouver, but the problem with larger companies is that they often have strict limits on what developers can work on in their free time while under their employ. So with my hair getting problematically long again, and not wanting to keep it for years, I figured I needed to buckle down and crank out a playable version of Stratagem before I went job hunting.
I also want to move on to working on smaller projects. Stratagem has long proven to be a development quagmire because of the sheer amount of work required to make it testable. I want to switch to faster failing projects, the sort of thin that can be testable after a week and released after a month.
With that in mind, I must confess that I've exploited a couple of loopholes in my initial specs of the game. According to the first post on this blog, the state of the game was not part of the pledge, nor the aesthetics, mode of release, or online multiplayer. Now I didn't abandon the core of the game, but I did scope it down to just a test of the main mechanics. So instead of 6 units, there's only one, a ranged unit since that tests the most annoying cases in the engine. Instead of the original medieval look, it's now a western. Instead of having 3 alternating turns per player per round, there's only one each. There's only hot seat multiplayer and instead of a release on a major platform, it's just a web app appearing on my website. In conclusion:
Stratagem has been released... sort of.
Funny thing is, it's not even called Stratagem. This isn't really a problem since Stratagem was always a working title rather than a final one, and another low budget strategy game was released with a similar title, so I really did need to change it. The new title is Showdown, in keeping with the new western aesthetic. So...
Showdown has been released.
And that's good enough for me right now. A released playable experience is worth a hundred half finished projects, so I'm putting this one in the win column. I hope to come back to it someday and make a vastly superior version, but that will have to wait a while.
As for this blog, well, I don't want to commit to anything yet, but I hope to repurpose it again. Keep your eyes peeled for a 3.0 post. Exactly what the purpose of it will be is kind of dependent on what I'm allowed to do on my own, so I really can't say what that will be.
That's all for now,
I'm Lambwatt, this is day... the last one, and I'm going to find a hairdresser.
Well, we've come to it at last. I got rather shy about updating this blog, so this is probably coming completely out of left field, but it's happening all the same.
Stratagem has been released.
I'll give you a bit of background while I let this sink in. The project I was on with my most recent employer was completed a couple months ago, and my employment with it. My next goal is to get into a larger game company, there are several here in Vancouver, but the problem with larger companies is that they often have strict limits on what developers can work on in their free time while under their employ. So with my hair getting problematically long again, and not wanting to keep it for years, I figured I needed to buckle down and crank out a playable version of Stratagem before I went job hunting.
I also want to move on to working on smaller projects. Stratagem has long proven to be a development quagmire because of the sheer amount of work required to make it testable. I want to switch to faster failing projects, the sort of thin that can be testable after a week and released after a month.
With that in mind, I must confess that I've exploited a couple of loopholes in my initial specs of the game. According to the first post on this blog, the state of the game was not part of the pledge, nor the aesthetics, mode of release, or online multiplayer. Now I didn't abandon the core of the game, but I did scope it down to just a test of the main mechanics. So instead of 6 units, there's only one, a ranged unit since that tests the most annoying cases in the engine. Instead of the original medieval look, it's now a western. Instead of having 3 alternating turns per player per round, there's only one each. There's only hot seat multiplayer and instead of a release on a major platform, it's just a web app appearing on my website. In conclusion:
Stratagem has been released... sort of.
Funny thing is, it's not even called Stratagem. This isn't really a problem since Stratagem was always a working title rather than a final one, and another low budget strategy game was released with a similar title, so I really did need to change it. The new title is Showdown, in keeping with the new western aesthetic. So...
Showdown has been released.
And that's good enough for me right now. A released playable experience is worth a hundred half finished projects, so I'm putting this one in the win column. I hope to come back to it someday and make a vastly superior version, but that will have to wait a while.
As for this blog, well, I don't want to commit to anything yet, but I hope to repurpose it again. Keep your eyes peeled for a 3.0 post. Exactly what the purpose of it will be is kind of dependent on what I'm allowed to do on my own, so I really can't say what that will be.
That's all for now,
I'm Lambwatt, this is day... the last one, and I'm going to find a hairdresser.
Saturday, 21 March 2015
The Game Overthinker: A Retrospective
Greetings interwebs!
I’d like to talk to you today about something my reader(s? Yeah probably not.) may be unfamiliar with: a little web show called The Game Overthinker. The show was created in 2008 by Bob (MovieBob) Chipman, who you may know of as the host of Escape to the Movies and The Big Picture. Basically the show was a platform for MovieBob to act as a video game culture commentator in a format instantly recognizable to long time Big Picture viewers. And it was AWESOME! A solid mix of insight, humour, and a strong personality, the show grew a large enough audience to propel it’s creator to the Escapist, Screw Attack, and beyond.
All of which happened before I was even aware of the show or it’s creator. I was first introduced to MovieBob through Escape to the Movies and didn’t know about the Game Overthinker until Extra Credits plugged the show in an episode titled “Choice and Conflict in Games” in 2010. This was also around the time the show was making it’s first foray into having a framing narrative In which the Overthinker had wacky adventures in-between pontificating about game culture. It accumulated a pretty solid cast of characters over it’s run, all humorously played by Bob, and experimented with some cool special effects, though never really rising above the tech level of “Birdemic”. But that was a huge part of the charm as the show marinated itself in the kind of bonkers creativity, hammy acting, and low tech visuals that dominated video gaming in the 8 and 16 bit era’s.
The story, and the show itself came to an end two days ago in the show’s 100th episode. In anticipation of the last episode, I took some time to re-watch the whole series and thought I’d share my take on it here, since I never seem to post anymore anyway.
The story, and the show itself came to an end two days ago in the show’s 100th episode. In anticipation of the last episode, I took some time to re-watch the whole series and thought I’d share my take on it here, since I never seem to post anymore anyway.
Massive spoilers for the entire series from this point on, so if the show sounds at all interesting to you, please go and check it out at http://gameoverthinker.blogspot.ca/. And if you like it, please consider contributing to Bob’s Patreon here. There’s a follow up series and some other projects in the pipe.
The pre story era:
I’m gonna try and keep this short, since I want to focus more on the story than the cultural criticism, since that would basically take 100 miniature posts, and I don’t have that kind of time. However, there were a couple of things I found upon watching the re-watching episodes 1 to 42, so quick thoughts:
-This goes for the entire series, but it’s particularly noticeable with the older episodes. Since it spans as much time as it does, watching the show can be an interesting experiment media archeology. One can see the last 7 years pass in a few hours through 100 vertical slices. The show’s tendency to address controversies while they were relevant also means that there’s a mention of most of the small dust ups that would eventually coalesce into the HashtagWeShallNotDignifyWithAName.
-Speaking of, and I’m trying to word this very carefully, looking back on the early years, I can see how the people propping up said hashtag today would have felt at home with the early Overthinker. Don’t misunderstand, 2008 MovieBob would be just as pissed off about that shit storm as 2015 MovieBob, but the earlier episodes that mention feminism or racism are generally in a position defending games from it rather than criticizing the game. Of course said defences are given with a lot of nuance and the arguments being refuted are given a clear explanation, unlike an opinion from say, Fox News which would likely be given in straw man format. More importantly, he never argues that the discussion shouldn’t be happening. But I still find it illustrative the growth of it’s author over the better part of a decade, or even just a couple years. Compare “Pr0N,” and “Super Mario and the Sacred Feminine” from 2008 to “I Heart Bayonetta” and a Big Picture episode called “Gender Games” if you want to see what I mean.
-There’s a surprising amount of gratuitous T & A in the opening episodes. Nothing explicit obviously, but still more than you would expect.
-The sped up voice track used a lot in the early episodes bears such a resemblance to the effect that would be used for Ivan the fairy later in the series that it’s hard not to hear the episodes as Ivan and the Overthinker taking turns to speak instead of MovieBob throughout.
The Game Antithinker, and the Quest of the Overthinker:
In December of 2010, in Episode 43 “Double Trouble”, The Game Overthinker changed forever when a seemingly normal episode examining the concept of evil twins was interrupted by the Overthinker revealing that not only was “Wario’s Woods” the last game ever made for the NES, (which is true) but there was a real Wario’s Woods in Minnesota (which, so far as I can tell, is not). A Blair Witch style clip from his brother’s exploration of the forest reveals the Overthinker’s own evil twin, the Antithinker, who proceeds to take over the show and banish the Overthinker to Wario’s Woods.
For the next three episodes, the Antithinker hosts the show and looks at video games, and the Megaman and Zelda franchises in particular, through the skewed lens of a man whose interest in video games consists only of Madden and Call of Duty, with all other games being the products of nerds creating a fantasy world where their lives sucked less. The caricature could get a little grating at times, in part because the gay as an insult thing is still irritating, even when done ironically, and the swipe at hardcore bro gamers was so over the top that it really only worked in small doses. I still enjoyed the character, and I wish we had gotten to see the Antithinker covers Mario episode I’m sure there was a plan for, but even I’ll admit, it could be a little much at times. The latter two Antithinker episodes we did get each contained at least a small moment in which the story humanized the Antithinker a little, and the second one, a nostalgic feeling of regret induced by Ocarina of Time, seemed to weaken the Antithinker.
Following the Zelda episode, the show went back to following the Overthinker, who had apparently felt the Antithinker’s moment of weakness and began a quest to ready himself for the time when the Antithinker would return to the woods to finish him. There was notable moment when straw man, a character from the early series who occasionally showed up to regurgitate a simplified version of an argument to be refuted on the show, voiced the complaints of a large section of the show’s audience that was angry about the new storyline. The Overthinker’s response, when asked to kill the annoying character that everyone hates, is to vaporize straw man on the spot, in an act that wouldn’t have any negative consequences what so ever. Over the next two episodes the Overthinker trains, first alone, then with the bald guy from Rygar, until the arc culminates in the 50th episode special “War of the Thinkers”, a commentary free, all action short in which the Overthinker finally defeats the Antithinker and frees himself from Wario’s Woods.
Of the whole arc, the episode that stands out most to me is “The Zen of Grind”, which established an early prototype for what the new show could be at its best, with the framing story and the episode complementing one another. The Overthinker talks about the origins and impact of level grinding on rpgs and games in general, while he himself is grinding slimes to prep himself for fighting the Antithinker. “War of the Thinkers” is also notable for establishing the look and feel for the special effects from here until the appearance of the green screen tech used in the Robothinker arc. But we’ll get to that later. All in all the Antithinker/Quest arc was a well told, if a little rocky, story with an awesome finale.
The Ninja Saga
With the previous storyline having demonstrated what the show wanted to be, it fell to the ninja storyline to establish the form the show would take from here on out. It starts out slowly by establishing a couple new cast members: Ivan, the Overthinker’s fairy intern straight out of the Ocarina of Time, and Police Commissioner Bunnyface, played by Dylan the rabbit. It also introduces Jack Lieberson, a ninja-American senator seen around the edges of the series, mostly just used to poke fun at the ubiquity of ninjas in the Overthinker universe. The plot picks up when Bunnyface requests the Overthinker’s help in dealing with the strange new plague of video game creatures that have begun appearing around the city. It’s explained that the events of “War of the Thinkers” created a rift between the world of video games and the real world that allowed the creatures to slip through. Meanwhile, a mysterious figure is seen destroying game stores and the Sharkcade, a favourite childhood haunt of the Overthinker. The figure is eventually revealed as the Pyrothinker, a ninja with power over fire, and the Overthinker’s investigation of him introduces his counterpart, the ice ninja Cryothinker. On top of that, the pair turn out two be the sons of straw man, out for revenge against the Overthinker. To defeat them, the Overthinker forges a sword out of the Antithinker’s medallion left over after their battle, and fights both ninjas hand to hand in “Ninjamaggedon”. When killed, each of the ninja’s bodies is found to contain an stone charged with elemental energy, the apparent source of their fire and water powers.
It has a few hiccups at the start, most notably on the first episode “Putting the Cart Before the Cloud”, where the main visual is the Overhinker staring down at the laptop with the script on it. There’s also the issue of the near two minute opening credits with inconsistent music, but by the forth episode, both of those had been ironed out. The third episode, “What we learned in the dark”, introduced an act breaks structure that saw the commentary portions broken up once or twice by the the story segments. It allowed for a clean separation of thoughts in the commentary, and neatly handled the time required for traveling, or building, or defrosting between significant action and plot moments. As discussed before, the structure worked best when the story and commentary complimented each other, which happened a couple times this arc. The Sharckade’s destruction led to discussions of the significance the arcade era to gaming, and the presence of ninjas tied into the dominance of Japanese culture in the medium and its fading influence over the modern industry.
In the special effects department, the frozen effect is my favourite in the series. While the dynamic fire and lighting effects always stood out, frozen people always managed to look like part of they were in the scene while maintaining the artificially coloured look. Ivan likewise usually didn’t look terribly out of place, though, it’s likely because as a light emitter, there’s no expectation for him to have a shadow.
Probably the best idea in the run was to make final showdown with the ninja’s into a mailbag show, where between action clips, the Overthinker would answer viewer questions. This allowed the action scene to jump from cool moment to cool moment without worrying too much connecting fight choreography or consistent scene geography. This would be the format for most of the big battles throughout the rest of the show.
The Retrothinker and the Necrothinker
After finding a VHS tape in the ruins of the Sharkcade, Ivan and the Overthinker discover that a gaming TV host calling himself the Retrothinker froze himself in 1990 building’s basement and was released during its destruction. The Overthinker manages to talk the Retrothinker out of of a suicide attempt, but all progress is lost when the Retrothinker goes to check up on the Sonic franchise. In a moment of grief, a shadowy figure abducts him and grants him the earth stone, with power to raise the dead game characters from his era back to life, turning him into the Necrothinker. The Necrothinker sets his minions loose upon Activision and Zynga, and creates a tower fortress out of the ruins of the Sharkcade. After defending the Activision and Zynga from the zombie hordes, the Overthinker leads a selection quality modern game icons in an assault on the Necrothinker’s tower. After a sword fight with the Necrothinker himself, the Overthinker uses the water and fire stones to seperate the Necrothinker from the earth stone, turning him back into the Retrothinker. He then hides the Retrothinker from the police and assures them that while they won't find a body, the Necrothinker is definitely dead.
This was hands down the best arc of the show. Not only did the episode topics like zombies, preservation of the medium, and retro gaming tie in beautifully with the Retrothinker storyline, but the Necrothinker was the deepest villain in the show. The best villains are have a little bit of the hero in themselves, and the Necrothinker was a reflection of the Overthinker’s own fondness for the golden age. We can sympathize with his sense of loss and his desire to see the characters he loved restored. His whole transformation works as a perversion of what the Overthinker said to talk him our of suicide: that he has to live to share what he remembered with the world. Meanwhile the fight forced the Overthinker to defend aspects of gaming that he wasn’t as attached to and fight a person he really didn’t want to kill. He had to confront his own beliefs about modern gaming and find the good in the games of today.
This arc also revealed the biggest flaw in the show’s new format. The Game Overthinker wanted to be topical, have a well shot, well written story, and have the story and commentary tie into each other whenever possible. But writing and shooting take along time and being topical depends on being able to air at the time rather than several weeks later. This was best shown in “Seeing Red” where a discussion of Dizzy and other retro characters and their prospects for modern revival was replaced by talk about the reaction to some concerns regarding Call of Duty’s complete omission of the Geneva Convention raised by the Red Cross. It was an unfortunate loss of what would have been a nicely themed episode. The solution taken here was the one used throughout the series, namely dropping more thematic tie ins in favour of being topical.
The show made format adjustment to the teaser - commentary - epilogue setup that would be used for most of the remaining episodes. While the change was made official in episode 46 “Beyond Sopa” a number of preceding episodes had already wound up with most of their story at the beginning and end. With the commentary crossing the narrative less often, the theming became less noticeable but also easier to ignore when it didn’t work out, and the move also helped to placate the more vocal members of the audience who didn’t care for the story, allowing them to easily skip it.
But despite the flaws, I still maintain that this was the high water mark the show.
The Robothinker Saga
This arc took the form of an extended parody of the Cell saga from Dragon Ball Z. The Antithinker reapears, but is killed immediately by a pink haired time traveller with a sword called the Omegathinker. The Omagathinker had come from the past to both to prevent the Antithinker from killing the Overthinker, and stop the Robothinker, an air stone powered military drone AI that had been plugged into Xbox live before turning on its creators, from destroying the world. After the Overthinker and Cobalt Core, Senator Lieberson’s hitherto unknown private army, are unable to stop the Robothinker, the Omegathinker begins fighting him in a battle that gets periodically cut to during the next several episodes. The Overthinker stays at home and hosts the show as usual allowing some world building to happen in the background. The key point is the introduction of Mr. Phibb (a.k.a. the Devil), who allows the previously killed Pyrothinker and Cryothinker to return from the dead and freeze the Overthinker before moving to interfere with the Omegathinker/Robothinker battle. The Overthinker is saved by Dr. Beardo, the creator of the Robothinker, who still hopes to stop him. Meanwhile the Retrothinker goes to fight the Robothinker, but finds himself completely outmatched until the Mr. Phibb convinces him to use the Earth stone to change himself into the Necrothinker. The Overthinker and the ninjas arrivee just in time to witness the transformation and battle ensues. The Overthinker and Omegathinker keep the ninjas in check while the Necrothinker and Robothinker duke it out, and Ivan is sent to have Dr. Beardo unveil the Overthinker’s new teleporter use it to save get the good guys out of the fight. Using the teleporter, they move themselves from the battle to their apartment, move the ninjas to the apartment while accidentally fusing them into the Plasmathinker, remove the air stone from the Robothinker, and move the Plasmathinker into prison. Finally they teleport the now power deprived Robothinker to the apartment where the Omegathinker finally kills him.
The first thing to note about this arc is, as you may have guessed from that monster of a paragraph, that this was where the plot started to become much more complicated than the usual "guy wreaks havoc, Overthinker fights back" setup that the previous arcs employed. In the 12 episode context of the series it’s not that difficult to follow, but it definitely lacks the relative cleanliness of the previous arcs. Admittedly some of that is par for the course when you’re doing a Dragon Ball Z parody, but after Phibb resurrects the ninjas, there starts to be too many balls in the air.
The bigger issue is the ending. My feelings on it are kind of mixed. The use of the teleporter is clever and the last moments of the Robothinker still have suitable gravitas, but the introduction of the teleporter isn’t telegraphed at all. I don’t know that it’s quite a deus ex machina, since the teleport continues to be used as a teleporter through the rest of the series and it never does anything unexpected for a teleporter, but… well…
The bigger issue is the ending. My feelings on it are kind of mixed. The use of the teleporter is clever and the last moments of the Robothinker still have suitable gravitas, but the introduction of the teleporter isn’t telegraphed at all. I don’t know that it’s quite a deus ex machina, since the teleport continues to be used as a teleporter through the rest of the series and it never does anything unexpected for a teleporter, but… well…
Consider the Oversword, the weapon the Overthinker makes from the Antithinker’s medallion. Ivan informed us that the ninja’s could only be harmed by anti-metal. The Overthinker then says that he has some and pulls out the medallion. We saw in “War of the Thinkers” that the medallion was all that remained of the Antithinker after the battle, and we saw Overthinker pick it up. Then an entire episode is detected to making the sword. By contrast, there isn’t a single mention of having a teleporter, working on a teleporter, or even to the Overthinker working on a mysterious “Protocol Erricson”. The first mention of the protocol is when the Overthinker tells Ivan to activate it at the beginning of “The Next Crash” and it’s revealed to be a teleporter and used the first time in the epilogue of the same episode. Again, I liked the use of the teleporter once it's established, but it bugs me that it basically gets conjured out of thin air.
Time was another interesting thing in this arc. A few jokes are made pointing out the inconsistencies in the Omegathinker’s knowledge of things that shouldn’t have happened in his reality due to the Robothinker destroying everything before they could happen. The show’s solution was to just ignore the question, but it does expose unique problem with combining the narrative and commentary portions of the show which I think is worth discussing. Obviously the commentary portions of the show take place in unique moment in time at which they were filmed, but the story segments tended to have a more flexible relationship with time. Way back in the Antithinker saga, all the time between episodes was assumed to have passed normally. We saw snapshots of the Overthinker’s exile, but it was assumed that he continued to survive, train and explore the forest off screen between episodes. But if the same view of time were held in the ninja saga, we would have to conclude that the Overthinker’s time as a popsicle, and the accompanying ninja dance party, lasted nearly a month. However, the show never explicitly gives out a date for the story events, which provides a neat way around this inconsistency using a sort of temporal doublethink. Multi episode character interactions can be thought of as events displaced in time so that the events of the previous episode always happened just prior to the events of the current one. In this case of the Omegathinker’s recorded history, everything that happened in our reality also happened in his because he always got here yesterday morning and the Robothinker always showed up last night.
On the technical side, this is when the show introduced the green screen tech that would be used for the rest of the series to handle multiple Bobs being on screen at once (except in the apartment scenes where the lighting could be carefully controlled). While it often surrounded the characters with a fidgety green aura, it made up for that by allowing much greater variety and complexity in the interactions between characters. Ariel fight scenes, characters moving while being shown at a distance or in exotic locations, characters appearing in groups of 5-8 instead of two, all were only achievable with the green screen. The show also settled on the version of the intro it would use for the rest of the series and the long battle over act breaks finally ended in a draw: they’re there when they are, and they’re not when they’re not.
Despite the somewhat anticlimactic ending, the Robothinker arc was still an enjoyable one. As complex as my synopsis made it sound, the changes are spread out over enough time that they’re not overwhelming, and the fact that the game was always changing meant the story never got bogged down. I also really liked the unexpected turn in the parody, with the Overthinker going from the Goku analogue to that of the minor characters hiding and watching the fight on tv. It’s also worth noting that this was the only arc not to handle the big battle with the mailbag show setup, and while that did take away from the ending a bit, it’s impact would have been undermined in this arc simply because the Omegathinker/Robothinker fight was cut to in almost every episode.
The Ultrathinker, the Second Quest, and the End of All Things
Remember when I said the Robothinker arc put too many balls in the air. This was where they became a problem. It’s definitely the most convoluted storyline and is riddled with sudden changes in direction and plot points hastily happening off screen. So for this one, I’m just going to cover it in a point form summary. Here we go!
- The Necrothinker turns back to normal
- The Omegathinker returns to the future
- Senator Lieberson and Commissioner Bunnyface have the Retrothinker arrested for his crimes as the Necrothinker, and place the Overthinker under house arrest
- The Antithinker re-appears, released from hell by Mr. Phibb, and busts the Retrothinker out
- The Plasmathinker turns back into the two ninjas off screen
- Lieberson appears on TV, flanked by the ninjas, introducing himself as the leader of the Oolong Tea Party which is now in control of the government with the help of their new cybernatetic army, the Justice Iron Shadow Militia (J.I.S.M.)
- The Antithinker delivers Retrothinker back to the apartment and explains himself, revealing the mysterious shadowy stranger as the Ultrathinker, and setting him as the puppet master behind all the Overthinkers prior enemies
- He also remembers that the Ultrathinker needed something called Lost Cross to find the ultimate weapon
- The heroes investigate a mountain cave looking for information about the cross and find Dr. Beardo inside
- The J.I.S.M. troopers are revealed to be powered by the video game creatures (now dubbed vidspawn)
- Dr. Beardo finds the Lost Cross… in his car…
- The Ultrathinker teleports the Overthinker into his weird inter dimensional limbo place
- Retrothinker uses the stones and the lost cross to go through the Gamer’s Gate and claim the ultimate weapon: the Golden Axe
- The Ultrathinker reveals that he was a monkey that interacted with the predecessors of video games in the 70’s before being shot into space where cosmic radiation transformed him into a trans-dimensional being
- Lieberson imprisons Bunnyface and unmasks himself to reveal that he was Dr. Beardo all along, and he possesses the Golden Axe’s counter part, the Master Sword
- Omegathinker reappears and joins the team as they fight the J.I.S.M. troopers and the ninjas
- The heroes kill the ninjas
- Retrothinker runs inside to fight Dr. Beardo
- The Robothinker reappears and joins the fight against the heroes
- The Ultrathinker kills the Overthinker and enters the real world
- The lead J.I.S.M. guy kills the Omegathinker in a flashback
- The Antithinker kills the J.I.S.M. leader
- Ivan possesses the Robothinker and uses him weapon to steal the Master Sword from Dr. Beardo, allowing Retrothinker to kill him.
- The Overthinker is raised from the dead into some kind of ascendance where he speaks with a being called The Captain
- The heroes fight the Ultrathinker from the top of a Boston skyscraper
- The Overthinker appears to the heroes and gives the Captain’s power to the Retrothinker allowing him to finally slay the Ultrathinker
And then theres a final resolution scene and the end.
It was no secret that the show was always making up the story as it went along, but this was the only arc that really showed it. The Second Quest is talked up as this big event in the show, but it boils down to only two scenes and the “it was in my car” reveal of the Lost Cross. The show bent over backwards to work every character into the finale, then killed the Omegathinker a flashback so he wouldn’t interfere with the fight with the Ultrathinker. Meanwhile some episodes basically had no story whatsoever, though one of them, “Pink Rising,” made up for it by being narrated by Commissioner Bunnyface. Basically the show alternated between cramming in major reveals and changes to the situation, and marking time till the final fight.
But while the story was kind of a mess, a lot of care was taken to ensure that every plot thread was resolved, however haphazardly, and went somewhere, even if they didn’t really affect the plot at all. Despite the lack of a plan, the series as a whole actually managed to finish with very few real continuity flaws. I think I found two, but they’re both pretty tenuous. Over episodes 95 and 96, Liberson appears with the ninjas and some J.I.S.M. guys at the foot of the Ultrathinker when he had just kidnapped the Overthinker, then at the end of episode 96, Dr. Beardo is in the apartment helping with the quest with no indication that he had left at any point. There was enough time with him simply not in the shot that he might have snuck out, but it’s definitely ambiguous.
The other goes way back to Episode 47, “Farm Team,” which contained the very first tease of the Ultrathinker as his voice was heard monologuing over a control panel playing videos of the Overthinker and Antithinker. The camera zoomed out to show the panel was on some form of spacecraft orbiting the Earth. This seems to show just how early a rough idea of the space monkey back story had been dreamed up, but it ship in orbit contradicts the “trans-dimensional being that evolved in deal space and can only subtly influence the real world” version of the character. Given the time between the two versions though, this one’s easily forgivable.
I guess there’s a small problem with the ninjas still having their powers when they come back from the dead without the stones, but it seems like in this universe, characters who go to gel maintain the state and abilities they had at the moment they died. This also helps explain why the Antithinker had only limited use his alternate form after coming back since he died in human form. At least I think it does.
But enough about the flaws, what worked?
Well the characters for one thing. The Antithinker was much more fleshed out and interesting this time around, and the banter between all the characters in the apartment kept things funny and enjoyable. Most of the time. The only joke that really got tired was the Overthinker, the author insert character, sighing with irritation at the story segment and asking Ivan to just roll the credits, but only because it was used for about five episodes in a row. I also liked the little touches in each character's weapon in the final battle. The Retrothinker goes from his yellow Necrothinker sword to the Golden Axe. Ivan, the OOT fairy wields the OOT Master Sword (via Robothinker of course). And the Antithinker is seen using the Oversword that had been made from his own medallion.
And for all the times it interfered, the show’s topical nature ultimately helped it to tie the finale together. The lead up focused on explaining the HashtagWeShallNotDignifyWithAName, and the topic occurred as a running theme in the mailbag questions during the first two final fight episodes. In the final episode, the Overthinker arrived at his final thesis on the subject.
The show ended with the promise of two new spinoff series: A back to basics Overthinker reboot, and an adventure series with the side characters. I’m anxiously looking forward to both of them. It’s a little ironic that after all the backlash over the framing story, the reboot really will be dropping it. But it isn’t dropping it to be popular. The story is going away because it was finished, and it was well worth the telling.
Thank you Bob.
That reminds me, BOB, IF YOU’RE READING THIS: In re-watching the series, I came across “Who’s Your Daddy Megaman” and “I Heart Bayonetta,” both of witch seemed like the first instances of recurring segments that were never followed up on. If you’re still taking suggestions, I would love to see more episodes like those, doing design and aesthetic breakdowns of a character or stage.
Thank’s again.
And rest in peace Door Guy. You will always be remembered.
Subscribe to:
Posts (Atom)