AWS for Games Blog
Guest Post: A platformer maker, made for every platform
In this guest post, Butterscotch Shenanigans cofounders Adam and Sam Coster explore the importance of cross-platform play in launching latest crafting platformer, Levelhead, simultaneously across console, mobile, and PC.
Butterscotch Shenanigans started as a family passion project with three brothers who wanted to pursue their creative dreams, starting small to allow room to fail fast, learn, and move forward. In 2018, we put our learnings into practice, aiming to build a game so ambitious that no one would assume it had such humble roots.
After a year in open beta, last month we launched Levelhead, a platformer-maker that sees players use programmable switches, secrets, and hundreds of items to create complex levels. It’s the first game of its kind to feature a level exchange, wherein players can boost their levels to the top of the charts by playing other community-made levels. Any player can get their creation seen by the masses – and collect hundreds of thousands of plays and followers in the process. Levelhead is also intrinsically cross-compatible. Players can pick up and play levels regardless of platform, storefront, or language. They can seamlessly move their works-in-progress to the cloud and continue editing them from any platform they own the game on.
In just over 3 weeks, Levelhead has seen more than 133,000 players, 22 million level attempts, over 40,000 levels published, and heart-warmingly positive reviews from players and the industry alike. For a small team with limited resources to successfully develop and launch a project of this size, and simultaneously publish it across 6 platforms and storefronts across mobile, console, and PC (Xbox, Nintendo Switch, Epic Games, Google Play, and the App Store) feels like an achievement to say the least. And we think our ability to do all this, comes down to placing cross-platform as a priority for our game, and our team.
Platform and device agnosticism is a core business pillar of our studio. That is, players should be able to pick up a game on their favorite storefront and device, and their experience should be the same as anyone else’s and feel native to wherever they are playing. Taken one step further, the user should be able to grab the game on a different storefront or device, and swap from one to another whenever, and wherever, they like.
Core Problem: Data Centralization
Becoming cross-platform compatible is something that has to be true throughout the entirety of the business, and that includes our architecture. All the data a game generates has to also be platform and device-agnostic, and so it has to be centralized into one backend system, which we aptly named Rumpus.
Data portability is essential to enable cross-platform generally, but this is even more true for us. Levelhead is a platformer-maker powered by user generated content (UGC). We consider absence of data portability between devices (and platforms) as actual data loss, and so it was essential that we made seamless data portability a core part of Levelhead’s design. All this boils down to two core components in our game architecture: data storage, and a seamless login system.
Storage at scale
As you can imagine, UGC games generate heaps of data from created items and levels, player progression features, save files, and logs. By nature, these games are also innately social, and so require players to have seamless access to their own and other player’s data.
The core of our storage system within Rumpus is a custom service we call “crates”. Crate items are the combination of a collection of structured, searchable data stored in MongoDB linked to binary blobs (like level data), and stored in Amazon Simple Storage Service (S3). Ultimately, having a robust, well-tested, generic storage system built on AWS allowed our development to move rapidly and prevents us from having to develop new storage systems for every new feature, which becomes especially costly during the discovery phase of development when requirements are rapidly changing.
Our crates have access rules including who can create items in that crate, how many items can be created, and how large of data payloads they can store, etc. Crate definitions also include database indexing schemas, lifecycle hooks, definitions and permissions for stats and leaderboards, and so on. By having generic tooling around these crates, we could make specific definitions for each of the primary kinds of user data including player saves, player-made levels, profiles, and more.
Because we have full control over this system, we can custom-tailor any given crate once we fully understand its use case. For example, during development we identified the generic search options and database index patterns on crates meant level searches weren’t scalable past ~10,000 levels. Leading up to launch we resolved by testing various strategies against a million simulated levels until we could get all searches below 30ms (and most less than 5ms).
In order to support specific storage needs, you also need to have a scalable compute foundation layer. We use Rumpus to facilitate all web requests, whether for storage, authentication, and everything else in-between. To ensure that we could focus our dev time on features, and not on infrastructure, we deploy Rumpus into AWS Elastic Beanstalk with automatic scaling based on CPU usage. Similarly, our database (hosted by MongoDB Atlas with peering into the Rumpus Virtual Private Cloud) is set to autoscale as needed. After some pre-launch stress-tests to make sure things were auto-scaling as expected, we were able to launch with the confidence that our web tech would keep running without a hitch, our costs would stay as low as possible, and data would remain both secure and accessible.
Buttery Smooth Logins
It’s one thing to ensure data can be safely and easily stored and shared amongst players, but enabling seamless native access to platforms and stores is a different story. Every platform has its own user management system, as well as rules around 3rd party login systems. For the most restrictive platforms, we must integrate our login system with the native one and must not provide alternative login options. And while it’s tempting to pull out the pitchforks when we feel the a platform is making us conform to its rules, the fact is that native login provide a much better user experience.
To satisfy all platforms and create the best user experience possible, we defined requirements for our system that included: ensuring users could access our centralized login service in Rumpus regardless of platform or authentication system, integrating Rumpus with each native account system, and where possible providing alternative login methods for users who have strong preferences (e.g. some may like to provide an email rather than a platform ID).
In order for all of this to work, players would need to be able to connect their Rumpus account to all of their platform accounts. We achieved this by enabling players to log into their central Rumpus account using one authentication method, and then simply connecting all of their platform accounts so that future, native logins on other platforms are painless. To make things even more smooth, we also made it so that accounts with verified email addresses would automatically add those email addresses to Rumpus during first-time login. Any future login attempts with other accounts that bore the same verified email address would log them into the same Rumpus account, while also storing the identifier for the new authentication service.
Behind the scenes this required a ton of work. For each platform we had to implement in-game login as well as web-based login. On the game side, this meant figuring out how to have the game talk to each platform securely, and with the user’s permission, to obtain their identifiers and send them to Rumpus. On the web side, this meant hooking up OAuth individually for every platform. Sitting in the middle, the shared authentication logic of Rumpus had to be able to validate each incoming request, then look up the user to see if they existed or otherwise send them to register. Add license-checking, and the fact that each platform has a unique authentication method, and cross-platform authentication quickly becomes a mammoth task!
While this was all an extremely heavy effort for us to put together and test, the benefits have been clear. Despite having more than 133,000 players to date, we’ve encountered very few complaints or support issues with logging in, have an extremely high login rate (players aren’t required to log in, but must log in to access all the web features), and see a substantial fraction of players playing the game on at least two different platforms.
Read more about Butterscotch Shenanigans’ infrastructure or find more game solutions at the AWS Game Tech website.