Asteroid Outpost Lobby Progress

I am currently working toward a match-making service and lobby system in AO where servers will be able to set some game settings and start a lobby, and then clients will be able to see a list of all the active servers and join one. The match-making part of this is done. I set up a pair of simple PHP pages and hooked those into a database, one to post a server and the other to request the server list. Right now, when you click “Host” in AO, it starts a “Server Beacon” thread that will post and re-post its server information on the web, it expires after 1 minute. The clients are able to download the server list, then request more information from each one (and incidentally also grab a ping), then display that information in a table I designed in XNA. That’s as far as it goes.

Next, I need to alter the existing TCP protocol I am using to put players in a lobby before starting the game. This lobby should display mostly read-only information to the client, but allow the server to change settings? I guess I’ll worry about that when I actually have game settings. For now, all I need is a player list and a “GO NOW” button that will start a count-down timer, initiate the game world, and sync all the clients before starting the game.

Since I’m getting closer to getting multiplayer set up and working from an end-user perspective, I’ve started to do some more thinking about the gameplay modes and what comes next. My initial plan for multiplayer is coop defence. My initial initial plan was 2 players, but I have since thought, why 2? I’m starting to think that 2-4 players feels like a good number, and absolutely nothing in the back end will need to change. The way I’m thinking of doing the AI waves is to provide both a theme and value. The theme would be something like “Lots of motherships” or “cloaking”, where the units in the wave would belong to the “theme” of the wave. On the same note, I don’t want waves to consist of only 1 unit type like a lot of tower defence games do, and I understand why they do it, but I don’t want that feel for this game. A “Value” would be assigned to each wave. I’m thinking that each AI unit will also have a value, the higher, the stronger or harder the unit is to defeat. When the waves are randomly generated, I will keep adding units to a wave until the value of the collection of units exceeds or matches the intended wave value. This will also make it easy to add a multiplier for multiplayer, or change the value for different difficulty levels. This brings up an other point, if there are 2 players in the game, the AI should be at least twice as strong, right? If it’s exactly twice as strong, I think it would be easy. If one player needs help, the other one will pitch in (if able). It will require lots of play testing, but my gut tells me that a 2.1 multiplier might work well. Any thoughts?

Minecraft Intersections

I have been spending a lot of time in Minecraft recently. With the new patch to 1.6.4, a lot of people’s minecart systems are broken because they fixed the “bug” where 2 minecarts that are moving beside each other will accelerate, aka: a booster. Our minecart system wasn’t immune either, we had to do an overhaul of all of 3-way intersections and our cart delivery system (CDS). During the overhaul, we decided that we would not use ANY bugs or glitches that might be fixed in future patches, this included cart stacking. I was curious to see what other people did for CDS’s or 3-way intersections, so I looked on YouTube. I was quite surprised to find that all of the 3-way intersections I could find were single-track, and that at least 90% of the CDSs were stack-based. There were some interesting 4-way intersections that were quite compact, but also quite complicated. This got me thinking that I should make some videos for both: my bi-directional 3-way intersection and my 1.6.4 and beyond compatible Cart Delivery System.

I’ll give a quick description of the CDS because let’s be honest, it could take me a while to make a video. This system, as complicated as it may seem, uses very little redstone logic, and that was one of my objectives. There are N cart-bays in a line, spaced 2 apart (cart, space, space, cart), with each cart sitting on an un-powered “powered rail” and facing parallel to each other. One end of the delivery system is used for both the outgoing and incoming carts. When you request a cart, ALL of the carts get boosted and each cart moves over one bay, then stops on the brake using only stationary tracks and powered rails. The cart that was closest to the entrance/exit will be fed out to the user. The exact same thing happens when a cart is re-loaded except that all the carts move away from the entrance/exit to make room for the new cart at the end. Reloading carts requires that a single piece of track per cart-bay gets switched, otherwise the carts will try to leave. I call this a “Shifting Station” because all of the carts shift either toward or away from the entrance/exit. You’ll also notice that there are no gaps the carts, there will always be a contiguous block of carts from the first bay beside the entrance/exit inward. It looks pretty cool when you watch it too, I’ll have to show you.

EDIT: No video, but I did make a detailed page about this.

TeeVee Release

I was thinking the other day: Why am I holding on to TeeVee? So…

