Game Design

There are 3 entries in this Category.

World of Warcraft

SomeRPGGame

World of Warcraft is probably the MMORPG that brought this type of game into the mainstream, and it’s still live and being played today.

So I thought I’d try it out. Luckily, a friend used to be a veritable WoW-fiend doing high-level raids, so I had a pro guiding me through the beginning, suggesting good races to pick etc.

WoW is great, and of course it’s an institution, but oddly, I found I did not enjoy it enough (compared to Star Trek Online, which I’m more familiar with). Because that is rather weird, I thought I’d try to list the things I like and dislike about WoW, in the hope that it’ll make me more clear about what kinds of games I would like to make.

Mission duration

The thing that initially attracted me to STO was that it had story missions, which felt almost like episodes of a TV series. At least as far as I played, WoW’s missions are a lot shorter. Where in STO I play what feels like half an hour to finish a mission, from accepting it to getting the rewards, WoW favors shorter missions of a few minutes, meaning every time I get a tall un-moveable window containing a wall of text (“lore”) and a button to accept a mission or complete.

Even in STO (where it is at least moveable) I do not like mission windows. They take me out of the story, even though I enjoy the gratification of successfully levelling up. And it just feels hollow to get a big achievement for going from point A to point B.

While STO’s mission accept and completion dialogs are similar, they occur much less often, and one mission consists of several smaller quests in the WoW style. This gives them the opportunity to design the dialog before those missions as a real conversation, not just a monumental text dump. I guess it’s a matter of personal preference, where I fall on the side of conversations.

Beginner Help

Both WoW and STO have little help popups that introduce you to using the in-game UI. But like a lot in STO (which came later, so I’m really not blaming WoW for that), their implementation feels more like it would feel in a real computer program.

You can click all of them to either advance in the directions it gives you (which means it will pop up e.g. your inventory to show you how to equip a weapon), or close a single-popup instruction.

The WoW ones, on the other hand, have no obvious way to dismiss them (I tried all three mouse buttons), and at least in my case have the habit of covering mission rewards (and since the mission window is also immovable, if the mission description doesn’t scroll, there is no way for me to read the rest).

Also, the help in STO is tiered. You create a new character, it shows you every hint exactly once. In WoW, I repeatedly get reminded that I just received a new item and seem to be pretty much forced to equip it right then and there to get rid of the tutorial popups.

Moreover, after each mission, I get a large banner in the middle of the screen, telling me to press M to see the map. Even if I can see where to turn in the mission perfectly fine in the mini-map. Even if this is my 10th mission.

One mistake STO makes with help I don’t want to repeat is that popups contain static text and sometimes only point at fixed locations. So if I move an ability from the default spot in the tray, I just get help pointing at the tray, not the actual ability. Also, any keyboard shortcuts the docs mention indicate the default (they point that out, though) so do not reflect any changes I may have made to key bindings in the settings.

UI performance

I play on a Mac. STO’s Mac port is done using Cider, which means I essentially run a Windows emulator. Also, their UI feels like it is written like the game itself, i.e. it calls back to the server for confirmation a lot.

While this is correct for actual gameplay and mini-games, it means that on a slow or busy connection (whether on my side or theirs) a lot of the UI loses clicks, even for parts that aren’t timing-sensitive like the confirmation panels when ending a mission or moving between sectors.

WoW on the other hand feels different. Buttons just behave like you’d expect them to, and if you click a button it triggers an action (the exception being if you accidentally right-click instead of left-click a button, in which case it highlights but then never does anything — it should just not highlight in the first place on a right click).

Icon design

The symbols in your tray in STO have a clean, “iconic” look, made up of simple glyphs and (after an update this year) following a system that makes it easy to tell apart the various groups of abilities and match up abilities with their icons.

WoW’s icons are less clean, more fancy, as you’d expect from a fantasy game. I think I’d get used to them if I played it some more, but they seem to be at the slightly less self-explanatory level STO’s were a year ago. WoW would benefit from an icon redesign, I think, but that’s a minor nitpick, but a big thing to keep in mind for one’s own game designs. Structure them like STO’s icons, even if I may choose a fancier style for a fantasy game.

Damage feedback

Especially STO spaceships make it kind of hard to detect when your character takes or deals damage. Since WoW mostly deals in living beings, they can provide much more obvious feedback about damage dealt or received, where your character shrinks back or similar to indicate you’re not doing too well. Such cues on the character models are much better than having to keep a health bar or “hull strength” indicator in peripheral vision.

