Developer experiences from the trenches

Developer experiences from the trenches

Start of a new post

Patterns for Multiplayer Game Variety

Mon 28 April 2014 by Michael Labbe
tags code 

Game Rules

So you’ve made a super fun multiplayer game and you want to expand it by adding game modes, tweaks and so forth. Here are some possible do’s and don’ts that allow for rapid expansion and moddability.

The approach of branching your game logic by game modes makes your code unexpandable. Consider:

if ( gamemode == MODE_DEATHMATCH ) {
    DisplayFreeForAllScoreboard();
} else if ( gamemode == MODE_CTF || gamemode == MODE_TEAMDM ) {
    DisplayTeamScoreboard();
}

This works with a finite number of game modes, but it makes modding hard. It also makes expanding the number of game modes difficult. A better approach is to create an abstract game rules base class which is derived for each game mode.

class IGameRules
{
public:
    virtual int GetTeamCount( void ) const = 0;
};

class GameRulesDeathmatch : public IGameRules
{
public:
    int GetTeamCount( void ) const {
        return 1;
    }
};

class GameRulesCTF : public IGameRules
{
public:
    int GetTeamCount( void ) const {
        return 2;
    }
};

Now you can simply write the game logic as:

if ( gamemode.GetTeamCount() == 1 ) {
    DisplayFreeForAllScoreboard();

} else if ( gamemode.GetTeamCount() == 2 ) {
    DisplayTeamScoreboard();
}

This approach lets you easily extend your game code to new game mode variants by simply deriving from the IGameRules hierarchy.

Modifiers

Unreal gets credit for being the first game to use modifiers. Modifiers are tweaks to tuning values — they are not holistic mods. This lets the player apply, for example, low gravity and instagib at the same time, by selecting two different mods. (Thereby ruining my vanilla experience, grr…)

This is pretty simple: apply modifiers from top-to-bottom order. Call out conflicts. Unreal did modifier selection with a complete UI in the late 90s.

Combine the Two

Consider exposing game rules methods as modifier tunable values. For example, if you have a game rule bool IsElimination(), which causes players to not respawn after they die, exposing this as a modifier value will allow a modder to go in and take an existing game mode, say, Team DM, and turn it into an elimination mode. Boom! A modder just recreated a simple Clan Arena mode with a text file and no need to learn a scripting language.

Start of a new post

Good Code Doesn’t Tolerate Bad Data

Mon 07 April 2014 by Michael Labbe
tags code 

When something is not right in your game’s simulation, complaining loudly to the developer-culprit as early as possible roots out issues. Production code that tolerates failure at a data processing level while producing a completely errant play experience saves no time.

If a developer commits errant content and time goes by, the cost of fixing it goes up. The developer may have forgotten the intricacies of their contribution, or worse, be on a different project. The content may need to be regenerated from source files in a manner that is either unclear or is not available to the person who deals with the bug. The symptoms of the bug may be disconnected from the problem. For example, I have seen a non-normative bitrate in an audio file corrupt a stack, becoming a time consuming issue to track down.

When you realize a subtle warning was added to a programmer-facing debug log that stated the issue, but was ignored by the developer who added the file, it is time to look for better solutions.

Throwing assert messages when an invalid programmatic state is hit is a common practice for trapping code logic errors. Extending this diagnostic trip-up to content issues for non-programmers is a useful tool for getting in developers faces at the right moment in time — when the developer is trying out their new content for the first time.

What can a content alert do for you?

  1. Provide validation that content is consistent with the engine’s expectations. For example, if a PNG has a corrupt header, there is nothing wrong with the PNG loader logic. It’s just dealing with questionable data. Sure, it could probably display something if the rest of the file is structured properly, but this is indicative of a bad file and you need to get this up in developer faces before they move on to other challenges.

  2. Test code that runs as soon as possible. If you have a cooking stage that runs over your content, throw your alerts then. If you do not, do it at level load. Validate everything.

  3. A way of passing a diagnostic message on to the content creator as soon as possible. Short circuit the QA/bug tracker loop for content creators (level designers, artists, audio engineers). This saves time by providing the opportunity for a specific diagnostic message that gets to the root of the issue. Bug reports from QA describe the symptom of the issue and usually lack direct diagnostic messages. This is much quicker.

Real-World Content Asserts

Resource r = LoadResource();
if ( r.GetBPP() != 32 )
    ContentFail( "Resource has invalid bitdepth" );

ContentFail is a preprocessor macro which, in developer-friendly builds, accumulates a descriptive list of issues for the content creator.

How to implement ContentFail in C

You know which builds are going to developers and which are going to the end user. Use conditional compilation to optionally throw a message up in front of the user.

#if ENABLE_CONTENT_DIAGNOSTICS
#define ContentFail(msg) (void)(HandleContentFail( __FILE__, __LINE__, msg ) )
#else
#define ContentFail(msg) ((void)0)
#endif


void HandleContentFail(
     const char *file,
     int line,
     const char *failmsg )
{
    /* Append failmsg to diagnostic list here */
}

