Categories
Projects

BattleGrid Update

It’s been a while since I’ve posted any updates about my game, and that’s mainly because I’ve been spending a lot of time working on it and things have been changing pretty quickly. There’s about a half-dozen posts I’ve started in the past month about things that have already changed.

Anyway, toward the beginning of this month, I sent links to the game to a few people to start getting feedback. As expected, the feedback has been extremely valuable. The in-game UI has changed to something that works much better, and I’ve started work on help screens based on feedback about what confuses people. I also got the idea to create a map for the sole purpose of testing the frame rate when things are hectic, and this one map has been very useful as I figure things out.

What people don’t know yet (including my few testers) is that the game is running on my iPad now. Granted, it runs terribly, but it runs. I’ve only got about three weeks before PAX, so having it running on the iPad is a huge step toward my goal.

The other big news is that Unity made their Android basic kit free earlier this month, so there’s a good chance BattleGrid ends up on Android tablets at some point. Of course, I need an Android tablet to test with, so the iOS version will still come first, and long before the Android version, since I need to see the iOS version make some money first…

Oh god, I hope it makes some money. Enough to pay off the development tools and licenses, at least.

Categories
Development

There’s always more to learn…

One of the reasons I love programming is that there is always something new to learn – a new language, a new technology, a new technique. The bright side is that it’s always fresh and fun. The downside is that sometimes it makes you feel like an idiot.

I’m going through this “new and exciting” experience with my game. Unity is a fantastic development platform – it’s flexible, it’s easy, and it’s powerful. I’ve been working with it for over 2 years now, so I thought I had figured a good bit out about how to do things. But I’ve been struggling with getting a decent frame rate even though my game is really pretty basic. My game has tiny worlds (minuscule, really), mostly static meshes, low-poly models, etc. However, the frame rate would frequently dip below 30 FPS… Totally unacceptable on my fairly beefy computer.

Now, a lot of my problems are just the result of a misunderstanding about how Unity optimizes some things. Unity uses an “Update” method on objects that need to be updated every frame. I was using this method all over the place to manage things that needed to happen over time – but not necessarily every frame. Well, as it turns out, having that Update method means Unity needs to call that method, which takes time, even if the method doesn’t do anything. So, I went back and stripped out most of my “Update” methods and replaced them with coroutines. And instantly I got a 20-30 FPS increase.

But my frame rate was still sitting in the mid-50s for a simple game. I’ve spent hours tweaking some of my most commonly used code to eke every last drop of performance out of it. I’ve done a pretty good job, and created a lot of code that’s useful for time-slicing and scheduling operations to run over multiple frames. Still not enough, though.

So today I’m doing some thinking and out of nowhere, an idea pops into my head: “What if I try triggers for targeting?” A trigger in Unity is a collider that doesn’t affect physics. So, it can tell when another object enters, moves around within, or leaves its collider. You could use them to trigger an enemy spawn when the player gets close, or fire a trap, or whatever. Stupidly, I had not been using them for targeting. Instead, I was periodically scanning every target within range and finding the best target. With triggers, I can instead handle this as new targets come into range – when a new target comes into range, check to see if it’s “better” than the current target. This has two side effects: it’s doesn’t take as long because you’re only checking a single target, and it happens as soon as the target enters range. This means that turrets will now immediately notice a new target and react to it instead of having to wait for the next target scan.

Luckily, my AI design was pretty good, so making the switch was easy and I got it tested within an hour. My frame rate is now sitting in the 100+ range, though I still want to try it out on a really busy battle. If things work out, I won’t have to go to some of the “drastic” measures I was thinking about (like enforcing a unit limit).

Categories
Development

Game Development

So over the course of developing BattleGrid, I’ve learned a lot about game development – nitty gritty stuff that it’s hard to learn without actually doing any of the work. I find a lot of this fascinating. I develop applications for a living, and while the basics are all the same, the details about how to do certain things are totally different. Case in point:

