A Room With a View…of the Courtyard
After a too-long PAX-and-New Character Art-based build hiatus, I’ve updated the Early-Access Beta build 4 times in the last week or so! It feels good to be updating the game for the beta testers again! There are a lot of small fixes and features in these builds, but the two big ones are the addition of chat rooms and a brand new map, Courtyard.
Courtyard
In the old days, we walked to the only map, the Ballroom, uphill, both ways, and we liked it. Eventually, after a couple years of playtesting on that single map, I decided to test my working theory that making new and interesting maps for SpyParty wouldn’t be too terribly hard, at least relative to something like doing the AI and animations for a new mission. In other words, I was working under the assumption that because most of the gameplay in SpyParty is based on the character behaviors and the perception and deception mechanics, doing new maps would be a relatively easy way to add new gameplay. The maps would obviously be important and add a lot of variety to the game, but their layouts would not be as crucial to the feel of the game as they are in a shooter or a platformer. I mean, Ballroom itself is just a box and everybody seemed to like it!
So, I tested this theory by adding the Balcony and Veranda maps, and I’d say the theory was proven to be true, since both of those maps worked well and people like playing them. The Ballroom is still the go-to map for serious play because it’s the most tuned and balanced, but the other maps add some spice and hint at how the game will feel with lots of different settings and map topologies.
On the runup to PAX, I had an idea for a new map where the statues would be centrally located, but the Sniper couldn’t see them all at the same time. I was wondering how that would change the Inspect Statue and Swap Statue missions, which have turned out to be two of the riskiest missions for Spies to attempt. My original thought for this level was a single statue right in the center, but I decided that would be too hard, so I settled on three statues embedded in a central pillar, where the Sniper can only see one at a time.
I hacked this map together one night at PAX, and we playtested it the next day. The initial tuning was way too hard for the Sniper, not to mention how hard it was to get your bearings. After some tuning, and Wessel’s suggestion of using a statue of Alan Turing to give the Sniper an orientation reference point, the Courtyard seems to be working out well. I think I overcorrected a bit and the statue missions are now a bit hard for the Spy again, and it needs more playtesting and tuning, but it’s definitely already interesting and fun to play for both roles.
Current stats for Courtyard look like this:
| Game Type | Total Games | Spy Wins |
| all | 420 | 172 (41%) |
| Known 3 | 14 | 10 (71%) |
| Known 4 | 32 | 14 (44%) |
| Known 5 | 18 | 6 (33%) |
| Pick 3 of 4 | 63 | 27 (43%) |
| Pick 3 of 5 | 14 | 8 (57%) |
| Pick 4 of 5 | 90 | 28 (31%) |
| Any ? of 4 | 15 | 4 (27%) |
| Any ? of 5 | 174 | 75 (43%) |
You’ll recall there there are currently three game types in SpyParty, “Known n” where the Sniper knows the n missions the Spy will try to accomplish, “Pick n of m”, where the Sniper knows the m missions available, but not which n ones the Spy picked, and “Any n of m”, where the Spy can choose which n to accomplish opportunistically during play, rather than having to pick them ahead of time. We’ve started abbreviating these k4, p4/5, a3/4, and so on in the beta chat and forums.
As you can see from this table, the different modes have different levels of handicapping between the players. I’ve just gathered these numbers from all the games on the Courtyard map, so this is totally ignoring skill differences, early games where players were just testing out the map, and the like. But, it’s still interesting to see the balance.
Unfortunately, as you can see, the Any game types are missing their n parameter. As I started gathering this data, I realized I’d screwed up and left that number out of the database for Any game types, so I can’t tell if the a?/5 games are a3/5 or a4/5, which is a bummer, because it makes a big difference in difficulty for the Spy and Sniper. I’ll probably have to ignore old Any games when I do real ranking with this data. I’ve since fixed it,1 and although there aren’t enough games with the new correct data yet to be statistically significant, here they are:
| Game Type | Total Games | Spy Wins |
| all | 46 | 16 (34%) |
| Known 4 | 9 | 0 (0%) |
| Pick 3 of 4 | 15 | 9 (60%) |
| Pick 4 of 5 | 1 | 1 (100%) |
| Any 3 of 4 | 1 | 0 (0%) |
| Any 3 of 5 | 1 | 0 (0%) |
| Any 4 of 5 | 19 | 6 (31%) |
Chat Rooms
Soon I will be opening up the beta, and this (hopefully) means a lot of people will be playing SpyParty simultaneously, at least towards the end of the closed beta when I send out the rest of the invitations and into the beginning of the open beta when anybody can sign up and play immediately. The old lobby had a single room, and when 10 or 12 people were in there chatting, it got a bit hard to keep track of who was talking to who and what they were saying.
So, I did the simplest chat room design possible, with the goal of load-balancing the lobby if there were 30 or 100 simultaneous users chatting. I basically decided to put all the room creation and multiple-join/leave commands on the chat console, and have the GUI only allow you to select a single existing chat room at a time. This way advanced users can hang out in multiple chat rooms and make new rooms, but newbies can just join one and chat and play a match without thinking too hard about it.
The jury is still out on whether the current chat rooms work very well, and we’ll have to wait until I invite more people in to see if they solve the load balancing problem, but they’re certainly slightly confusing at the current density. I tried to make sure joining “Headquarters” (the default room that’s always there) was easy enough that you didn’t have to think about it and it acts just like a single room lobby if there aren’t many people online, but I didn’t want to dump people automatically into a chat room for fear of causing problems when the game was scaled. We’ll see how it works out. I foresee a lot of changes in this code and UI as the number of simultaneous users goes up.
One change I made shortly after releasing the feature was adding a “Created by <username>” line in the chat room description. Since users can create any rooms they like, this will at least keep people honest, or at least culpable! Before I added this players were creating rooms that sounded official, which was funny but probably fraught with peril. I also don’t support hidden rooms or password protected rooms or anything yet. I’d like to keep the community from segregating as much as possible for the time being.
On the subject of chat, I really need to do something soon about my text rendering code, it is incredibly slow right now:
checker: /fps
SpyParty version v0.1.2202.0
19.869 ms/frame (fps: 50.33) sort self - current frame
zone self hier count
checkerlib::simple_font::DrawStringOrthoPixels 18.6377 18.6377 54.78
+chat_display 0.3964 16.6585 1.00
SwapBuffers 0.2445 0.2445 1.00
+IdleFinal 0.2400 0.4846 1.00
+_global 0.0582 19.8692 0.00
Logging Performance, etc.
There were a bunch of other smaller fixes, one of which other programmers might find interesting: I use the spypartyhelper.exe to write the log files now, rather than having the main spyparty.exe write them out. The helper has always done the crash dump management (using a modified version of Google’s Breakpad) and the auto-updating privilege escalation, but now I also have it handle logging, using a named pipe from spyparty.exe. The reason I made this change was some machines (like my main development machine) would happily write out the logs in the main process without affecting performance at all, even though I had commit mode turned on for the log file. I used commit mode so if the game crashed, the log file would contain the most up-to-date log entries, so when the helper grabbed it and put it in the crash dump report and uploaded it to my server I could use it for debugging. However, on some machines, the commit mode logging would take hundreds of times longer, and I couldn’t figure out what the difference was between fast and slow machines. What’s worse, it became clear that a lot of beta testers were assuming the game just loaded slowly, which subtly (or not-so-subtly) affects how you feel about the game, even though all the time was being spent writing log statements. Once I realized people were suffering with slow load times, I knew I had to fix it.
The weirdest bug I fixed involved the Spy playing the cough animation as soon as control was taken from the AI. The cough animation is supposed to be played when the Spy bails out of a conversation too soon after saying “banana bread” to contact the Double Agent. I added the cough because some people were cheesing out and running away from the circle before the contact animation had finished, and it was too hard for the Sniper to spot this glitch. So, the cheesers got a big surprise a few builds back! But, it shouldn’t be happening in a new game if you haven’t even done anything yet, and beta testers couldn’t get a good repro. Well, after a bunch of debugging, it turned out I wasn’t clearing a timer in the Contact Double Agent situation on new game, so if somebody was shot within 2 seconds of a “banana bread”, then since they were moving at the start of the next game but the timer hadn’t expired, the situation decided they’d cheesed out of the conversation and made them cough. Yay for cross-game bugs! I guess it was the ghost of the previous victim making the Spy cough!
Mail Deliverability
Man, sending mail reliably on the internet today is fraught with peril. I’ve been trying to figure out how often a beta invitation or confirmation mail simply doesn’t get delivered, or gets dumped in a spam folder. So far, I’ve struggled with and been victorious getting SenderID and SPF working, and I’m still wrestling with DKIM, but I am confident I’ll prevail…eventually. Of course, all the major mail clients use different standards. I guess I could just pay a mail sending service to handle this for me, but it just seems crazy if I’m forced to do that to get mail delivered. Then again, I’ve wasted a ton of time dealing with this, so maybe it would have been worth it. I tend to think the learning and understanding I get from working through these problems myself is worth the time investment, but that could easily be rationalization, who knows?!
Update: I think I have prevailed in the email war. I’ve got all the major email providers2 verifying my DKIM and SPF records. I had to battle php messing up newlines which confused the hash, SELinux disallowing postfix from talking to opendkim, and whole bunch of other randomness. My only problem now is with AOL, and their postmaster just admitted the problem was on their side and they’re fixing it. Hopefully that is the end of any spyparty.com email going into the spam folder, woohoo! I sent out 500 invites tonight to celebrate, which brings us to 2011-05-11 06:35:21 US Central Time on the in-order invites.3























