csanyk.com

video games, programming, the internet, and stuff

Category: Game Design

Pixel Art Chess Set: Communicating function through design

My five year old nephew started learning to play Chess recently, as I discovered on a visit a few weeks ago.  We played two games, and I didn’t have too much trouble beating him, but for a five year old he’s not bad. He knows all the pieces and their basic moves and their relative value.

I thought it would be fun to build a video Chess game that he could use to help learn strategy and how to see the board. So this is my latest project. I’ll be posting more about that as I work on it.

My first step was to design graphic resources. I didn’t want to spend too much time on it, just a basic “programmer art” chess set, that I could use to build the program with. Of course, it didn’t end up that way, and I’ve gone down the rabbit hole designing variations on sets of minimalist pixel art chess men. It’s too fun and fascinating not to.

My first attempt was actually rather good, I thought. I went for 16x16px representations of the classic chess pieces. I drew them very quickly, but was very pleased with my results, particularly the Knight.

I could have stopped right there, but it was so fun to make this set that I wanted to continue exploring and see if I could refine my pixeling technique further.

I decided to search the net for images of chess pieces to see what variety there was, and found a lot of examples of beautiful sets. I started to take notes and to infer design rules for chess men:

  1. Chess pieces are called “chess men” which seems antiquated and sexist, especially given that the most powerful piece in the game is the Queen.
  2. The modern standard chessmen are a design named for English chess master Howard Staunton, and have been in use only since the mid-19th century. A strength of its design is that each piece is easily distinguished from the others, making errors from mistakes in identifying a piece — a problem with other sets — unlikely. Previously, chess men of different types had a less distinct appearance from one another, and were not as standardized.
  3. In a Staunton set, the Knights are the most detailed, ornate, varied, and realistically represented pieces. 
  4. In Staunton sets, there is a standard height order: pawn, rook, knight, bishop, queen, king. (This surprised me, since Rooks are more valued in Chess I would have expected them to be taller than Bishops.)
  5. The pieces are differentiated by their tops. Each type of piece has a distinct, unambiguous shape.
  6. The body/base of the pieces have a common design, to create unity among the pieces in the set.

I tried to apply design choices to my chess set following these insights.

A follower on Twitter offered feedback that the pieces should be different heights, so I tried that. With a 16×16 pixel tile size, I could only shorten the back row pieces by 1-3 pixels.  I also tweaked the King piece by adding a few more pixels to its top, to make it a bit more distinct from the Queen, and moved the Pawn so that it wold be more centered in its square.

I do like the result:

Staunton pixel chessmen

I think my initial 16×16 Staunton set look like they’re in ALL CAPS, while this set is more “readable” by using “mixed case” heights for the pieces.

I wanted my chess game to be focused on usability and instruction. I needed each piece to be immediately recognizable, and not to convey a bunch of extraneous information to the player that has nothing to do with play mechanics. 

My next attempt was a different take altogether. I wanted the look of each piece to suggest its rules for movement. I also thought that it would be clever if the pieces communicated the rules for using them through their visual design.

I ended up being very pleased with this set as well, although I went through many more variations, particularly with the Pawn. This one also came together easily and rapidly.  When your tile size is 16×16 and you’re working in just a few colors, it’s easy to work fast.

Things I like about this set:

  1. The shape of the piece is a built-in tutorial for how the piece moves.
  2. The Pawns still have a pawn-like shape (at least the black pawns; white pawns are “upside down”).
  3. The Knight’s shape may be read as an abstraction of the horse’s head shape of the Staunton piece.

I think out of these variations, my favorites are: P9, Kn2, B3, R1, K?  I’m least certain which King I like.  I think K4 and K5 are my top two, but I also liked the idea of incorporating a crown motif into the design, to signify the King’s special property of being the King.  K1, K2 and K6 were attempts at this, but I think K1 looks too much like a Staunton Rook, unfortunately.

I wasn’t sure which of my designs to use for my final set, so  I posted my sets on Twitter and a pixel art community on Facebook. @Managore responded to my request for feedback by coming up with a set of his own design, which I quite like.

His design was retweeted and liked over 500 times, and received many positive compliments from his followers, many of whom are game developers. One of my favorite indie developers, @TerryCavanaugh, who made VVVVVV and Don’t Look Back, pointed out an physical chess set that had been designed a few years ago which incorporated the same ideas.

It’s exciting to see my idea get picked up and reworked by fellow game developers who are inspired by the concepts I am exploring. So fun! Getting that validation that what I’m working on is interesting to others is very motivating. But it’s particularly good to get some attention from developers whose work I’ve admired for years, however modest.

