Pleasing all of the people all of the time

Published
2014-06-12
Tagged

Buckets of Dice 2014, Christchurch’s local gaming convention, has just finished, and we’re getting a raft of happy people enthusiastically telling us how much fun they had1. One question that came up in discussion with out-of-towners is how we allocate players to games. There’s a couple of fun algorithms we’ve developed over the last few years to do player allocation, and since it may be of use to others who are helping organise roleplaying conventions (or any other real-time event where you have to repeatedly assign people to things), I figured I’d post it on the internet for everyone to see.

Because there’s no niche too small on the internet.

The setup

Because some people won’t attend roleplaying conventions but may still want to understand what I’m talking about.

At your average roleplaying convention, you have a series of games in a number of sequential sessions. Each game is run by one person (which we’ll refer to as “Game master” or “GM”), and has a minimum and maximum number of players that it can take. Each player, obviously, can only be in one session at a time.

Drawing this made me feel like I was preparing for a business-type powerpoint presentation.

In an ideal world, every game would end up with some number of players in it between the minimum and the maximum, and every player would end up in their most favourite game ever. In reality, however, you may find yourself with some games over-booked, some under-booked, and so on. By necessity, some people won’t end up in their first choice. A good game allocation system makes re-allocation easy and also guarantees that someone who gets the short end of the stick in Session 1, say, will get their pick in Session 2 to make up for it. You can’t guarantee that people will always get into the games they want, but you can make sure that they don’t spend three sessions playing in games they’re only vaguely interested in.

The big picture

Our current game allocation strategy is heavily modelled on that of KapCon, Wellington’s annual roleplaying convention. I’m not sure if members of their committee have ever published their allocation strategy, but I wouldn’t be surprised if it’s something like ours. It’d be interesting to compare spreadsheets some day, and see how we differ from each other.

Every convention attendee registers for future sessions by filling out a Game Selection Form. This form has fields for the attendee’s name, the session they’re registering for, and their first three picks, ordered by preference:

A sample game selection form.

These game selection forms go into a suitable receptacle (this year it was a big yellow bucket) at the front desk. They need to get in by the start of the previous session (so Session 2 entries need to be in by the start of Session 1). This is because if you hand in your Session 2 entries at the start of Session 1, the team on desk processes the forms during Session 1 and can post the allocations between Sessions 1 and 2.

The signup timeline plan (for the first three sessions, at least).

(What about Session 1? If you’re really organised and know what’ll be running in Session 1 when you run registration, you can get your attendees to register for Session 1 when they sign up. Then you have months to assign your games properly.)

Dealing with imperfection

And if we only ever got perfect allocation schemes where everyone slotted into games perfectly, that’s all we’d need to do. Unfortunately, some games are more popular than others, and that leads to people getting bumped out of their first choice. This is how we deal with that:

Every attendee has a certain number of points. Points are bad. The organisers’ goal is to keep everyone’s point total as low as humanely possible. When you assign attendees to games, the number of points they get is dependent on which game they get into:

  • If an attendee gets into their first choice, they receive zero points.
  • If an attendee gets into their second choice, they receive one point.
  • If an attendee gets into their third choice, they receive two points.

We have never needed to put an attendee into an event outside their choices - I guess it could happen in really extreme circumstances, and then they’d get three(!) points.

If a game is over-full (i.e. there are more people who want to be in it than can play in it) we can use attendees’ points to work out who to remove. The workflow goes something like this:

  1. Find the person (or, more likely, people) in the game with the lowest point value. One of these people will be playing in their second choice.
  2. Check each attendee’s second choice. Can any of them slot into their second choice without over-filling it? If so, pick one of these people at random to re-assign.
  3. If none of these attendees can slot into their second choice without making it over-full, nonetheless pick one at random. Examine their second choice. Can you move someone with a low point value out of this game and into their second choice? If so, shuffle appropriately.
  4. If shifting one of these attendees into their second-choice results in a cascade of second-choice point-gaining moves, start examining the attendees’ third choices. Can one of them find their way into their third choice easily?
  5. If all these fail, you may have more players than available slots.

We generally don’t go beyond step 2, but it can happen. The goal here again is to make sure that people gain the least points possible. We’ve made it a rule that if you have to choose between one person getting their first pick and one their third pick, or two players getting their second picks, we should go for two players getting their second picks. Those players that do end up in second- or third-pick games, of course, will be favourably placed to get into their first choice in the next round.

The nitty-gritty

Or, how to do this in real time during a session when people keep asking you how much drinks are and where’s room 203 and when does session four start and where can they buy food and can they get into Joe’s game please they’ll be your best friend forever.2

Game allocation at Buckets of Dice is done via one large Excel spreadsheet. We have a separate sheet for each session, and each sheet shows which sessions each attendee signed up for, which session they ended up in, and how many points they got, as well as each game that’s running that session. Here’s a sample:

The spreadsheet that runs it all, with random names.

There’s five tables on this spreadsheet, although “GMing this session”, “Desk this session” and “Player finder” are all very similar and will be covered as one.

Table 1: The master table

This table lists everyone attending the con, their choices, and their allocated game. The data in column A can be fetched from a master list, for example the formula for cell A3 would be:

1
='Master sheet'!A3

This will autofill nicely. Choices are entered as codes - so for example, Goldie Holts on row 16 wants to play in Lady Blackbird, but if all spots are full she’ll go for Fading Suns or Monsterhearts. These do need to get translated as you enter the slips, but this shouldn’t take too long (and it’s even easier if they hand in their slips earlier than required). The “Code Allocated” column is usually set to be equal to the player’s first choice, for ease of use. The “Game Allocated” column is set up to fetch the name from the table on the right - for example, cell F3’s formula is:

1
=VLOOKUP(E3,K:M,3,0)