In STO it often happens to me that my ship suddenly blows up because I didn’t pay attention to that bar and the damage model has not quite triggered yet and an enemy hits me with an especially strong shot. I do not enjoy One-shot-and-you’re-dead enemies in my games.

If I wanted to have an instant killer enemy for story reasons, I’d make sure there is a little cut scene before the fight starts where it demonstrates this weapon on an unsuspecting NPC, and also that the weapon has some sort of “I have you in my sights” indicator that gives me a chance to evade it.

Cool-downs

When I fight in WoW, my character is constantly complaining “cannot do that yet”, “I have no target”, “not enough manna”, “this ability isn’t ready yet”. While I like the use of audio for feedback like this, it doesn’t help my immersion that my character constantly talks to me.

This is exacerbated by some misfeatures of the UI, where e.g. it doesn’t auto-target the next enemy, so usually I press buttons to swing the sword and the first press kills the enemy, but I don’t realize it because the animation takes its sweet time to make the character fall over, so I hit again, and hear “I have no target”.

Also, cool-downs and “manna” (or whatever power is used) are displayed separately in the UI. In STO, they’re one thing. If there is not enough power, the button for an ability stays inactive. In WoW, the button becomes active, but the manna bar is empty, and I get “Not enough rage” or whatever.

Now mind you, I’m aware that battle in STO is more real-time, like in shooters (it’s an action-RPG after all) whereas WoW follows the conventions of strategy games, where you click your enemy and then they’re supposed to be fighting it out while you watch. It’s about who you pit against who and what abilities you decide to use, not as much about each individual shot.

So maybe I just need to cool it down. Let the game play that part.

Range of actions

The way I play STO is fairly keyboard-heavy, although you can use the mouse like in WoW, and the tutorial describes e.g. how to fight using the mouse.

So usually my every interaction involves walking up to something until an action menu pops up or an ability becomes available, and then to trigger it.

WoW generally expects you to use the mouse. This leads to a weird dichotomy for me because my character is roughly near the object and I can click it with the mouse (“my hand is able to reach it”) but then my character complains “too far away”. Because I’m not yet in range.

There are indicators, mind you. The mouse cursor is B/W instead of color if you’re too far away, and your character tells you it needs to get closer, but again, it doesn’t help my immersion.

Although games already show lots of HUDs like mini-maps and ability trays and manna bars, I’m not sure if I’d want popups like in STO. I think LucasArts got it right here: When you clicked an item that was too far away, your character would simply walk up to it and then trigger the action.

Polish

WoW is definitely the more polished game. I’ve had one Mac where it would crash on launch, but whenever I got WoW to run on a Mac, it was solid. STO on the other hand, has crashed a lot for me on the Mac.

Also, WoW’s progressive downloading in the background is great. It shows you in the progress bar how much you need to start playing at all, how much they recommend so you don’t have to wait, and how much to have to hit the network the least while playing. And it seems to take only a few megabytes to start playing. The graphic design of the Battle.net client is also quite nice looking.

STO’s launcher OTOH shows you 9 different progress indicators before you can start playing, and even a fresh download from the server still requires an 8GB patch afterwards. And the progress indicator graphics are very eighties and in the Mac port text overflows the progress bar’s boundaries.

They may both be using HTML behind the scenes for all I know, but only STO feels like a web site with CSS bugs, WoW feels native.

Also, WoW’s buttons highlight and track properly and responsively, and feels like one application compared to STO’s three. And STO has glitches when switching levels where the level is drawn, and only then the load screen covers it, so you get a glimpse of every scene before you enter it. Not a very smooth transition.

WoW also has great in-game details, like rats and foxes running around for ambience, or little children coming up to you and asking you whether you really did all those things you did in the previous quest.

STO only has static characters standing in groups or on corners repeating the same phrase with your name filled in, like “It’s great to see you, Admiral” or “The Federation is doing its best to support you all here”. The infrastructure seems to be there, but I guess they can’t afford to script and implement that in most levels … ?

Trolls and griefers

I just had WoW spoiled by ending up in a cave where I was supposed to kill a spider queen that spawned about every 10 seconds. A few higher-level mages were camped out there and killing the spider as soon as it spawned, with a single shot from a distance.

The worst I’ve ever had happen to me in STO was one guy who kept moving his avatar in front of me and making it dance, or someone triggering a bomb next to me (which doesn’t have any effect beyond making a “poof” effect because outside designated PvP areas all players are on the same team). The solution? I switched to another instance, which is randomly assigned to each player, and identical to the one I was in before. It also takes along my mission progress. No onerous “moving my character to another realm”.