I don’t care how quick it is, split it up over multiple frames
There are a lot of things that I could do with a single line of code. I’m a bit of a code snob – I love clean, elegant code that’s easy to read, understand, and maintain. (I have a coworker that doesn’t feel the same way. We don’t get along.) In game development, though, you sometimes have to take a single unit of work and split it up over multiple frames. This means doing a bit of extra work to keep track of your progress each frame, so you can continue on the next frame. There are elegant ways to do this (I think I have a decent method), but it will never be as nice as the one-line beauty that I had before.

An example would probably help. Take targeting. Each turret and unit in BattleGrid has a targeting component that picks out the best target on the map. I’ve simply defined “best” as “closest”, so we just need to do a range check to find the closest. When I started, I just did the work, something like:

public void FindTarget()
{
    var target = this.Targeting.FindClosestTarget();
    this.SetTarget(target);
}

This worked great, except when an enemy was destroyed and the 5 turrets targeting it all decided to find new targets. Finding a target for an individual turret was easy and quick enough to do in a single frame, but if too many turrets all tried to find a target at the same time, the game starts to chug. So, I developed a simple queue:

TaskQueue.Enqueue(this.FindTarget);

Without going into any detail about what that means, that just puts the “FindTarget” action onto the task queue. The task queue executes one operation every tick (about 1/60th of a second), so if 5 turrets need targets, they just queue up their “FindTarget” actions, and targets are found over the next 5 ticks. This is fast enough that a player never notices, but slow enough that it doesn’t hurt framerate.

All this talk about targeting loosely relates to my next point:

AI is hard, but rewarding
I’ve never had kids, but I imagine teaching a kid to do something and then seeing them do it gives about the same warm fuzzy feeling that seeing an AI do what you taught it gives me. I’ve done a lot of work on the AI in BattleGrid, and I know there’s still plenty to be done. One of the hardest things to figure out was how to “teach” the AI what to build in given situations. I had a few ideas that were really complex, but ended up with a pretty simple idea – give the AI “effectiveness” values to work with.

This is what players do without thinking too much about it. “Oh, that guy has a blaster turret protecting his base. Missile turrets are longer range and can destroy that turret easily. I’ll build a missile turret.” I stored “effectiveness” values for every structure in the game. For instance, I’ve set it up so blaster turrets are highly effective against all mobile units, and artillery is effective against all stationary structures.

Now, I knew I had set these values and taught the AI how to use them. Even knowing that, the first time I saw an AI build a missile turret just out of range of one of my blaster turrets, I was amazed. That’s something a player would do – build a longer-range turret out of range of the shorter-range turret.

I’m still amazed when I see the AI counter my structures with the same things I would. I build artillery, they build shields and tanks. I build tanks, they build blasters. It’s the standard rock-paper-scissors scenario, but it’s fun to see it in action.

Continuing on AI…

Sometimes the AI needs to cheat
One of the things I noticed while playing is that the AI is much more difficult when it can afford more. When I dropped the price of all the structures (for testing), the AI could more effectively counter anything I did because they had the cash to do it. So, for more difficult AI settings, the AI cheats a bit… They get twice as much income as the player. This gives them significantly more cash, which means they’re not only thinking faster, they’re also building more that the player has to fight through. Fortunately, the AI isn’t particularly devious or clever, so the player can still beat them, but it takes significantly more work, which is exactly what I wanted for more difficult AI.

Balance is hard
I’ve struggled to get everything to feel balanced. The more options you give a player, the more difficult it is to make sure those options are balanced. I want BattleGrid to support multiple styles of play and make them all viable (playing offensively or defensively), but that makes it incredibly difficult to make sure each play style gets a fair shake. I don’t really have a solution here; it just takes a lot of testing and tweaking.

There are many more examples, but this is enough for now. Hopefully over time I’ll start to find elegant ways to solve all these problems; ways that I can carry forward into other projects.

