Good Robot is almost done, and we are on course to finish the remaining tasks in the next couple of weeks. We’ll release the game in the first week of April, which should give us some breathing room for testing and polish.
However, there is another reason we are launching the game two months after we’re done making it – promotion. This is the part where you email every single Game Journalist / YouTube Personality / Twitch Streamer / Person with a Blog in an illegal-substance-fueled-frenzy and hope they play your game and tell others about it.
“Why do you need to promote your game, Arvind?” I hear my friend Manny Straw exclaim, “If your game is any good, surely you can just put it up on Steam and people who see it will tell their friends about it, and then those friends will tell their friends, and soon you’ll sell a million copies! That’s how Minecraft did it!”
Reposted from Shamus’ Good Robot Devblog
My to-do list grows and shrinks as the project rolls on. I’ll have 20 items on my to-do list one week. I’ll get 13 of them done. Then at our next weekly meeting, those 13 are reviewed. Some are marked as done. Some end up back on the list because my solution was too narrow, or didn’t work in all cases, or I misunderstood the problem. Then a few new issues will get piled onto the list.
So after the meeting my to-do list will be back up to 25 or so items and we’ll begin again. So it goes.
But some items have never been touched. They’ve haunted the bottom of the list, never getting done, never getting looked at. The oldest item on my list now is actually a collection of bullet-points that can all roughly be summed up as “performance problems”. To wit: The game runs too slow.
Not on my machine, mind you. It’s fine on my machine. But on craptops (i.e. really old/slow computers) it runs at about half the framerate it should. So what’s going on?
Reposted from Shamus’ Good Robot Devblog
Some other indie developers were nice enough to play the game and send us their feedback. A common theme in the feedback was that things were too chaotic. Or too random. Or unfocused. Or too busy.
Looking at the game, it’s easy to see why, and it’s easy to see how we slipped into this state. We made a system that let you make wildly divergent robots, simply by tweaking a text file. Since creating robots is easy and variety is good, then more robot types = more good, right? Aren’t games always bragging about how many enemy types they have? Isn’t this a selling point? “Fight over 12 different enemy types!” it says on the back of the box.
Only 12, AAA game? Pshaw. We have that many in the first 15 minutes of the game!
It made sense at the time, but when the feedback rolled in it was a forehead-slapping moment for all of us. Of course this will seem like random chaos to someone who hasn’t played the game constantly for 6 months.
It’s like a version of Half-Life 2 where your first fight is against a group of foes with the behaviors of an antlion, a zombie, two soldiers, a metrocop, a strider, and a gunship. It’s not about being “too hard”, really. Even if you lower the hitpoints and damage output on the gunship and the strider to bring them into line with (say) a metrocop, the player still can’t be expected to parse all this chaos. They’re not going to appreciate the differences between the soldier and the zombie when both foes die in the same panicked volley of weapons fire.
(Shamelessly reposted from Shamus’s Good Robot Devblog)
When you’ve got more than one person working on a complex bit of software, you generally need a specification (spec) for new features. The bigger the team, the more you need a spec. The more complex a feature, the more you need a spec.
According to stereotypes, big firms usually lean too hard on specs, to the point where they might spend more time writing the specs than coding the feature:
“The button will be ten pixels from the left margin and will conform to the usability guidelines sheet 201-a. It will be labeled “Join Game” and will – after a confirmation popup as outlined in the interface framework – begin polling the designated server in request for an open slot. If no slot is found, then the fallback behavior […]”
Meanwhile, little indie houses have a slightly less formal approach:
Bruce: Can you add a button that will let players join the game?
Stuff gets done either way, but sometimes indies are a little slapdash and sometimes big firms are a little too bureaucratic. On Good Robot, our spec is usually a sentence or two in the shared Google doc that we use as a universal to-do list.
But this week I ran into something that I realized was too complicated for that. It was one of those features that sounded obvious and simple in the meeting, but then became mysterious when I sat down to write the damn thing. (This is the point of a spec: To reveal the unknowns BEFORE coding begins. This is important in big firms, since once you’ve begun coding you’ve ALREADY been allotted a fixed time budget, which means this is a bad time to begin figuring out what you need to do.)
Reposted from Shamus’ Good Robot Devblog.
Let’s talk about little things that make a big difference.
The game was lacking something. It was just too static. The world didn’t move, didn’t animate, didn’t react. The screenshots looked good, but when you were playing the game it felt like you were flying past a painting or something.
So my first solution is dust particles. Here is a shot of them, zoomed in so everything looks terrible:
The little specks are the thing we’re interested in here. In still frame, they just look like part of the background. But in gameplay they drift around. They get brighter when you hit them with your flashlight beam and they’re obscured by walls.
Like a lot of “field” effects, this one is pretty simple. There are only 400 dust motes in the game. They drift slowly, so the game doesn’t even have to move all 400 every frame. Each one of them moves in a different (but constant) direction. If it drifts off one side of the screen (either because you’re moving, or it is) it simply re-enters from the opposite side. If you could zoom out, you’d see your character has a rectangle of white particles following them around.
Reposted from Shamus’ Good Robot Devblog.
The more I work with a team of people, the more I’m convinced that having open, accessible game data is the path of least resistance. Why make buggy, lame, proprietary in-house tools when you can just stick all the data into text files and let people use their text editor of choice? Why spend time and effort packing simple data into binary files when you can leave it in plain text? As long as the data isn’t binary in nature (text-based 3D models and sound would probably not be a good idea) then open files are a win for everyone: Easier for coders, more comfortable for the artists, and more mod-friendly for enterprising players.
Of course, I’ve always thought this way, but I assumed it was bias from all the years I worked at Activeworlds, which focused on user-generated content, similar to Second Life or Roblox. I often wondered if I’d gravitate towards obscured data if I ever found myself working on a “proper” game.
But no. But if anything, I’m more pro-“open data” than ever.
But what if the users edit their data files to cheat and give themselves a billion hitpoints?
Yeah. Not a concern. Stopping single-player cheating is a lot like stopping pirates: It can’t be done, but if you’re really creative and determined you can waste a lot of time and money trying.
Early in the project, I had a lot of stuff hard-coded. Certain gameplay parameters were set in stone, and you couldn’t change them without changing the source code and patching the game. That’s basically fine for a one-person team. When I’m working alone, it’s just as easy to change a bit of source code as it is to change some text file of game data. But once Pyrodactyl joined, more and more of the game migrated out of code and into text files the artists controlled.
The only downside is…
It takes HOW LONG to launch the game?
The game used to launch in well under two seconds. Over the past few months, that number has been creeping upwards. This week I noticed it topped ten seconds. That seems unreasonable. We’re certainly not processing five times as much data at startup.
If anything, the game should be loading a little faster than before. Originally all of the level geometry drew from a single gargantuan atlas texture, which contained the tilesets for every level in the game. This texture was always read at startup, which probably had some modest time cost. But one of the problems Arvind ran into with Unrest is that some craptops can’t handle textures over 2048×2048. So, we chopped up the scenery textures so it only loads one at a time.
So what’s causing this slowdown?
That’s a Really Good Question.
I’ve always said that Microsoft makes horrible software, except for their software to make software, which is absolute excellence. When I left Activeworlds, I lost access to the corporate license of Professional Edition of Visual Studio and had to switch to the Hippie Freeloader Edition. (Called “Express”. Because nothing speeds your progress like missing features.)
It’s still great, but it was missing a good profiler. Profiling tools analyze the program as it runs, and show you where all the CPU cycles are going. It’s not something you need every day, but when you need it you really need it.
This year – in a mad fit of behavior so un-Microsoft it’s borderline suspicious – they began offering the super-premium version to the public, for free. So I have access to profiling tools again. Let’s see what it says about Good Robot:
I guess I sort of gave it away in the intro, but the result was actually a surprise to me. I would have expected the time to go into loading bulky texture data. (Nope. Nearly instant.) Maybe loading the 70 different audio files that comprise the sound effects for the game? (Nope. Trivial.) Or maybe the bit of code that examines the individual sprites a pixel at a time so that it can do per-pixel hit detection? (Eh. That’s a little heavy, taking around 11% of the startup time. But it’s not the problem.) Launching the engine? (Trivial.) Loading the shaders? (So fast you basically can’t measure it.) Loading the interface? (Not really.)
But no. The long load times were the result of reading text files.
Almost 40% of the startup cost is spent in EnvInit (), which is nothing but text parsing. And it’s not even all the text parsing. There are other text parsers at work elsewhere. They’re doing more in less time, because those other parsers are working on XML!
For those that don’t know: XML files are like text files, except they’re huge and cumbersome and barely readable. My two favorite XML quotes are:
“XML is a classic political compromise: it balances the needs of man and machine by being equally unreadable to both.” – Matthew Might
“XML combines the efficiency of text files with the readability of binary files” – unknown
But I probably shouldn’t be chucking stones at the XML camp while I’m living in the glass house that is my own text parser. XML might be huge and ungainly, but the game is loading it far, far faster than the rest of our game data, which is in a far simpler format. A great deal of time is spent reading the weapons in do_projectile_inventory (). The weapons file is a minuscule 25k, and holds just 48 weapons. It’s ludicrous that it should take 17% of the startup time reading that file. In the time the game spends laboriously reading that file, you could probably read it in from disk and write it back out again a hundred times over.
In an ideal world, there would be a single clog somewhere, one bit of inefficient or malfunctioning code that’s being called hundreds or thousands of times. But this is not an ideal world, and it seems like the problem is smeared all over the place. The problem is that I’m using strings poorly.
Way back in 2010, I had a post about what a pain in the ass it is to have to manually manage the memory of strings of text. You have to do lots of fussy work to allocate memory and make sure you handle it just right. Something that could be done in 2 lines of code in another language might take six or seven to do properly in C. And if you messed up you’d waste memory, slow down your program, or crash. So it was a lot of work for a lot of danger.
But that’s not how today’s hip youngsters do things. No! They have C++, which comes with sexy new ways to handle text.
I’ve been gradually transitioning to the “new” way of doing things over the last few years. (“New” is a really strange term in programming. I might mean “since last week” or “since the mid-90’s”, depending on context.) But there’s a difference between learning to do something and learning to do it well. I haven’t learned – or even bothered to investigate – the common pitfalls of the new system.
As a result, my text parser was doing a ton of needless work. Something like this:
It’s time to compare two strings!
But we don’t care about upper / lowercase. So take the first string and MAKE A COPY OF THE WHOLE THING, then convert the individual characters to lowercase, then take the contents of the copy and overwrite the original.
We also don’t care about whitespace. If we’re comparing “Apple” and “Apple “, they should match, even though the second one has a bunch of spaces after it. So MAKE A COPY OF THE WHOLE STRING.
Now take that copy AND MAKE ANOTHER COPY, and pull the spaces off the end. Now MAKE ANOTHER COPY and pull the spaces off the beginning. Now give the new, cleaned-up version of the string back to the original.
Now do ALL of that to the second string.
THEN compare them.
That doesn’t sound that bad, right? Sloppy, yes. But, copying a few extra bytes a few extra times should be harmless on a modern computer.
Except, when you need to look for thing A in group B. If thing A is a zucchini and I need to look for it in the list of 48 different vegetables, then I need to do that whole block of actions for every veggie until I find a match. As the list grows, the amount of extra copying can quickly get out of hand. The time cost can ramp up quickly, particularly in my implementation where I was frequently searching through lists within lists.
Does This Matter?
Well, not really. Not in the long run. This was something wrong, and it was wrong in an interesting and unexpected way, which is why I wrote about it. A ten-second load screen is not a horrible sin, and there are many games that take much longer to do much less.
But I’m also kind of picky when it comes to loading times, because loading slows down iteration and iteration is important. People love to say that “premature optimization is the root of all evil.”, but I think there’s a really good case for keeping the startup times snappy, particularly as team size grows.
Most of the people working on your game are probably not programmers. They’re artists. They’re making constant changes. Change the color. Add a few hitpoints. Swap out a new wall texture. Drop in a new sound effect. Tweak a particle effect. Replace a 3D model. You can’t make every part of the game editable while the game is running, which means your artists are going to be restarting the game often. In some cases, they might spend a majority of their time sitting and waiting for the game to start.
If you’ve ever tried to photoshop a large image on a crappy computer then you probably know what I’m talking about. It’s frustrating to have to wait a few seconds to see the results of every action. Just a two-second delay can be maddening. A ten second delay is even worse. It’s long enough to break your flow, but not long enough that you can (say) check Twitter or look for cat pictures. It’s a gap of dead time and it can kill creativity. I don’t know how other people respond, but when I have a lot of creative latency like this it really increases the odds that I’ll stop working as soon as it’s “good enough” instead of polishing things until it’s “great”.
(Reposted from Shamus’ Good Robot Devblog)
So the team is back from Europe and the public has played the Pyrodactyl build of Good Robot for the first time. Here are the notes and observations from this ad-hoc playtesting, along with my commentary:
1. Weapons with charge-up need a spinning animation so there is visual feedback that the weapon is doing *something*. Many players need to be told to hold the mouse button down in cases like the minigun.
As I mentioned last time, we’ve added a ton of guns to the game. One of the things that makes a videogame gun interesting is its firing rhythm. Some guns fire the moment you pull the trigger, but then have a long cooldown before you can fire again. (Doom 2 double-barrel shotgun.) Some spew out bullets instantly but have reload intervals that must be accounted for. (Half-Life 2 machine guns.) Some games have a long spin-up time. (The Team Fortress 2 Minigun.)
It’s this spin-up idea that’s a problem right now. Currently, a player using the minigun will have audio as their only cue that the gun is doing anything. They will depress the trigger and hear a long wind-up sound before the gun starts firing. Obviously on the show floor the player was effectively deaf, so it felt like the gun wasn’t doing anything.
But even in a more normal play situation this is clearly bad. Maybe they’ll have the volume turned down. Maybe there will be so much chaos around them that the spin-up sound will get lost. The barrel needs to rotate as the gun spins up, a light needs to come on, and maybe some particle effects.
2. People try to shoot the glowing machines because anything glowing = enemy. If you can shoot machines and they spit out all their robots and then they go dark, that would be great.
We’ve added these robot factory machines to the game that produce robots for you to fight. Each room has a few factories, and a fixed pool of robots in reserve. As the player fights, the factories take robots out of the spawning queue and add them to the gameworld. Right now there’s a population cap. There can only be N robots in play at any given time. Once N robots exist, the factories will stop adding more until the player kills a few. Once the queue is empty, the factory goes dark and it stops spitting out robots. This is a good first draft of the idea, but it’s clear we need to iterate a bit.
I’m not sure if the current population cap could be higher or lower, but what I don’t want is to build a game around fighting 300 robots and then find out it’s not possible to get that running smoothly on our target platform, known colloquially as “old laptops”. It’s much easier to relax the restrictions late in development than it is to lower them, since the latter requires changing huge parts of the game. So we’re keeping population counts low for the time being until we get the gameplay ironed out.
What happens is that people try to attack the machines that are releasing robots. That’s a perfectly valid thing to do, but right now the machines don’t take damage. In fact, your attacks pass right through them. This is unsatisfying and dumb.
There are a lot of ways of handling this. No matter what, machines need to react to player fire. Maybe they should be invincible, but release robots when hit? (Provided we’re not at the population limit.) Maybe after taking X points of damage a machine should shut off? Maybe it should be destroyed entirely, removing the device from the gameworld?
We’re leaning towards giving the player as much power as possible. More interactivity = better. I also like the idea of machines releasing robots as they’re hit. So if you keep shooting a factory, it keeps spitting out robots to attack you. This is a problem that will solve itself. Eventually the crowd will be so big you’ll have to stop shooting the machine and pay attention to the robots.
It will take some playtesting to get a feel for how tough factories should be, how fast they should release robots, and what the population cap should be.
3. There are machines in the first and final room where robots cannot spawn. Machines should only be in rooms where enemies can occur.
Yeah. That’s something I wanted to fix before EGX, but ran out of time. Right now factories will appear in rooms even though there’s no robots to spawn. Silly.
4. Doors need to be signposted better. Many players try to shoot them thinking they are enemies. If the door you shoot opens it would be much better.
It’s really surprising to me that I overlooked this detail, given that this game began as a “2D Descent”. In Descent you could open doors by shooting them. In fact, that was the preferred method of opening doors, since slamming into them face-first felt stupid.
5. We only have 3 door icons, we should include more types of rooms.
Whoever wrote this note wan’t talking about “rooms”. They were talking about “zones”. Let’s talk about nomenclature problems.
Here are the names for some of the things in our game:
A ROOM is a single 24×24 chunk of the gameworld. In the code I actually called these things “pages” for some stupid reason. The internal structure of a room might look complex. There might be side-tunnels, alcoves, cul-de-sacs, tight corridors, or whatever, but they’re all part of the same room. Rooms are arranged linearly. So the first room leads to room 2, which leads to room 3, etc, all the way to the final room. It might seem more complex than this to the player because their camera is zoomed in and they can never see the big picture.
I keep wanting to rename PAGES to ROOMS in the code. But then I talk myself out of it because that’s not a good use of time. But having a system named something dumb is really annoying. Someday my OCD will overcome my pragmatism, but it hasn’t happened yet.
A ZONE is a linear collection of rooms. A zone can have a distinct color scheme. A zone begins with an entry room, and goes through a linear sequence until you reach the final room, where there will usually be several exit doors. Each door leads to a different zone. Maybe one zone has a shop, another zone has an upgrade station, many zones are simply straightforward robot fights, and the last zone is a final boss. There are supposed to be icons on the doors, letting you know what sort of zone it leads to. When the player chooses a door, the screen fades out and they appear in the chosen zone. (You can’t go back.)
A LEVEL is a collection of zones. The player will be allowed to choose what order to visit the zones in by choosing doors. A level uses a common tileset an theme. So one level is a garbage dump, another is caverns, etc.
Picture Spelunky: A zone is a single trip to the exit, while a “level” is like, “the ice level” or “the temple level”.
“Hey Shamus, it seems like it would make sense to swap the names of levels and zones. See, in the games I’ve played…”
Sure, you can argue about this stuff all day. For the record, “zones” were added late in development. Re-naming complex, far-reaching classes in source code is an annoying hassle. SWAPPING names is doubly so. Even once you’re doing juggling all those lines of code, you still have to swap the ingrained names inside your head.
I named these concepts in the code, but since the rest of the team doesn’t read the code they don’t use the same nomenclature I do. Which is understandable. If I’m looking at a 6-sided solid in a Quake level, I’m probably going to call it a “cube” and not a “brush”, which is what Carmack named them in the code. (For some reason.) Sometimes the rest of the team uses the words “level” and “room” interchangeably with “zone”.
It’s confusing to me to have everyone using random words for things, while I’m sure it’s annoying to artists to constantly be corrected when the terms all seem arbitrary (if not counter-intuitive) from their standpoint.
I wonder how larger teams handle this programmer / artist division of nomenclature. It seems like this problem could get pretty big and out of control when you’ve got ten times as many people and a hundred times as many concepts.
Right now we have zones built around:
1) Shops. (Vending machines.)
2) Upgrade stations.
3) Regular mook fights.
4) Boss fights. (Always the last zone.)
We need more variety. Maybe some that are rare, like the Spelunky “undead” level type that randomly pops up once every few games. Maybe some doors should be mysteries so the player doesn’t know what they’re going to get. More variety = more interesting.
6. Spawn points should play a little animation/light sequence and say “checkpoint activated” or something, so players know what they are.
The game is a rogue-like. But you can buy a warranty for your robot so that if you die you respawn at the start of the level. (These warranties can only be purchased at shops, and escalate in price, so you can’t just trivialize death with warranties. This takes the harsh edge off of death, while still requiring you to master the game in order to have a serious chance of reaching the end.)
We need to communicate to the player what’s going on with this respawn machine. We could call the respawn machine “repair station”, but then players will try to interact with it, hoping for repairs.
Essentially, shooting everything should do something because players shoot everything. Everything that does something should react to the player shooting it, hopefully in a manner that shows what it actually does.
7. Basically, EVERYTHING needs to be interactive.
As Arvind said in a meeting, “Our game only has one verb.” The player can only shoot things. So we need to make the game responsive to that. This doesn’t mean everything needs to be destructible. But it does mean that everything needs to react to bullets in some way.
So that’s how things went at EGX. Arvind says people’s reactions were “very positive”. So I think we’re on the right track.
stolen reposted from Shamus’ Good Robot Devblog)
Way back in July, I said the plan was to have the game “feature complete” by September. I think we sort of met that goal. We’ve completed all of the features planned so far, but I think everyone expects to add a few new features between now and the planned February 2016 release. We do have a mild case of Feature Creep, which can probably be managed through medication and therapy.
What we’ve done since July:
- The interface has solidified. Actually, it’s not so much “solidified” as “been entirely replaced with something else, which has then solidified”.
- The gameplay still has a few remaining question marks, but the core rhythm of the game is there.
- The art style has taken shape.
- The story hasn’t exactly been written yet, but we’ve stopped re-inventing the setting every time we have a meeting. We’ve settled on a single idea that everyone seems comfortable with.
Last week I talked about Good Robot going to EGX. As of this writing, I don’t have the feedback from the public on the game. Although by the time I post this the show will be long over.
When Killing Things Gets Boring…
It was almost two years ago that I said the game lacked interesting-ness. When I joined up with Pyrodactyl, the rest of the team agreed: The game needs “something else”. At least one more gameplay layer: A meta-game. Something to collect. A story to drive the action. A skinner-box mechanic. A mystery. Some humor. Something.
The robots kind of all felt the same. Some of them shot faster, some moved faster, and some were larger or smaller or had more hitpoints, but these variations were only enough to keep the player amused for about half an hour. Beyond that it just felt repetitive.
We were planning on adding some humorous story beats. That would help, but it probably wasn’t something to bank on. Yes, Borderlands gets away with this exact thing, but I think that game is the exception rather than the rule, and I wouldn’t want to bet on us being able to bolster lackluster gameplay with gag voiceovers. That sort of hope is the kind of thing that creates situations like The Writer Will Do Something. “Bah. We can make a shit game and then the writer will add a story to make it good. And if people don’t like the game, we can blame the writer.”
After a while we arrived at the idea that the current enemies didn’t have enough variety in their attacks. The weapons system had evolved over time in an ad-hoc way. There were a couple of different, independent weapons systems (lasers and missiles) that each had their own limitations and quirks and which had totally different interfaces. There were lots of options for the designer to worry about, but not a lot of interesting choices to make.
So I tore out the various enemy weapons systems and replaced them with with a new unified system of projectiles. The designer could control number of projectiles, the rate at which they fired, their color, appearance, sound, how much they scattered, and numerous other things. You could make anything from a shotgun to a railgun to a missile launcher.
For the purposes of testing, I changed it so that the player could fire these new weapons, simply because it’s easier to launch the game and push the fire button than it is to launch the game and then fly around for thirty seconds looking for a robot carrying the weapon you’re trying to test.
What we discovered in the process of testing was that this made the game a lot more interesting. These weapons were supposed to be for enemy robots, but the real fun was when we put them in the hands of the player.
This also fits in nicely with something I really enjoy, which is making open-ended systems where other creative people can discover possibilities I’d never considered. You give them lots of options with potentially emergent outcomes, and see what happens. If you’re curious, here is what a weapon definition looks like in the game files:
#First is the name of the projectile, in brackets. This is the name used to assign the weapon to a robot in robots.ini. [GenericGun] #This is the name of the weapon shown to the player. Title=Plasma Repeater #This is the description for the shopping interface. Description=Start a conga line of bouncing chaos. #Type can be bolt or beam. Type=bolt #Slot is either primary, secondary, or "robot". (Robot weapons won't be available for the player. Default is robot.) Slot=primary #Size is the width and length. (Beams only use width.) Size=0.6 0.6 #The color of the projectile. Also the color of any residual particles and explosions. (Three-digit RGB hex.) Color=afc #The name of the sprite from sprite.ini Sprite=projectile5 #The name of the sprite that will be used as a pickup icon. Icon=Gun1 #The name of the sprite that will be the player's hand when this is equipped. Hand=Hand1 #How the hand will move. Values are: Fixed, Aim, Spin. HandAnimate=Spin #If true, the sprite will glow, like lasers. False means opaque, like a robot. Glow=1 #If true, the weapon can hurt the user with splash / reflections. FriendlyFire=0 #The brightness of the comet-tail effect. 1=full. 0=disabled. Tail=0.05 #If true, the projectile will chase the target. (Doesn't work for beams.) Homing=0 #If true, this projectile can be shot down by others. (Good for missiles.) Shootable=0 #The size of the glowing aura around the projectile. 0=no aura. AuraSize=0.4 #The color of the glowing aura. AuraColor=333 #Movement speed, in units per frame. Speed=0.08 #How long it takes for the projectile to reach full speed. Zero will disable acceleration. #THIS NEGATES BOTH GRAVITY AND SPEED SCATTERING. Use wisely. AccelerationTime=100 #The starting speed. ONLY used if AccelerationTime is not zero. StartSpeed=0.01 #How much the player is pushed back when firing. (Also pushes robots, but only cosmetically.). 0.0 = none. 1.0f = very strong. Recoil=0.0 #How much the trajectory is changed by gravity. Warning: Robots can't correct for this. Gravity=0 #Makes the projectile spin as it flies. Degrees per frame, so 1.0 = 60 degrees per second. Spin=20 #If this projectile is a homing projectile, this controls how fast it will turn. Degrees per second. TurnRate=0.5 #If this is greater than zero, then it will explode on impact with this damage radius. ExplosionRadius=0 #This controls the accuracy of the shots. 0.0 = precise. 1.0 = totally random. Scatter=0.05 #This is how fast the weapon can fire. Higher=slower. RefireRate=2 #The sound effect when fired. Sound=laser_med #How much damage is inflicted on impact. Damage=3 #How long the projectile will live. No effect on beams. Lifespan=2000 #How long it takes for the glowing to fade after the projectile expires. (Important for beams.) Fadeout=500 #How often (milliseconds) to emit sparks. CAREFUL! Low values can create insane numbers of FPS-killing particles. 0 to disable. SparkInterval=50 #How long (milliseconds) between pressing the button and the weapon firing. (Applies only to player.) Warmup=0 #How many projectiles do we get out of a single shot? Volley=1 #If true, the weapon must be re-triggered and warmup before firing again. (Applies only to player.) OneShot=0 #How long in milliseconds does it take the weapon to become ready to fire again? (Applies only to player.) Cooldown=0 #When the projectile hits something, it can bounce off and keep going. This is how many bounces are allowed. Bounces=1 #How many little bits of rock particles you get when this projectile hits the wall. Debris=5 #The cost to buy this weapon in the store Cost=2000
This is often how I document features for the artists. I make an example and cover it in comments. I don’t know how AAA studios handle documenting systems between teams or individuals. It seems like making a document or a wiki would be more organized or professional, but this seems like it would be more convenient to use. Also, it makes the documentation available to the players if they decide to go poking around in the data files and trying to mod things.
But nothing fuels feature creep like adding new features. Once we had new guns, we came up with the idea of giving the player the option to change weapons, which led to having robots drop weapons, which led to adding stores where the player could buy weapons.
“It’s Like 2D Borderlands”
This is all well and good, but the focus of the game has been dragged away from “dog-fighting and dodging incoming projectiles” to “acquire better guns”. Arvind is seriously considering adding a system to generate random guns, Borderlands-style. For the last several weeks it’s been like there’s this pervasive gravitational pull towards more Borderlands-ish ideas: The story, the foes, the weapons, the humor. Every time there’s a problem it seems like, “We could try doing things the way Borderlands does it” is the answer.
This is good, inasmuch as it’s more entertaining, but we need to be careful about making extreme changes this late in development and introducing massive new systems that will take months to tune and balance properly.
I have this writing gig, and I’d already given up hope of Good Robot seeing the light of day, so if it turns out to make money at some point that’s a bonus. But other members of the team have the more sensible position that we shouldn’t just keep hammering away at a videogame for free, forever, constantly changing the foundational mechanics, and never nailing anything down long enough to ship a game and get paid.
A lot of indie devs say things like, “If I was a millionaire, I’d make the ultimate version of [game that they love]!” But if this experience has taught me anything it’s that if we didn’t have to worry about money, we’d never ship a game at all. There’s just too many possibilities to explore.