STO seems to generally be engineered to avoid conflict between players. Between players, there is not even collision detection. Most quests require you to trigger enemies, so you have the first chance to get them because your enemies can’t know when they’ll pop up and get in before you.

Also, most battle zones not only have more enemies than you could be expected to kill in a short timespan you’d need to troll someone, they also reduce the level of all characters in a certain area. So my Vice Admiral (60) fights on Nimbus III as Level 20, like everyone else, making it just as hard for the troll to kill the objective as for me. Chances are I’ll get a success in.

Realms

I don’t like that you need to explicitly select a Realm and that’s where your character is. Although at least in WoW there actually are several realms. Wildstar warns you to select the right realm, then only has a single one. Also, WoW lets you move a character to another realm.

In Defiance, the servers for Europe and North America are completely distinct, and if you log into the other server, you get a new, empty game. If you sometimes play with European friends and sometimes with US friends like I do, you need to level up two separate characters to be able to do that.

Realms are really a technical limitation that players should not be bothered with. Sure, barriers are needed so game areas aren’t overcrowded, but players should be able to change to another “shard” of the server at will to meet friends. Ideally, everyone who has someone else in their friend list should automatically be moved into the same shard. And most definitely should the user list be shared between all servers, so I can play my character whenever I want, and look up friends even if they’re on another shard.

Mind you, I’m not saying there shouldn’t be areas that are restricted to certain factions, or that everyone should just be able to walk into your home.

Update: Changed my opinion on using STO-style popups when I remembered that LucasArts adventures just had your character walk up to an object if it was too far to interact with. Made this less of a shootout and more focused on WoW with info from more other games strewn in.

Handling keypresses in Cocoa games

WASDKeys

At first blush, Keyboard event handling for games in Cocoa seems easy: You add -acceptsFirstResponder and -becomeFirstResponder overrides to your custom game map view, then override -moveUp:, -moveDown:, -moveLeft: and -moveRight: to handle the arrow keys.

However, if you play a game like that, you’ll notice one big difference to most other games: It only ever accepts one keypress at a time. So if you’re holding down the up arrow key to have your character run forward, then quickly press the right arrow key to sidestep and obstacle, your character will stop in its tracks, as if you had released the up arrow key.

This makes sense for text entry, where you might accidentally still be holding down one character while another finger presses the next, but for a game this is annoying. You want to be able to chord arbitrary key combinations together.

I found a clever solution for game keyboard handling on the CocoaDev Wiki, but it’s a bit old and incomplete, so I thought I’d provide an updated technique:

The solution is to keep track of which key is down yourself. Override -keyDown and -keyUp to keep track of which keys are being held down. I’m using a C++ unordered_set for that, but an Objective-C NSIndexSet would work just as well:

@interface ICGMapView : NSView
{
	std::unordered_set<unichar>	pressedKeys;
}

@end

and in the implementation:

-(void)	keyDown:(NSEvent *)theEvent
{
	NSString	*	pressedKeyString = theEvent.charactersIgnoringModifiers;
	unichar			pressedKey = (pressedKeyString.length > 0) ? [pressedKeyString characterAtIndex: 0] : 0;
	if( pressedKey )
		pressedKeys.insert( pressedKey );
}


-(void)	keyUp:(NSEvent *)theEvent
{
	NSString	*	pressedKeyString = theEvent.charactersIgnoringModifiers;
	unichar			pressedKey = (pressedKeyString.length > 0) ? [pressedKeyString characterAtIndex: 0] : 0;
	if( pressedKey )
	{
		auto foundKey = pressedKeys.find( pressedKey );
		if( foundKey != pressedKeys.end() )
			pressedKeys.erase(foundKey);
	}
}

Of course, you’ll also want to react to modifier keys, and like most games, you will want to treat them not as modifiers in a shortcut, but as regular keys, so people can press Command to fire, or so. That’s basically the same, just that you override -flagsChanged: and that there are no standard character constants for the modifier keys. So let’s just define our own:

// We need key codes under which to save the modifiers in our "keys pressed"
//	table. We must pick characters that are unlikely to be on any real keyboard.
//	So we pick the Unicode glyphs that correspond to the symbols on these keys.
enum
{
	ICGShiftFunctionKey			= 0x21E7,	// -> NSShiftKeyMask
	ICGAlphaShiftFunctionKey	= 0x21EA,	// -> NSAlphaShiftKeyMask
	ICGAlternateFunctionKey		= 0x2325,	// -> NSAlternateKeyMask
	ICGControlFunctionKey		= 0x2303,	// -> NSControlKeyMask
	ICGCommandFunctionKey		= 0x2318	// -> NSCommandKeyMask
};