Categories
Projects

BattleGrid – Factories

I’ve been searching for a clever solution to an issue I’ve had with factories since I introduced the “5 active units per factory” limit: how do I show the player how many units are active?

The straightforward solution is to display some sort of bar above the factory, like a 5-segment progress bar that fills up depending on how many units are active. I didn’t really want to do this, though. Mostly because my experiments in getting UI elements to line up with 3D objects have been unsuccessful.

One of my other ideas was some sort of antenna on the factory that sent out little pulses to the units periodically. I liked the idea, but it doesn’t solve the problem – there’s still no indication of how many units are active unless a player waits for the next pulse and counts the pulses. I liked the idea, though, so it’s been sitting in the back of my head a while.

Then today, a neat idea struck me that I thought I’d try out. Enter the new factory:

The new, more compact factory
The new, more compact factory

The new factory is a bit more compact than the old, but for good reason. It needs some room for the new drones that hover around it:

The new factory with a drone hovering around it
The new factory drone, circling the factory

A new drone is spawned for each unit the factory builds, so you can easily see how many units are active by counting the number of drones. And every few seconds, the drones send out one of those “pulses” I mentioned:

A pulse sent from one of the new factory drones, hunting down its tank.
A pulse sent from one of the new factory drones, hunting down its tank.

The pulses seek out the unit the drone is attached to. These pulses look fantastic (a screenshot doesn’t do them justice) and add a little new animation to the game.

The factories are likely to get another change later since I’m not totally satisfied with the new look, and the pulses, while looking pretty cool in-game, are still a little drab, so I’ll have to dress them up a bit.

Categories
Projects

BattleGrid – UI (Continued)

The switch to the “select a cell, then a structure” UI when building structures looks and works great. There’s only one problem: not all my structures fit in a 1×1 cell. Some structures are 2×2, some are 3×3. The new UI still worked for these sizes of structures, but didn’t feel right. For 3×3 structures, the tile you picked is in the center of the structure, which is OK. For 2×2 structures, though, the tile you picked is the upper-right of the 4 tiles. I lack a screenshot, so this will have to do:

New build menu, showing the problem with 2x2 structures
The problem with the new build menu

I liked the new UI too much to switch back, though. It felt right, even if it wasn’t working great yet. So I did some more thinking, added a bunch of code, and a few iterations later I have things working pretty well. The only downside is that building requires one extra tap/click. However, requiring that extra tap works out pretty well.

When you tap a cell, the build menu appears. When you select a structure, the game finds the appropriate position closest to the tile you selected and places the structure there. Then the camera re-centers on the structure. For 1×1 (or 3×3) structures, there’s no change (though I might add a slight zoom-out if you’re too close for 3×3 structures), but for 2×2 structures, the camera will line up on the intersection of the 4 cells:

New build UI for 2x2 structures
Building an outpost.

If the location is valid, the cells with light up green. If not, the invalid cells will light up red:

The new build UI for 2x2 structures when the location is invalid
Invalid outpost placement

If all the cells are green, you can tap the structure, and it will start building. The part that works out well with the switch is that you can select a structure, and if the location is invalid, you can use the standard camera control gestures (swiping and pinching) to pan and zoom the camera. The structure you’re working on will stay centered the whole time, and when you’ve moved to a good position, you can tap it to build it. This is an improvement over the old UI, where you’d tap a structure and you could drag it around, but you lost control of the camera, so the structure had to go somewhere within the camera’s view when you selected the structure.

Categories
Projects

BattleGrid – UI

I’ve struggled with the UI in BattleGrid several times – I can never find something that feels right for the style of the game. Most of the time I just use simple gradient backgrounds because they’re easy and look decent. I was doing some thinking lately, and I came up with an idea for the in-game UI that I think I like.

Here’s the UI that’s been around for a while:

Old In-Game UI
Old In-Game UI