VLOOKUP()‘s arguments are:

  • The value to look up (E3)
  • Where to look it up (the range, K:M)
  • Which column of the range to use for display (3), and
  • The type of search (here 0 means that it will only accept exact matches)

Finally, we reach the Points columns. The “Previous” column is set to 0 for the first session - Session 2’s “Previous” column would just be set to Session 1’s “Total” column, so e.g. cell G3 in the Session 2 sheet would be equal to:

1
='Session 1'!I3

The “This” column is determined using a convoluted series of IF functions. For H3:

1
=IF(OR(B3="y",B3="z",B3=E3),0,IF(C3=E3,1,2))

This formula assumes that people will get into one of the three games they chose, and that you don’t give points to people who are on desk (y) or GMing (z).

Finally, the “Total” column is simply the sum of the previous two.

Table 2: The Games and GMs table

Columns K through O are all manually assigned, taken from GM signups. The “Allocated” column simply uses a COUNTIF to determine how many players are allocated to a given game. For example, the formula for P3 is:

1
=COUNTIF(E:E,K3)

Column Q (part of the “Allocated” column) is a status marker, showing if a game is under- or over-full. The formula for Q3 is:

1
=IF(N3="",IF(P3>0,"✓","!"),IF(P3<N3,"",IF(P3>O3,"!","✓")))

An exclamation point indicates that the game is either over-full or under-full, and either way needs attention before the session goes ahead. The “Full” column is a much simpler check - for R3:

1
=IF(P3=O3,"✓","")

It only displays a check when the game is completely full, and can be used to help re-assign people.

Tables 3-5: GMing, Desk, and Player finder

These are all very similar, and use a sequential series of MATCH() formulae to display lists. The GM finder is basically a player finder table hard-coded to look for the code “z”, and the Desk Duty finder one hard-coded to look for the code “y”.

The code is manual entry, and the game name is fetched in a similar manner to how column F is generated in the main table. The “#” column has two different formulae. The first row (cell T6) is generated by the following formula:

1
=MATCH(U2,E:E,0)

It simply matches the game code against the “Code Allocated” column, and picks up the first exact match. The player name and point total are generated by the INDIRECT() formula, in my opinion one of the most game-changing formulae that you can play around with in Excel:

1
=INDIRECT("A"&T6)
2
=INDIRECT("G"&T6)

Every other row uses a slightly different formula for the “#” column. Here’s the formula for cell T7:

1
=IFERROR(MATCH(U$2,INDIRECT("E"&T6+1&":E500"),0)+T6,"")

The main thing to notice here is the MATCH() function, which finds our game code in the range Ex:E500, where x is (the last match + 1). We need to add this value to the match as well, which is why we add T6 at the end. The IFERROR() just ensures that if we run out of people we leave blank cells, which looks much nicer.

Putting it all together

So this is how your actual workflow goes:

  1. Enter in game allocations for everyone in the main table. The “Code Allocated” column is automatically set to everyone’s first pick.
  2. Locate problem games in the “Games and GMs” table.
  3. Bring up over-full games in the Player finder. Pick a player with the lowest point value in the game, and see if you can move them to their second choice.
  4. Repeat until over-full games are eliminated.

Extra for experts

This isn’t the fullness of our allocation process. Here’s some issues we ran into:

Judging demand

This is hard.

We had a bit of panic four days before the con started, looking at demand for Session 1. The problem was that we had 41 signups for Session 1, and nowhere like that many vacant spaces in later sessions. We quickly scrounged up some surge proection (see below) for a number of the other sessions, but it turned out we didn’t need most of them in the end (thankfully). We did, however, learn some important lessons:

Demand tends to drop as the con progresses and people get tired. Especially, expect low demand on the morning after big events (duh) and afternoon sessions near the end of the con (as peoples’ energy starts to flag). Which means if you don’t quite have as many open slots on the Sunday of a two-day weekend con, you don’t have to worry too much.

Big events are trouble when it comes to allocating players. If you don’t hit critical mass with a four-player-minimum RPG, you’re left with at most four people (three + GM) to reallocate. If no one wants to play a twenty-player-minimum party game, now you have a sudden influx of up to nineteen people to move about. Pre-registration is one way around this: by getting people to register for these events before the con starts, you can gauge interest and have plenty of time to react if you don’t have many people showing enthusiasm for it.

What about when there’s too few players?

If games aren’t going to run, you want to notify the relevant GM as soon as possible, so they can slot into another game. Since you will hopefully only have to do this to one person, you can always consult with them between Sessions and alter the schedule as appropriate. If this starts happening a lot, you can always make sure that GMs submit their own game choices with everyone else, which at least gives you the ability to re-assign them early.

What about when there’s too many players?

Again following in KapCon’s footsteps, we implemented a regiment of Surge Protection GMs, ready to step in with low- or no-prep games if sessions got too full.

The problem with Surge Protection, of course, is that you want to activate it at least one session before it’s required, so people can sign up to the Surge Protection games if they like the look of them. We got around this problem by advertising Surge Protection games but also mentioning that if any games got pulled due to lack of demand, these games would get pulled first. Surge Protection GMs still submitted session allocation forms like every other player, so we could re-assign them when their games didn’t run.

Conclusion

So that’s how we do game allocation at our con, from concept through to implementation. I recommend that you build your own spreadsheet for your con: there’s nothing like knowing exactly what each cell of your spreadsheet is doing, and it’s generally hard to add comments to Excel spreadsheets. The general principle can be expanded to other media as well: if you have an interface you want your desk folks to be using, I encourage you to try implementing this system on that instead.

Now this is all dealt with, you get the fun job: actually organising the con.


  1. Thanks, guys! 

  2. This session assumes that you know your way around an Excel spreadsheet, and what a formula is.