-(void)	flagsChanged: (NSEvent *)theEvent
{
	if( theEvent.modifierFlags & NSShiftKeyMask )
	{
		pressedKeys.insert( ICGShiftFunctionKey );
	}
	else
	{
		auto foundKey = pressedKeys.find( ICGShiftFunctionKey );
		if( foundKey != pressedKeys.end() )
			pressedKeys.erase(foundKey);
	}

	if( theEvent.modifierFlags & NSAlphaShiftKeyMask )
	{
		pressedKeys.insert( ICGAlphaShiftFunctionKey );
	}
	else
	{
		auto foundKey = pressedKeys.find( ICGAlphaShiftFunctionKey );
		if( foundKey != pressedKeys.end() )
			pressedKeys.erase(foundKey);
	}

	if( theEvent.modifierFlags & NSControlKeyMask )
	{
		pressedKeys.insert( ICGControlFunctionKey );
	}
	else
	{
		auto foundKey = pressedKeys.find( ICGControlFunctionKey );
		if( foundKey != pressedKeys.end() )
			pressedKeys.erase(foundKey);
	}

	if( theEvent.modifierFlags & NSCommandKeyMask )
	{
		pressedKeys.insert( ICGCommandFunctionKey );
	}
	else
	{
		auto foundKey = pressedKeys.find( ICGCommandFunctionKey );
		if( foundKey != pressedKeys.end() )
			pressedKeys.erase(foundKey);
	}

	if( theEvent.modifierFlags & NSAlternateKeyMask )
	{
		pressedKeys.insert( ICGAlternateFunctionKey );
	}
	else
	{
		auto foundKey = pressedKeys.find( ICGAlternateFunctionKey );
		if( foundKey != pressedKeys.end() )
			pressedKeys.erase(foundKey);
	}
}

An alternative would be to just enlarge the numeric type used to store keys in your unordered_set. Instead of two-byte unichar values, you’d just pick uint32_t, and then define the constants as values that are out of range for an actual unichar, like 0xffff1234. If you’re using NSIndexSet, you’re lucky, it uses NSInteger, which is already larger.

Then add an NSTimer to your class that periodically checks whether there are any keys pressed, and if they are, reacts to them:

-(void) dispatchPressedKeys: (NSTimer*)sender
{
	BOOL	shiftKeyDown = pressedKeys.find(ICGShiftFunctionKey) != pressedKeys.end();
	for( unichar pressedKey : pressedKeys )
	{
		switch( pressedKey )
		{
			case 'w':
				[self moveUp: self fast: shiftKeyDown];
				break;
			...
		}
	}
}

Since your timer is polling at an interval here, and you can’t make that interval too fast because it’s the rate at which key repeats will be sent, it is theoretically possible that you would lose keypresses whose duration is shorter than your timer interval. To avoid that, you could store a struct in an array instead of just the keypress in a set. This struct would remember when the key was originally pressed down, and when the last key event was sent out.

That way, when the user begins holding down a key, you’d immediately trigger processing of this key once, and make note of when that happened. From then on, your -dispatchPressedKeys: method would check whether it’s been long enough since the last time it processed that particular key, and would send key repeats for each key that is due. As a bonus, when a key is released, you could also notify yourself of that.

You could even create “key event” objects of some sort to hand into your engine.

I want to make an MMORPG…

A demo session of the eleven chat client

I hear that’s the thing beginning programmers say to game developers. One of those naïve things people want to do who don’t know any better. But while I agree it’s an illusion to think we, as beginners, and a single person, could just write out the next World of Warcraft, I can totally understand why one would want to do it.