It works, but it takes up more room than I like, there’s an odd gap on the left, and it’s very bland. There’s a lot going on that doesn’t serve much purpose most of the time.

And here’s the new version I’ve been working on:

New In-Game UI
New In-Game UI

A lot of the space that was wasted on UI is gone. Instead, we have a simple pause button which now acts as a pause + config button (the game is paused in the screenshot, so it’s a “play” button), and your cache in the bottom right. The rest of the screen is opened up to enjoy the action and designate priority targets.

The build UI is removed entirely, in favor of a tap-to-place build menu that appears when you tap on a cell in the grid (a few other games have done this, and I like the feel). When you tap (or click) on any cell, the camera will center over that cell and the build menu appears.

New Build Menu UI
New Build Menu UI

Those three buttons lead to other menus with the actual structures in them, and when you click on the structure, it starts building on the selected cell. The same menu appears when selecting an existing structure, but the only button that pops up (for now) is the recycle button (to sell the structure).

There’s a bunch of new UI bugs now (there always are when making a big change like this), and I still need to re-code a few things to make the new build menu work well, but I already like the new UI better. I still want to do away with those gradient backgrounds, though…

Categories
Life

I don’t think my efforts to relate with others are working.

Social interaction isn’t exactly something I’m good at. Lately I’ve been trying to relate to others by saying something like, “oh, I know what that’s like.” It’s supposed to be meant as a “I feel ya, bro”, but I think it’s comes across as more of a “Hey, let’s make this about me.” …Which makes me feel like a douche. Case in point:

Them (a coworker): “How’s it going?”
Me: “Pretty good. How ’bout you?”
Them: “Okay… I’ve got a cold, so I’m feeling pretty exhausted.”
Me: “Oh, I know what that’s like… I had a cold the last week of December.”
Them: “Oh man, that sucks…” <--- The point where I realized I've made a terrible mistake. Them: "I sent an email yesterday saying I couldn't make it in, and..." (there was a bit more idle conversation here) As I walked away, I realized I had never said "Hope you feel better" or anything nice like that... So I'm fairly sure I came off as a douchebag. I'd go back and say something like that, but I'm pretty sure that would just come off as weird, making me a weird douchebag.

Categories
Development

I think I’m a code snob.

I work with a small team of developers – there’s about seven of us in total that do full-time development. Of that group, there’s only a few of us – about three – that I would call “serious” about coding – by which I mean would have heated and/or deep conversations about “good” code. Of those three, two of us typically feel about the same, and the third doesn’t really agree.

If it’s not already obvious by the wording of that last sentence, I’m in the two-person group. The two of us have pretty similar ideas on how to write good code. Here are some of the principles we try to follow:

YAGNI (You Ain’t Gonna Need It)
I heard a variant of this in college that went “Lazy programmers are good programmers”. The idea here is: don’t write code you don’t need. This obviously varies a bit depending on what you’re writing, but in general, just don’t create anything until you need it to exist. We work in a teeny team and all our development is for internal projects. It’s a giant waste of time to try to create a perfect solution that will fit everybody’s needs, especially when you don’t know what those needs are.

Don’t Reinvent the Wheel
If you run into a big, general problem, someone else has probably solved it, and has done a better job than you will. I don’t care how good you are, you’re not going to sit down one day and turn computer science on its head. You’re not going to sit down one afternoon and crank out a better solution than a several-hundred-man-hour open source project. So don’t think you’re right and they’re wrong because they don’t do something the exact way you want. Instead, just benefit from the hundreds of hours of work and expertise that has gone into creating something ahead of you.

We All Write Bad Code
Everyone has written crappy code at some point, so when someone calls you out on it, just accept it and move on. I have a hard time with this one myself, since my instinct is to fiercely defend any assault on my code as if you’re trying to eat my baby. But there have been plenty of times I go back and look at my code and say, “what was I thinking?!”

