Bringing Super Mega Baseball to SHIELD
Tight controls and a smooth learning curve have players knocking it out of the park in no time in this arcade baseball simulator, named Polygon’s 2014 Sports Game of the Year.
Super Mega Baseball is designed for the ultimate couch co-op experience with room for up to 4 players. A groundbreaking difficulty system offers a grand total of 100 difficulty levels, allowing anyone to play a competitive game no matter how good (or bad!) their friends are. Take it a step further by analyzing the full batting and pitching stats to hire the best staff and level up throughout a season. The atmosphere may be light, but the simulation is deep in SMB.
What Went Right?
Super Mega Baseball was designed as a console game that leverages console class (or PC) hardware. The game’s world is full of animated characters, thousands of crowd members, a complex physics simulation and very complex animation blending. It’s a twitch game that rewards very precise and well-timed input from the player, so running at 60fps is integral in order for all of this to work properly.
When we first looked at porting to this platform, we assumed we’d have to simplify the crowd and cut corners visually in order to hit 60fps. As it turns out, the SHIELD hardware is remarkably powerful. In addition to running at full 60fps, we were easily able to run at 1080p and MSAA (with GPU headroom to spare). On other platforms we were frequently bound by the render-thread (CPU), which was the case on SHIELD as well, but the processor is fast enough that a modest amount of optimization work let us hit our performance targets.
NVIDIA Graphics Debugger
The NVidia graphics debugger tools were invaluable when implementing and optimizing the OpenGL ES renderer backend.
We communicated via email to NVIDIA staff, and they were always very responsive and helpful with any problems we had. In addition to providing support, they were actively playing and testing the game as test builds went live, giving us real time QA feedback.
The SHIELD does not easily support multiple users on one device, nor is the user required to be signed in to Google Play services. This becomes problematic when trying to provide a seamless user experience across multiple devices and preserve user savedata. A person can play the game while signed in to Google Play (where savedata lives in the cloud), or not signed in (where savedata is stored locally only, with no user information available). This makes it effectively impossible for multiple people to share the same SHIELD device and have their own version of savedata.
So with Super Mega Baseball, we had to work with the assumption that only one user per SHIELD device will be trying to progress in the game. Even though the game supports local multiplayer, only one set of progress is saved.
A simple versioning scheme within our savedata format is used to determine whether we should use the local or cloud version of a savedata file. This makes it technically possible to ‘transfer’ savedata information from one user to another.
Each of the platforms that Super Mega Baseball is on has a different method of associating a particular controller with a particular user account. So we’ve had to make the game treat each platform a bit differently. On platforms where a user signs-in and the OS manages the user->input device mappings, the OS does all the heavy lifting for us. On devices that only support a single ‘signed-in’ user, such as Steam or PS3, we just associate each new input device with the same user. Since the SHIELD falls into this latter category (supports only a single signed-in user, with the OS not mapping input devices to users for us), this is the model we used.
The issue that we ran into was that the game on SHIELD reads some single controllers (like the Xbox 360 wireless pad) as multiple connected input devices. Basically, turning on a single Xbox 360 wireless pad reported to us that 4 new pads were present. So when you plugged in any additional pads (such as a SHIELD controller), the game ignored them, because only 4 players are supported.
This meant that we had to enable a ‘user engagement’ model where regardless of how many input devices are connected, we require a button to be pushed to map a user to an input device. Fortunately for us, we already had this system in place because this is the model required on Xbox One as well.
Google Play Integration
We have abstractions for online features that allow us to smoothly integrate with the various console and Steam backends (for leaderboards, cloud saves, achievements, etc). In theory, adding another backend driven by Google Play should have been very straightforward. Unfortunately, the Google Play API is somewhat different than all the others, with respect to how data can be retrieved, and configuration was unnecessarily complex.
Unfortunately, this has resulted in an inferior user experience where we can’t have full global leaderboards because users must opt-in to publishing their scores globally. For Super Mega Baseball, comparing your score to the rest of the world is core to the competition of the game, and it’s simply not possible on this platform.
What Went Wrong
Release Mode Build Time
The GCC toolchain was excruciatingly slow when turning out our release build (with full optimizations turned on), taking over 20 minutes for the compile/link step. On all of the other platforms we’ve worked with, this took under one minute.
The version of GDB that shipped with the toolchain simply did not work for us. Some of the features we use in C++ would cause it to crash. The problematic code was at the core of the Object Model System in the engine, so it was impossible to work around this problem. Not having a functional debugger was a showstopper for us.
Fortunately, the NVIDIA team was already working on a replacement. Within days of us raising this issue, we were provided with an experimental build of their internal debugger (which worked perfectly!)