The reason why MMORPGs are near-impossible to pull off is the same reason that makes them so interesting: They’re a big honkin’ fun challenge. They combine all the fun tech and its problems. And they’re fun to use and well regarded as well. Think about the challenges:

  • Graphics and animation – often even on low-end machines, often in 3D, with bone meshes, inverse kinematics, several detail levels of models and customizable weapons, avatars etc.
     
  • User interfaces – often completely custom written on top of low-level 3D engines.
     
  • Maths – figuring out how leveling needs to work, how different weapons interact, but also pathfinding, and graph theory for the NPCs’ limited “AI”.
     
  • Social and economic science Managing interaction between players to encourage fun, discourage trolls and griefers, and balance gameplay between beginners and hardcore gamers or at least keep them from interfering with each other’s enjoyment. Often also involving trading systems.
     
  • Networking – Including load-balancing of lots of users, accounting for input lag, streaming level data and video.
     
  • Security – In addition to traditional hackers, you’ve got lots of players and script kiddies who are fans and are just trying to game the system a little for personal benefit.
     
  • Storytelling and content-creation – Non-sequential stories depending on user decisions, and lots of other content overlapping with graphics and animation to keep players coming back, and to bridge the gaps between story missions.
     
  • Databases – Includes storing all user information with good performance under heavy load and with transactional integrity even on sudden disconnects (e.g. so you don’t “pay” for an item and then don’t receive it).

I think the only thing from computing you don’t need to know how to do for an MMORPG is how to build hardware dongles and write their drivers.

And you want to build one?

Well, yes and no. I wouldn’t really want to run an MMORPG. I also already have a job. And I suck at 3D modeling. But a bunch of these problems are intriguing and fun to think about, so I’m tinkering with ideas, writing little test projects that implement this or that part that one would need for such a game. I’ve also been reading a lot of stuff on Stack Exchange’s GameDev sub-section, for example a question on how one calculates the leveling of characters.

So you might just see me blog a little more about game design in the future. Or this may be the first and only post I’ll do about this topic before I lose interest, who knows.

So what have you made so far?

Having played a couple hundred hours of Star Trek Online, I realized that a lot of the program felt like a graphical client talking to an IRC server that had a bot that ran the actual game logic. So the networking layer is what I wanted to start with. I’m not sticking to any IRC specification, but simply started implementing a modular chat server that is kinda similar to IRC, and has chatrooms (which are useful for separating maps and their communications overhead), and of course user accounts with blocking mechanisms.

The advantage of this approach is that, even if I don’t ever make a game that uses this, it may be useful to other people who are looking for some sort of networking layer, be it for chat, or for some other social program. And at the very least it let me practice sockets and is allowing me to learn how to use TLS to encrypt a connection.

Where will it go from there?

Well, the basic idea is to then build the “bot” that actually implements the game. It will live in chat rooms, one for each map (i.e. a city, planet or whatever) and let you connect to one. Once in a chatroom, it will send you all the data you need to get started.

In the case of a graphical game that would be models, level maps etc. as well as pending messages you may have (e.g. “crafting operation completed” or “spell prepared” etc., but also remind you of mission rewards you need to accept or present a mission introduction you haven’t confirmed as read yet). It will also send status about the player, like inventory, cooldowns of abilities you’ve recently used etc. and update you about changes in any of these, and inform you of nearby enemies and allies and what they’re doing (to you?).

You can now send commands to this bot, which include character movements, casting a spell, firing a weapon or whatever.

So, oddly, all of this feels a lot like it can be implemented fairly elegantly and simply as sort of an IRC/e-mail hybrid with read receipts. And this can all be done without needing to have a client, nor any graphics. Heck, you could test this by writing an ASCII client that looks like NetHack.

The game map

The game is streamed, so it might not be the best idea to download the entire map at once. Especially if you want to be able to maybe have large or endless maps, or maps that can be re-used for different purposes. You’d want to be able to only load those parts of maps that the user visits for this mission.

So the obvious approach so far seems to be to just split the map up into tiles that have relative locations to each other and then load the tiles surrounding your player’s location, and when the player moves load additional ones so you never run out. This can be a 2D tiled map to start with, but can easily be expanded into cubes that can also be stacked vertically.

To simplify, I’ll probably have only a 2D coordinate inside each tile. The vertical coordinate for a player or NPC inside its particular tile-cube will then simply be decided by the ground level underneath it. Since we can connect the tiles arbitrarily, stairs would still be possible to make. Just create a tile with the stair model at its end:

StairsOnTileMapExample

The player will seem to walk up the stairs because the ground level rises. If we now connect the left edge of the tile to the tile one level up, the user will easily walk up one level. The only downside of this approach is that a character won’t be able to hide under the stairs.

Another advantage of using such tiles is that they can be used for collision testing. You can just block an entire tile from being stood on.

That wasn’t too hard … ?

Well, this is still missing any item management, interaction, mission objective enforcement, combat or pathfinding mechanisms, so it’s far from a game, but yeah, it’s probably what I will try to implement after the chat server is finished. Or maybe I’ll just — oh look a butterfly.