Be Open Minded
There’s always something new to learn as a developer – it’s why I love my job. There will always be a new technique, a new language, or a new style out there. It’s important not to get set in a particular at of doing things.

Now, it’s time for me to rag on person number 3…

I’ve gotten into arguments about code at work before. It hasn’t happened lately (mainly because I haven’t had to work with that particular person), but it still bugs me. After putting a lot of thought into it, I think I’ve settled on the fact that I’m a bit of a snob when it comes to code. Be warned, I’m about to do a lot of patting myself on the back.

Plenty of people can write code. Writing code to make a computer do things is not hard. It’s a science – there’s a good bit of learning, sure, but once you know the language, you can do all sorts of things.

I think what makes a good programmer is art. There’s a difference between getting the job done and writing good code. Good code is clean, simple, and elegant.

I code in C#. I absolutely love it. It’s a wonderful language, and anyone who thinks otherwise obviously hasn’t spent much time with it. However, a lot of the greatness behind C# is in the work Microsoft has done on the .NET framework to add tons of code to make my life easier.

LINQ
I think LINQ is God’s gift to programmers. It’s simple, it’s clean, it’s powerful, and it’s easy to understand. I do a lot of data analysis-style work. That means taking a bunch of data and processing it to get more data. Let’s take a simple example of calculating the average for a set of data points.

[csharp title=”Old-School”]
float total = 0;
foreach(float value in data)
{
total += value;
}
float average = total / data.Count;
[/csharp]
Now, that’s not complicated. Any programmer can read and understand that. It’s not technically wrong. However, I’d argue it’s not good, especially when you have this alternative:

[csharp title=”LINQ”]
data.Average();
[/csharp]
I’m fairly certain someone who is not a programmer can understand that. Why wouldn’t you use that if you had it at your disposal?

Now, that’s actually a LINQ extension method. I prefer the extension methods to actual LINQ syntax, but they’re both great. Actual LINQ syntax is a lot like SQL:
[csharp]
var points = from x in xValues
from y in yValues
select new Point(x, y);
[/csharp]

It’d be easy to wrap your “average” code in a simple static method in a utility class and use it wherever you wanted. The power in LINQ comes from being able to chain things together. For example:
[csharp]
var moreData = points.Where(p => p.y > 20).Select(p => p.x).Average();
[/csharp]