Here it is! This version is fully functional for users that have television episodes stored on their computers, and those episodes have names along the lines of: “MyShow s01e05.avi”, but it will recognize a wide verity of common naming styles. This version of TeeVee is very rough, and can be confusing to new users, please see the new user guide (available once you register). If you have any questions or comments, good or bad, please post them here, or on TeeVee’s page.

Please tell me what you think. I have been working on this project, for myself primarily, on and off for over 4 years now. It is a passion of mine, and I think tools like this are immensely useful when you would like to watch television shows in-order, and only once. I hope you enjoy it as much as I do.

Networking!

After weeks of work, I finally got Asteroid Outpost to work over the network! There are a few bugs to work out, but Mike and I were able to mine the galaxy together, WOO! I was surprised how easy networking was with the right method. I have tried and failed a few times to get networking working before, so I was expecting many issues. This method was quite effortless, I’m using a combination of Reflection and Events, and I would highly recommend this approach to anyone who is designing a networking application and is able to use these tools. Now for an in-depth view at the implementation:

First off, a friend of mine blew my mind with how he handled inter-entity communication. Now that I’ve implemented it, it’s completely obvious: use Events to communicate status changes. Status changes can be things like: moving, health changing, power level changed, dying, etc. Each of these will have an event that fires and tells anyone who’s listening. An example would be in my AI: my AI locks on to a target entity and tries to kill it, duh. If you don’t use events, in every update you’d have to check that your target is still alive. With events, when you first lock-on to the target, you’d listen to the target’s dying event. When the dying event fires, you’d get a chance to respond by picking a new target. Convenient, right?

If you don’t know much about Reflection, either read a little from the link, or here’s a short summary: Reflection allows you to look up information about types, create new types, and invoke arbitrary methods on instances of types at run-time. You can create a type by name, call a method by name, get a list of events that some random object has, and many other useful things.

So secondly, I use reflection to call methods on the remote machine. I send some way to look-up a target object along with the name of the method to execute, then a list of all the parameters the method accepts. On the receiving end, I first look up the target object, typically by entity ID, the networking class, or the game instance. Once I know which object will be receiving the message, I reflectively look up the method I want to call using the method name we received, then invoke this method with the parameters that we also received. Calling a remote method becomes as simple as calling a local method.

Now… for the cool part, how I’ve integrated my event system with this network reflection system. Each of my events uses a different delegate, so each event uses a different set of parameters. In my case, each event has a single argument, and that argument extends from this nifty class:

public class ReflectiveEventArgs : EventArgs
{
    public ReflectiveEventArgs(IReflectionTarget target, String theRemoteMethodName,
                               object[] theRemoteMethodParameters)
    {
        Target = target;
        RemoteMethodName = theRemoteMethodName;
        RemoteMethodParameters = theRemoteMethodParameters;
    }
    public IReflectionTarget Target { get; private set; }
    public string RemoteMethodName { get; private set; }
    public object[] RemoteMethodParameters { get; private set; }
}

So each event contains all the information required to reproduce itself over the network using reflection. This generic class is never used directly, even though it could be, but it is even more powerful when you extend from it like this (class hierarchy simplified slightly):

public class EntityMovedEventArgs : ReflectiveEventArgs {
    public EntityMovedEventArgs(Entity theEntity, Vector2 theNewPosition)
        : base(theEntity, "SetCenter", new object[] { theNewPosition })
    {
        NewPosition = theNewPosition;
    }
    public Vector2 NewPosition { get; private set; }
}

This way, the entity just invokes its moved event like it normally would, but behind the scenes, it has actually encoded a way to travel over the network. The method SetCentre is part of any Entity that will be able to move, and it accepts a single parameter of type Vector2 (theNewPosition).

Now for some real fun. How does the network class know what to listen to? Sure, all entities will be able to move, but not all entities will have a power level or a mineral count or… something specific to your class. Reflection! Every time an entity is added to the game world, the network class is given a chance to listen to events. Some events will only want to travel from the server to the clients (eg. moving), and others will only want to travel from the client to the server (eg. request a building). I have handled this by using custom attributes. I plan to change my current implementation, but right now I have an attribute for every event. Using reflection, I can look up these attributes and tell the difference between server->client events and client->server events. The network class will only listen to the events that it deems appropriate based on whether you are a server or not.