I’m excited about this project and look forward to working on the program. I have more design ideas that I’m looking forward to getting into soon.

Fun enum ideas for game development

Most video games have a counting, ranking, or level system of some sort. It’s often good to have a thematic flavor to your counting systems. This way, rather than calling your level progression by boring old regular numbers, you can give each level number a meaningful, or flavorful, name. This can add character or meaning to your game world, or it can be used to help disguise the underlying math, resulting in a game where the underlying mechanics are masked away from the player, leading to a more mysterious experience where they need to experiment and discover. What’s cooler: a “level 3 sword?” Or “the sword of autumn?” What’s more powerful: the knight sword or the rook sword?

To that end, I thought I’d demonstrate a few example enums that you can use to spice up your game design.

ENUMerate all the things!

Alphabet {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z}

Greek Alphabet {Alpha, Beta, Gamma, Delta, Epsilon, Zeta, Eta, Theta, Iota, Kappa, Iota, Kappa, Lambda, Mu, Nu, Xi, Omicron, Pi, Rho, Sigma, Tau, Upsilon, Phi, Chi, Psi, Omega}

Military Phonetic Alphabet {Alpha, Beta, Charlie, Delta, Echo, Foxtrot, Golf, Hotel, India, Juliett, Kilo, Lima, Mike, November, Oscar, Papa, Quebec, Romeo, Sierra, Tango, Uniform, Victor, Whiskey, Xray, Yankee, Zulu}

Army (simplified) {Private, Specialist, Corporal, Sergeant, Officer, Lieutenant, Captain, Major, Colonel, General}

Navy (simplified) {Seaman, Petty Officer, Ensign, Lieutenant, Commander, Captain, Admiral}

Chess {Pawn, Knight, Bishop, Rook, Queen, King}

Rainbow {Red, Orange, Yellow, Green, Blue, Indigo, Violet}

Elements {Earth, Air, Fire, Water}

CardRank {Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King, Ace, Joker}

CardSuit {Clubs, Diamonds, Hearts, Spades}

Zodiac {Aquarius, Pisces, Aries, Taurus, Gemini, Cancer, Leo, Virgo, Libra, Scorpio, Sagittarius, Capricorn}

Seasons {Spring, Summer, Autumn, Winter}

Months {January, February, March, April, May, June, July, August, September, October, November, December}

Weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}

Lunar Cycle {New, WaxingCrescent, FirstQuarter, WaxingGibbous, Full, WaningGibbous, ThirdQuarter, WaningCresent}

Some of these may not necessarily have a natural order to them, but might just be a set of categories which you could use to organize something in your game. That something could be worlds, or items, or creature types, or powers, or anything else you can think of.

What else?

What else is there? Probably a whole lot! You could probably make a good basis for a game system out of gemstones, or metals, or barnyard animals, or anything, really!

If you know of a set of things that would make a good enum that I’ve left out, leave a comment below.

Using enums in GameMaker Studio

Enums are covered in the manual in the article on Data Types.

The basic syntax is as follows:

First, you have to declare the enum.

enum <variable>{<constant> [= <value>]}

You create the enum using the enum keyword, naming the enum <variable>. Then, in brackets, you list all the constants that make up the values in the enum. You can explicitly declare values for the enum constants, or you can leave them implied, in which case GameMaker will assign them integer values starting at 0, and increasing in order through the collection. You can even use expressions rather than a static value.

To access the enum constants, you use the syntax enum_variable.constant.

In your code, there are all kinds of situations where using an enum is potentially useful. Here’s a few things to look for in your code that might signal a good opportunity to use an enum:

Conditionals for checking state

Consider the following ways of checking the state of some object:

//check state using string matching
if state == "state_idle" {//do state actions}
//check state using literal numbers
if state == 0 {//do idle actions}
//check state using variable
state_idle = 0;
[...]
if state == state_idle {//do state0 actions}
//check state using enums
if state == enum.value {//do state actions}

Out of these, using enums is the best approach. Why are enums better?

Conditional checking by string matching is much slower than number matching. Your string value provides semantic meaning to the reader, making the code easier to understand when a human reads it. But when the program goes to check the conditional, it has to check every letter in both strings to see if they match.

As well, this approach is fairly error prone. It’s very easy to type the strings in slightly wrong. If you’re not careful, it’s easy to type one string where the state is assigned, and another string value where you’re checking state in order to do something state-specific. If you don’t catch the error, you’ll have a hard to diagnose bug because the conditional check won’t match what you’ve set the state variable to. One extra space, or misspelled word, or inconsistent use of capital letters, and the string match check will fail. The compiler won’t help you catch this sort of bug.

It’s a lot faster to do conditional checking via numbers. But naming your states with literal numbers: 0, 1, 2, etc. provides no meaning. Is 0 the idle state? is 1 running? is 2 jumping? Keeping track of this stuff in your head makes your work as a programmer harder, and makes the code hard to read, and brittle. You can do slightly better by creating a named variable and assigning the number value to it. The named variable can be expressive, e.g. state_idle = 0, state_running = 1, etc. But variables values can change, and storing each value takes a little bit of memory. By contrast, an enum value is constant — it cannot be changed once it is declared. And enums are global, so they are only declared and set in memory once, and thus require fewer resources. Even if you have ten thousand instances that use your enum, the memory used by them is the same as if there is only once instance.

Create an enum that provides expressive labels on these values, and you have the best of both worlds: expressive code that checks conditions fast, and uses computer resources efficiently.

Iteration over a set

Conventionally, programmers often rely on conventional looping variable names such as i or j to iterate over a collection of things, such as the members of an array, or other data structure. While this is OK, you can make your code more expressive by using enums to denote important numbers.

For example, it’s common for programmers to use a nested for loop iterating over the variables i and j to create a grid structure. Instead of using i and j, we can use variables named row and column instead. As we iterate over the range of rows and columns, we can use enums as flags to do something special at row (or column) == enum.constant.

Another example:

Say we want to implement an inventory equipping system for the player. The character has inventory slots for head, body, gloves, right hand, left hand, shoes. We decide to create an array, called inventory[], and assign the equipped item in each slot.

We could simply index the array with numbers:

inventory[0] = hat;
inventory[1] = armored_breastplate;
inventory[2] = iron_gauntlets;
inventory[3] = sword;
inventory[4] = empty;
inventory[5] = double_jump_boots;

Now, it’s not too hard to tell what each inventory slot is for. But it’s not as easy as it could be, either. Is the sword in the left hand or the right hand?

Let’s use an enum, and make the code easier understand.

enum inv_slots{head, body, gloves, right_hand, left_hand, shoes};
 
inventory[inv_slots.head] = hat;
inventory[inv_slots.body] = armored_breastplate;
inventory[inv_slots.gloves] = iron_gauntlets;
inventory[inv_slots.right_hand] = sword;
inventory[inv_slots.left_hand] = empty;
inventory[inv_slots.shoes] = double_jump_boots;

Now, it’s quite easy to see that the double_jump_boots are being worn on the player’s feet, rather than being carried in the player’s hands. It’s simple to keep track of which slot is which.

Creating a set of related, named values

Here’s a useful enum for direction angles for a top-down game:

enum compass {e = 0, ne = 45, n = 90, nw = 135, w = 180, sw = 225, s = 270, se = 315};

It’s much easier to remember and understand direction = compass.sw instead of direction = 225. You can use this enum for 4-direction and 8-direction movement or aiming, and you could even expand upon it if you wanted by adding constants for ene, nne, nnw, wnw, wsw, ssw, sse, and ese, like so:

enum compass {
 e = 0, 
 ene = 22.5, 
 ne = 45, 
 nne = 67.5, 
 n = 90, 
 nnw = 112.5
 nw = 135, 
 wnw = 157.5
 w = 180, 
 wsw = 202.5
 sw = 225, 
 ssw = 252.5
 s = 270, 
 sse = 292.5
 se = 315,
 ese = 337.5
 };

(I like to format my code like this; lining up the variable names, equals signs, and values makes it easy to scan down the file, and makes it clear that these values are all related.)

If I wanted, I could go a step further and use radians to make it clearer that these values are fractions of a circle:

enum compass {
 e = 0, 
 ene = radtodeg(pi * 0.125), 
 ne = radtodeg(pi * 0.25),
 nne = radtodeg(pi * 0.375), 
 n = radtodeg(pi * 0.5), 
 nnw = radtodeg(pi * 0.625),
 nw = radtodeg(pi * 0.75),
 wnw = radtodeg(pi * 0.875),
 w = radtodeg(pi), 
 wsw = radtodeg(pi * 1.125),
 sw = radtodeg(pi * 1.25),
 ssw = radtodeg(pi * 1.375),
 s = radtodeg(pi * 1.5),
 sse = radtodeg(pi * 1.625,
 se = radtodeg(pi * 1.75),
 ese = radtodeg(pi * 1.875)
 };

You can group together, and name other values that go together in a system using enums in this way, too.

Parting thoughts

Hopefully, these examples will help you see how enums can be useful to make your code more expressive, easier to read, and easier to maintain. Look for opportunities to use them in your code. They can really help!

csanyk.com © 2016
%d bloggers like this: