Friday, December 17, 2010

Tiny multiplayer RTS

I made a tiny multiplayer RTS for XNA. You don't get direct control over your units, you only get an abstract kind of strategic choice - a balance between higher-level strategies. In a real RTS, being able to micro your units is critical, but so is knowing the higher-level strategies, and this is a toy model of those higher level strategies. In almost every RTS (with the exception of myth?), you have to maintain a constant balance between defending, attacking, and expanding - and there's an RPS relationship between them. (Turtle beats rush, rush beats expand, expand beats turtle). In this tiny RTS, instead of having direct control over your units, all you get is control over that production balance (choosing to produce more offense, defense, or econ units), and choosing how to time attacks.

Here's a screenshot of some of my attackers (the swords) on their way from my base (upper left) to the enemy base (lower right).


Design: I like the RPS relationship between the three strategies, and how your opponent's strategy is hidden from you - you have to scout out the enemy, since there's a fog of war.

I like the exponential economic growth, I think that nicely captures the quick economic ramp-up you find in RTSs. It doesn't plateau as naturally as in real RTSs, where your growth is quickly limited by various bottlenecks (like having a cap on simultaneous peon units extracting resources, or tying economic growth to expanding over the whole map).

I don't like how scouting is "free" - normally in RTSs you're sacrificing the units to do scouting. I also don't like how geography doesn't really matter - you can't position your attackers and defenders in a way that protects your base, or fighting over one resource instead of another. In an earlier version of the game, I made it so that the attackers couldn't kill econ units until all the attackers and defenders were dead, but that ended up being pretty broken.

Technical details: It's using GFWL for the matchmaking - although I hate it as a gamer, it's is super easy to code with it and XNA. However, unless you're a registered Indie/Community/AppHub developer, you're limited to playing LAN games, which is sucky. I made the game automatically host if no games are available, and automatically connect to any games that are waiting for players - so run a copy of the game on two machines on a LAN and you're set to have the most fun possible! You *may* have to create a new "offline" GFWL profile to make it not search for games on the internet :(

It's a clickonce installer, which is pretty slick (although the installer UI can be a little janky, it's cool that it automatically installs and updates itself with barely any work on my part). The source is available on the codeplex project page, but it's nothing special.

As for networking, it's a lockstep/deterministic simulation that sends user input over the network before it's used in the simulation (in the style of starcraft), so it's really low bandwidth, at the cost of a fixed 250ms latency on your input. It's been forever since I've done any networking code, and I'm glad this was relatively straightforward (with a couple desyncing bugs).

I stole the barycentric-allocation-triangle idea from simant :)

Sunday, October 24, 2010

how to make bechamel sauce the first time

* melt butter in saucepan
* begin panicking
* with one hand on the tippy saucepan and the other hand whisking, use another hand to add flour, milk, bay leaves, allspice, salt and pepper, and another hand to adjust the heat to keep it between getting too hot and drying out, and getting too cold and coagulating
* be suprised it's not a lumpy burned mess, optionally stop panicking
* put on moussaka

Monday, November 30, 2009

hire me!

I'm a game programmer looking for work, in LA and willing to relocate. I'd like to do gameplay, audio or general programming. Here's my resume as a word doc.




I've been working on a little game demo, a roguelike. You can download the installer (run the setup first, it's a ClickOnce installer). Mike Tipul (a coworker) and I started it a year ago, and we collaborated on it then abandoned it until recently, where I dusted it off for release. There's a codeplex project for it, or you can download just the source (no project files, no artwork).



Features:
* Tile based pseudo-ascii rendering
* Visibility/lighting and shadows
* Procedural dungeon and forest generation
* Location-based damage and severed limbs affect gameplay
* Weapons and multiple damage types
* A tiny little mission where you clear out a forest of wolves, then a dungeon of goblins
* Lots of tutorials that walk you through the game (which is about 5 minutes long)

Monday, October 27, 2008

gravitybone

I am so impressed by gravitybone. Clever, funny, artful - and I'm not just saying this because Brendon's in this building. This is the sort of thing I wish our industry (and me specifically :) would produce.

I'll probably think of it every time I hear 'perfidia' (that and Wong Kar-wai) then play it again. It's worth your time (it's short and very friendly) and the hassle of fileplanet's download service.

Saturday, June 28, 2008

C++ is so baroque

Because of stuff like this. What's so crazy is that webpage is all good advice - a page of code to make a type safely cast to bool.

And here I am reading it all.

Saturday, June 7, 2008

natural intervals in programming

Don't read this, it's boring. I sometimes run into bugs dealing with the edges of intervals. Most of these bugs are because some code assumed an interval was inclusive at the top, and some other code assumed it was exclusive.

Most people seem to understand the convention for array sizes (ie a function called int getSum(const int* a_Array, a_Count) wouldn't touch a_Array[a_Count], and a two-parameter version getSum(int* myArray, int start, int count) would touch a_Array[start] but not a_Array[start + count]), but we don't always get it for floats / real numbers.

I think the "natural" way to split intervals is half-open, like [a, b). To include the bottom and exclude the top, and to do it this way for integers and real numbers. All your "is this number in this range" checks should be of the form fMin <= x && x < fMax, and this should be a convention you can use without really thinking about it.

The important part is consistency. If different parts of code assume a different convention, you're boned. There are a few reasons I think the best convention is the interval [min, max). It's the closest to how division and quantization work - an object at 20.0 gets put into bin 2, because 20/10 = 2. Any logic and math is consistent no matter how we're storing the positions (if they were meters in integers, floating point numbers, or 10s of meters in integers, whatever). The reason the interval has to be half-open is so that only one of two adjacent intervals gets the point (this is important for partitioning groups of things).

Most functions that deal with ranges of numbers exclude the top. Random usually returns [0,1), arrays can be accessed from [0, count), this is how quantization works (representing RGB with char values gives you the range [0, 1<<num_bits) for each channel), etc. This is so boring, so don't think about it - just use min <= x < max.

Sunday, April 27, 2008

boogs

This bug:


Looks kind of like this cellular automaton.