In this implementation, ENABLE_CONTENT_DIAGNOSTICS is on for all builds going to developers and, presumably, off for ship. You accumulate a list of issues and push them to a dialog box after a level load, treat them as compile warnings in a build process or purposely sound an alarm in the cook process.

One benefit of compiling out the content asserts in release builds is avoiding the fear that you are adding a ton of diagnostic strings to shipping code. Go nuts here — be as descriptive and as helpful as possible.

None of this is particularly fancy, complicated or tricky to implement in any language. It amounts to adopting a philosophy of enforcing correctness as early as possible in the design of your tools.

Edit: thanks to @datgame for pointing out a bug in the example code. It has been fixed!

Start of a new post

The PCG Uniqueness Scale

Wed 25 September 2013 by Michael Labbe
tags design pcg 

Not a PCG screenshot

PCG uniqueness scale. Higher is more interesting.

  1. The asset is a direct copy. If an asset is not perceivably different than the one next to it, it is effectively not unique, and is a direct copy.

  2. The asset is visibly distinguishable from another of the same class but is otherwise not special. If an asset is not the same as the one next to it, it is locally unique. It must be perceivably different than the one next to it, but if there are a hundred variations, none of the variations are special. This is the lowest form of uniqueness: it is not a copy, but variants do not provoke further classification by the user. Perlin noise textures are an example of this. Many people believe that this is the true limit of procedural content uniqueness. Not even close.

  3. The asset violates a sense of classification if placed in another area. If an asset would be illogical to a user to place in another area or seemingly makes sense only in the areas where it is placed, it is divisionally unique. Terrain generators that make use of biomes to generate palm trees in tropical areas are divisionally unique.

  4. The asset is notably unique regardless of, or due to, spatial separation. The asset stands out from its surroundings due to properties which are unique from others in its perceived class. It is parametrically unique. A single tree which is larger than all the rest, burned and charred and on the highest hill is an example of this.

  5. The asset has unique properties which simply enforce an entirely different classification by the end user. This may be in spite of a single set of algorithms generating each property under the hood. It is unique by genus. A watermelon in a basket of apples qualifies as being unique by genus.

  6. The asset cannot exist in the same world as another asset. There is no logical way for two assets to exist in the same world. They are represented in such a different manner that there is no opportunity for them to reasonably coexist.

Start of a new post

What You Need for TV Gaming

Mon 10 September 2012 by Michael Labbe
tags gaming 

Steam is launching Big Picture Mode this week.  I’ve been excited about this since I hooked our gaming PC up to our big TV. I put together a list of products that you’ll need to do this properly. Monoprice is insanely cheap but makes up some of the cost in shipping. It’s worth it.

First, for A/V, use something like this HDMI cable for video.

ATI video cards have built in 5.1 audio, so feed this into your receiver to get full 5.1 audio for your games. It’s really simple and avoids the need for a dedicated audio cable.

I also believe in having a POWERED usb hub at the destination near the TV rather than at the PC. This is great for headphones and hooking up wireless devices without straining them (and depleting batteries). You will be using a wireless keyboard and mouse.

This USB hub is powered and has a ton of ports. I own 3 and can recommend them.

You will also need USB extension cord(s) in order to run the hub to your PC. Depending on the length, you may need a repeater which amplifies the signal. One or two of these ought to do the trick: link

For controllers, the best is the Xbox 360 wireless controller. Here’s an Amazon linkto the Xbox 360 wireless receiver. These just work. Plug it into the USB hub that is near your TV.

For i/o, consider the Logitech Wireless Touch Keyboard K400.

You won’t be playing games with that touchpad, but it does let you navigate without hassle from the couch. Yes, you can do things like use iPhone apps for navigating but they are all useless when your computer goes into the BIOS and you have to drop everything and plug in a usb keyboard. This is the way to go.

As for setup, the PC is in my office with a monitor hooked up via DVI. On Windows 7, use Windows Key-P to bring up projector options to switch between the monitor and the TV. This allows the PC to continue operating as a normal desktop machine while making it easy to switch to running it on the TV.

Because the computer is in the office, there is nothing fancy about ethernet or power running that has to be done. And it’s a hell of a lot quieter than an Xbox because it’s in the other room.

Finally, we put the computer into sleep mode when we’re not using it and set it to wake on keyboard press. With this setup, we can fire it up to watch a show or play music and then it powers down again without having to boot it fresh every time.

Make sure your video card has good performance at 1920x1080, since that’s your TV’s native res. No 720p here — 33% more pixels than an Xbox. We use an ATI 6970 for this and it’s quite good at running most modern games at 60fps with 2xAA.

Grab zap straps from Monoprice so you can neatly tie your USB extension and HDMI cables together after you run them to your receiver.

Enjoy!

« Page 6 / 9 »

rss
We built Frogtoss Labs for creative developers and gamers. We give back to the community by sharing designs, code and tools, while telling the story about ongoing independent game development at Frogtoss.