OK, we’ve gone back into programmer-only town. But if you know LINQ (or maybe just C#), you can see that means you’re taking the points where y is greater than 20, selecting their x values, and averaging them. Even without knowing what it all means, you can start to get an idea of what’s going on – you’ve got points, and where something is true, you’re selecting something, then averaging it. It’s a natural way to think about the data.

Extension Methods
C# has a feature called “extension methods”. As the name implies, these are methods that extend another object. These are extremely handy when you don’t control the object in question. For instance, say you want to add some functionality to an object created by Microsoft. With an extension method, you can add that functionality.

You could always write the method as a static method on a utility class:
[csharp]
Utility.DoSomething(myObject);
[/csharp]

This is fine, and gets the job done. But with a very minor change to the “DoSomething” method, you can also use it like so:
[csharp]
myObject.DoSomething();
[/csharp]

Of course, this may not always be appropriate, but I find it often produces more readable code. The other benefit is with IntelliSense, where once you’ve typed myObject., a list of what you can do appears.

I’ve heard it said you should use extension methods sparingly, and that’s absolutely true. Some things just don’t make sense as extension methods. However, I’ve found they often make my code look better and read better, and if you’re using LINQ, they can fit in with the LINQ methods beautifully.

Categories
Projects

BattleGrid Details – Gameplay Concepts

As promised, I’m back with more details about BattleGrid. This post describes some of the key concepts behind the gameplay in the game.

Control Areas
This is the basic concept behind BattleGrid and one of the more unique concepts in the game. (I’m sure it’s been done before, but I haven’t seen many games with it.) Each player has a certain area that they control. This area is colored with their player color and it is only within this area that a player can build. Control is spread by outposts, which claim grid cells within a short range around them.

Top-down view of a game in progress, showing the control areas of each player
Top-down view of a game in progress, showing the control areas of each player

If two players both have outposts that claim a cell, that cell becomes “contested”. Contested cells can’t be built on by either player. This makes quick expansion using outposts an effective way to limit another player’s expansion. Any structures built on a cell before it becomes contested remain active.

Contested area between red, blue, and orange players
The grayish area between the orange, red, and blue outposts is contested

If a player loses control of a cell containing one of their structures, that structure becomes neutralized. Neutralized structures don’t function, and can be claimed by the first player to control the cells the structure is built on. Structures in contested areas are particularly vulnerable, since the last player to keep control over the area claims all structures within it.

A neutralized blaster turret
A neutralized blaster turret

Bitstreams
Bitstreams are the resource points in BattleGrid. Controlling these is vital because they provide a constant stream of bits for building new structures.To harvest bits from a bitstream, you have to build an Extractor on them.

A bitstream
A bitstream

Priority Targets
This is a big part of the “no micromanagement” in BattleGrid. Instead of commanding individual turrets or units, the player simply picks out certain targets to prioritize. Any turret or unit that can fire on a prioritized target will do so. Mobile units will immediately change course to get in firing range of any prioritized targets. If no targets are prioritized, units will attack whatever enemy is closest.

A prioritized target
A prioritized target

Factories and Units
Factories build units. Each factory can support 5 units, and will automatically build new units as slots are available. Units are entirely autonomous – the player can’t control them directly. Instead, the units will attack anything designated by the player as a priority target, or will spread out and attack nearby enemies if no targets are prioritized.

A tank factory (building a tank)
A tank factory (building a tank)

The constant flow of units from factories make them a valuable structure, but the factory itself is relatively weak and must be protected. Units are weaker than turrets, but make up for it in numbers. If the factory is destroyed, however, every unit it supports will immediately be destroyed.

A tank fighting a missile turret
A tank fighting a missile turret

In the course of taking these pictures, I have decided that I really need to tone down the pink player color…

Categories
Projects

BattleGrid Details – Structures and Units

BattleGrid structures are divided into three categories: base structures, turrets, and factories.

Base Structures
These are the basic structures that form the backbone of your base.
Outposts expand your cache and control, so they’re necessary to expand your cache so you can build the more expensive factories and artillery.
Extractors harvest resources.
Shields act as a defensive structure, projecting a large shield dome that protects anything within it. Shields are very tough and recharge, but can drop quickly under sustained, concentrated fire.

Turrets
Turrets are your primary defensive structure, though they’re equally effective when used offensively.
Blaster Turrets are cheap, short range, and rapid firing – they act as the best deterrent to units from factories, but are also effective against any other turrets in their range.
Missile Turrets are more expensive, but have a greater range and 100% accuracy, thanks to their tracking missiles. These will usually form your main defense early in the game, since their longer range makes them effective against most units.
Artillery Turrets are the best offensive structure in the game. They’re slow firing and inaccurate, but they deal splash damage and have extremely long range. They’re relatively weak, though, so they need to be protected by other turrets.

Factories
Factories produce your mobile units. These units will move to attack any priority targets, or will spread out and attack whatever is closest to them. Factories come in three flavors:
Tank Factories produce tanks. Tanks are slow but strong, and are able to take a bit of punishment before dying.
Recon Factories produce recon tanks. Recon tanks are the opposite of tanks – they’re quick but weak. They make effective anti-artillery units since they’re able to quickly get within the artillery’s minimum range and fire away at it.
Laser Factories produce laser tanks. Laser tanks are fairly weak, but have a steady laser beam weapon that will always hit and slowly eats away at enemies. This makes them perfect against other units and the weaker turrets.