After all of that, the network will be able to catch all events that you would like to send over the network, AND it has all of the information required to tell the receiver what to do when an event gets fired. That’s it! When your entity moves, the entity will fire an event telling anyone interested, the network picks that up, serializes the method call embedded in the event args, sends that across the network, deserializes the method call on the receiving end, then the receiver invokes the method using reflection, in this case, it will invoke SetCentre with the new location! It is nearly trivial to add new events too, simply make a new class that extends ReflectiveEventArgs, make an event that accepts this as a parameter, then invoke the event! Poof, the event has affected everyone on the network.

Before I release a new version on SourceForge, I want to have a human way to connect to network games. Right now, the binary will only connect to the localhost, so you have to change the code to connect to a friend. I have just finished writing a simple, and flexible match-making service in PHP that will service this game, and potentially other games I make in the future or games my friends make. I will be working to integrate this match-making service into Asteroid Outpost right away, and along with this, I will need a list control and a simple lobby system. Should be fun, :D

Asteroid Outpost Progress

I have been working feverishly on Asteroid Outpost in the past weeks. I now have a networking package that uses reflection to call a method on the remote computer(s). I haven’t used it yet because I needed to get some other things in place first, like a menu. Good news, I now have a menu, complete with credits and screen transitions! Now I can finally start experimenting with networking, right? Well… Almost. While making the menu system, I found some pretty bad mouse handling code that needs to change. And then who can forget that Portal 2 is out! I reserve Luigi!

Sprite Maker

I have been designing a sprite maker for my 2D games. The idea is that my sprite maker would produce a sprite map and an XML file describing the sprite map. I would also produce a Sprite class & DLL in C# that would be able to read the XML file and handle all sprite animations for you.

For the purpose of this project, I have defined the following:

  • A Sprite is the collection of Sequences that represent a Game Element
  • A Game Element is a visual element in the game-world
  • A Sequence is a collection of ordered Frames
  • A Frame is a rectangular section of an image

That is to say that menu items, HUDs, buttons, text, loading screens, all of that is not a Sprite because they do not exist in the game-world.

Also, each Sequence has a unique combination of Set, Animation, and Orientation where:

  • A Set represents the set of the sprite to use. This can be used for a second, complete set of Sequences for the sprite. Examples are: (full health, half health, and almost dead) or (sword, vs spear).
  • An Animation represents an action that the sprite is doing. Examples are: Idle, Walking, and Jumping
  • A Orientation represents the direction the sprite is facing. Examples are: (left and right) or (0, 45, 90, 135, 180, 225, 270, and 315 degrees)

Any of the above can be left as “Default” if they aren’t useful for your application. Every frame can be accessed by using a 4-dimensional array like so:

frame[set][animation][orientation][frame#]

Where the frame# indicates the progress through the Sequence. When the Animation changes, the frame counter restarts at 0. When the Set or Orientation changes, the Animation and frame counters do not change, the current animation just continues in the new Set or Orientation. Each Animation indicates which Animation should follow, once completed. For a looping animation, the animation will refer to itself. For a ping-pong animation, there will be a second animation that uses the same set of frames, only in reverse. And for animations continuing on to greater things, they point elsewhere. Whenever an animation completes, either a flag will be set to indicate this, or an event will get fired to allow the game to take any required actions (like start moving after standing up).

In my editor, I am building a few import methods to import from individual files, existing sprite sheets, and even 3D models. I have already built something that will load 2D individual files from Reiner’s Tilesets, but am currently focusing on building the 3D->2D importer. I should have this project on SourceForge before too long.

AO Full Steam Ahead

I have been spending the bulk of my disposable time refactoring Asteroid Outpost (AO). I have implemented a version of the Unreal Engine’s Controller and Pawn classes, except that I have named them Controller and Force respectively, where a Controller controls one or more Forces and all Entities belong to a Force. So the AI will be implemented as a Controller and the HUD is technically a Controller, but due to other limitations, I can’t easily make the HUD be an Controller, so instead, the HUD will have a Controller. All of this refactoring is designed to make multiplayer easier to implement, so be expecting some networking code in the near future.

My friends were trying to convince me to move AO to 3D, but I fended them off because 2D is just easier. No plane normals, no cameras, and less math. For the time being, I am going to continue with 2D and my method of converting 3D models into 2D sprites. That brings me to my next point:

I tried searching the internet for an application that would help me streamline my 3D->2D process. I found a few applications that did this, but either they didn’t run on my machine due to missing DLLs or they were written for Windows 98 and wouldn’t run on a modern machine. There was one that was close: Flash 2D Sprite Renderer. The only thing it did not do was make a sprite with a square grid OR give you an easy-to-access meta-data file that contained where each frame is. Instead, he “cheated a little and added the details of the sprite sheet on to the end of the png file” with no description as to how, and to be honest, I’m not sure I want to write an application to post-process the sprite his application produces. So long story short: I’m going to add a 3D->2D importer to a Sprite Maker I have been working on in silence for quite some time. I will leave the details of the Sprite Maker for an other day.

Winamp Meta Merger and XNA Project Updates

I have finally posted the code to my Winamp Meta Data Merger and instructions on how to use it. The instructions are actually fairly complex, and that’s because it’s a complicated process. I will tidy up the user interface one day, and post an executable to help people move their Winamp ratings and other useful pieces of data forward after a file restructuring.

I have finally gotten around to upgrading a bunch of my XNA related projects on SourceForge to XNA4 and VS2010 (EDIT: now all moved to Bitbucket). I may as well give a quick summary of the projects here:

  • 2D Primitives is our most popular project with 362 downloads to date. It has functions to draw lines, rectangles, circles, and arcs. XNA does not provide these features.
  • 2D XNA HUD is a framework for creating 2D HUDs in XNA. It has event-driven buttons, windows that you can move around and so forth. (EDIT: Abandoned)
  • QuadTree is our implementation of a Quadtree in XNA. It allows for 2D spatial indexing. In other words, it allows for quick area-based look-ups.
  • Asteroid Outpost is the whole reason for the projects above. It’s the start of a tower defence / real-time strategy game that takes place in space.

I also checked out Mercurial like I mentioned I would in a previous post. I have mixed feelings. On one hand, it was very quick and allowed for some interesting scenarios, but on the other, it was complicated and Tortoise Hg lacked the UI polish that Tortoise SVN has. Maybe that’s because I’m using Tortoise SVN wrong to begin with though. In SVN, I usually just add all of the required files to the repository and that’s the end. With Merc, when I did this and went to commit, it wanted to show me all of the files in the directory structure because they were “Unknown”. You could filter those out, but it didn’t remember your selection, so you’d have to do that with every commit. I can see why they might have done that though, if you have all of the ignores set up properly, it would help you to identify when you’ve created a new file but forgot to add it to the repository. I started to go through the ignore file process in Merc, but found it to be tedious. You either needed to know regular expressions (which I do) or know what they mean by “Glob”. I couldn’t be bothered to read the documentation on the matter, so I switched back to SVN. I did come to one conclusion though: as a single developer, you will not need the additional features that Mercurial brings to the table. Cool concept, but even in the small group of people I’m working with at my company where Merc could be useful, it would actually not work because the guys I work with have a tough enough time understanding SVN.

Winamp Media Library Tool and Minecraft

Recently I’ve been a little busy organizing my music library and playing around with minecart intersections and stations in Minecraft.

Organizing my music is a little more of a deal that it would be for a lot of people, not only due to the volume, but because I like to keep the meta-data associated with each track; Meta-data such as song rating and play count. In Winamp, my media player of choice, all of this meta-data is associated to a file location and name, meaning that if you move or rename a file, all of your meta-data is lost. Luckily I wrote a tool to maintain your meta-data about a year ago. I’ve been too afraid to use it because one of the steps is to wipe all of your meta-data before you can re-load it. But my library was getting out of hand, so I finally caved and tried it out. It works great! I will be releasing the application and source code on SourceForge as soon as I get my act together. On a related note, I’m thinking of trying Mercurial instead of SVN for this project after seeing someone use it in action. As much as I love SVN, Mercurial looked really slick.

If you haven’t heard of Minecraft, now is the time to look at it. This one developer has made millions of Euros from a simple, yet creative 3D Java game. It’s a giant sandbox. I am particularly fascinated with minecart systems, probably because one of my favourite games of all time is OpenTTD. Last night, I implemented a T-intersection with a friend. The night before, I implemented a simple outbound train station that doesn’t involve chasing runaway carts. And before all of that, I implemented a 3-bay train station that will feed you a cart on-demand, without using the stacking trick. I hope to put up some videos of all of this shortly.