How many games of Hush Hush are there?

This will be a pretty quick blog post that takes a look into how many different paths exist in Hush Hush.  Some assumptions will have to be made, but the final result should be at least the correct order of magnitude (ish).  Let’s get started!

The first thing we need to do is figure out how many choices a user has in an asset.  To figure this out, I’m going to write a little AI that just randomly plays each Hush Hush asset 1,000 times, and compute an average number of decisions the player has to make.  That outputs something like this:

Averaged 11.483 choices in Bonnibel Date 1.csv

Averaged 7.561 choices in Bonnibel Date 2.csv

Averaged 2.252 choices in Bonnibel Date 3.csv

Each choice is generally one of 3 options, so that means that we can translate these numbers to unique paths by taking 3 to the power of the average number of choices.  Note:  This isn’t perfect, because this will just give the number of paths of an average play session.  This is an exponential function, which means we can vary by a lot with each additional choice made in a date.  This would give something like the following for number of unique paths:

Averaged 301,150 unique paths in Bonnibel Date 1.csv

Averaged 4,050 unique paths in Bonnibel Date 2.csv

Averaged 12 unique paths in Bonnibel Date 3.csv

Next, we’ll need to process the action list, which is a list of all of the different things a player can do in the game for each time slot.  We’ll need to calculate the total number of paths possible at each time slot, and then multiply that by the other time slots.

Some time slots are easy.  For example, if a time slot is only a job/skill (typically night or dawn) then we can calculate the paths pretty easily.  A night time slot (when both light and dark karma jobs/skills are available) has 20 different options. A dawn time slot (when only light karma jobs/skills are available) has only 10 different options.

Some time slots are pretty hard, and contain a mixture of mini events, events and phone messages.  I’ve assumed the player will read every phone message, and will also pick a random number of mini events, before picking an actual event at random.

After some number crunching, this results in around 1.34*10^62 unique paths for jobs and skills, another 4.08*10^229 unique paths for events (such as dates, intros and other purple items on the map), and then another 1.28*10^279 unique paths for everything else (phone messages and mini events).  Multiplying these together suggests there are approximately 7*10^570 different paths (that’s 7 followed by 570 zeros).  Assuming the Universe has around 10^82 atoms in it, then there are 7*10^487 times as many paths in Hush Hush as there are atoms in the Universe.

That being said, that doesn’t mean there are 7*10^570 unique outcomes to Hush Hush.  Some paths collapse back together and often the choice you make for a job or skill doesn’t matter too much.  For example, there’s no difference between picking burgers at night and solar tech in the morning, versus solar tech at night and burgers in the morning.  But it does give an interesting insight into the magnitude of numbers in the game.Hopefully you found this interesting, and I hope you enjoy Hush Hush!

~Programmer Panda

How Hush Hush Works

There’s no denying that Hush Hush is a large game, with hundreds of thousands of words of dialogue and thousands of different user choices (leading to a bizarre conclusion that it’s very unlikely for any two people to play the game the exact same way).  To manage this we made heavy use of Google sheets for data entry and automation to verify the game could be played.  This blog post gives a quick tour of what the data in Google sheets looks like, and how Hush Hush turns all of that data into a game you can play!

It all starts with the action list, which is a big list of every event and phone message that you can get at each time slot.  For example, on the morning of July 2 here are the different events and phone messages that may be available to the player:

The game then needs to work out which of these to show to the player, which is what the ‘Trigger’ and ‘State’ columns are for.  Every line of dialogue and action has the possibility of setting a trigger to a particular state.  For example, when you first meet Iro the Iro_HasMet trigger is set to true.  These triggers are what instruct the game to follow certain branching paths or to make certain events available on the map.

For example, if Elle_HasMet is set to false on the morning of July 2 then that means that Elle Intro will be available (it is only available when Elle_HasMet is false), and Bonnibel Greeting random will be unavailable (it if only available when Elle_HastMet is true).  These same types of checks happen for every event, mini event, phone message, etc in a time slot, and allow the map to be populated with the various things the player can do.

When the player clicks on a location on the map the game now has to figure out which asset to load.  The asset name is stored in the ‘Asset’ column.  This name references a full sheet tab.  For example, ‘Elle Intro’ is found in the chapter 1 sheet under the ‘Elle Intro’ tab.

Each of these tabs has all of the information necessary to play the date, including any dialogue, branching, requirements, stat/money/etc updates, and so on.  The game starts at the very top of the file and reads from the top down, kind of like a movie script or book.  Each asset is broken up into different structures, and those structures allow for different behaviour in-game.  For example, the ‘Simple’ structure is just a few lines of dialogue followed by either a link to a new structure, or a list of questions that the user can use to branch to a new structure.  There are also more complicated structures, such as structures that loop until you pick a branching path that points to a new structure, etc.  Here’s an example ‘Simple’ structure from Elle’s Intro:

In this example, the Narrator will begin with the dialogue “(The girl shyly twirls her hair and smiles at you, before blushing and turning her eyes away.)”.  Then the player will be presented with 3 options:

  1. Hey, I’m sort of new to town. Actually I’m visiting for the summer.
  2. Hi. I’m super good at guessing names. Let me guess yours. Is it… Pinecone? 
  3. Hey girl. Your name must be Aerial, because I think we mermaid for each other.

Each of these options has a follow up line of dialogue from Elle, and then they all jump to a structure called ‘Elle_Intro_3’.

You may notice several columns that are empty in this sample structure.  Those columns allow the writer to lock certain paths behind stat/money/trigger checks, or allow the writer to modify stats/money/triggers depending on the path the player picked.

Once all of these assets have been written we need to validate them.  The Hush Hush project includes several tools that automatically process the game data and check for dozens of different types of errors.  For example, we check for triggers that don’t exist, triggers that don’t get changed, triggers that are only changed but never used, dialogue ids that are never used, incorrect or missing next ids, lines of narration that have a character name associated to them, and much more.  These checks happen every time new data is loaded into the game, so we can get a pretty good idea if the game will work before even playing it.

At the end of the day, all of that text in a spreadsheet somewhere turns into this:

I hope you enjoyed taking a look at how Hush Hush works behind the scenes!

– Sad Panda Programmer

Tools We Use

At Sad Panda we use many industry standard tools to build our games.  This blog post will go over the different tools used by our programmers, artists and contractors to build the content you see in Crush Crush, Hush Hush and our other games.

The programming team uses the Unity Engine for building the games.  The Unity engine leverages the C# programming language, and we use Visual Studio Code and Visual Studio Mac for most of our code creation.  We also use Xcode on Mac in some situations (usually for our iOS builds).  We use git for versioning control, and we use different applications for managing git.  For example, Programmer Panda uses git extensions.  When necessary, the programming team uses Paint.NET for image manipulation.

The artist team uses the Adobe Creative Suite for creating artwork.  Most of the artwork is vector artwork, made in Adobe Illustrator or Adobe Animate.  This artwork is then converted to flat images and edited in Adobe Photoshop.  Most of the artwork is placed on a network attached storage device and then shared via either Jira or Slack with the programming team for integration into the game.

The writing team uses Google docs, and most of our games have the ability to pull content straight from Google docs directly.

Lastly, the audio team uses Audacity for recording and sound manipulation.

Many of the programs we use are free and/or open source, which is great for a small studio like ours!  However, we do have to pay subscription fees for Unity and Adobe products.  It is worth mentioning that Unity does provide a free license to indie developers who are just getting started.  Hopefully this blog post has given you some insights into what a small studio uses for building games!

~Programmer Panda

What is an SPS ID?

Maybe you’ve gone to the MORE page from within Crush Crush and seen the SPS ID.  Or, perhaps you’ve e-mailed customer support and we’ve replied asking for your SPS ID.  Or perhaps you just seen the title of this blog post, and you too are wondering what an SPS ID is!  To arrive at the answer there is first a bit of history to unravel.

Some History

On February 9th, 2016, Sad Panda Studios launched its first game on Kongregate, Crush Crush.  We weren’t sure if the game would do well, and didn’t know how to service a game like Crush Crush.  A free to play game with new content, limited time events and frequent updates requires some infrastructure that a typical game.  For example, a typical game that you purchase a single time and play might never receive an update.  However, Crush Crush has been updated over 700 times, with major new content updates, bug fixes, events during holidays, and more.  To deliver this content efficiently, Crush Crush needs a connection to a server to get the latest art assets, events, etc.

With this knowledge in hand, and knowing that Crush Crush was a success, we took off to the 2016 Game Developers Conference in San Francisco.  Armed with his laptop, Programmer Panda approached several kiosks to discuss a solution to live servicing Crush Crush.  One kiosk stuck out, and that week Programmer Panda added PlayFab support to Crush Crush.  PlayFab allowed the Pandas to set news updates, store player sessions (important on the web!), hand out items to users, perform customer support, change store prices, set events, and more.

A typical player page in PlayFab

If you played Crush Crush around this time on Kongregate, you probably noticed the addition of a PlayFab ID on the MORE page.  Our customer support team would have asked for this information to restore a save file, etc.  PlayFab also supported the necessary server infrastructure for managing in-app purchases on Steam, which was helpful when we were scrambling to just keep up with content updates to Crush Crush.  Remember, we were only 3 people at the time, all of us with full-time jobs outside of Sad Panda Studios.

Migrating away from PlayFab

Over the months and years, PlayFab didn’t offer us all of the tools we needed to do our job.  It helped us when the game was new, but was now holding us back on the type of content and updates we could make.  We were already writing our own server software to support in-app purchases on platforms like Kongregate and Nutaku, and we had our own tools for customer support and save files at this time as well.  A decision was made to migrate away from PlayFab, starting in 2018.  Little by little, features that used to rely on PlayFab were relying on our own server software instead.  In 2018 both Crush Crush Kongregate and Steam dropped support for PlayFab entirely, and now work using our own server software.  In 2019, the Nutaku version of Crush Crush finally dropped PlayFab for user session storage, switching the last game over to our own server software exclusively.  Blush Blush, Hush Hush and Kitty Catsanova never used PlayFab, and have always used our own server software.

When you first install one of our games, a unique ID is assigned to your account.  That ID is your Sad Panda Studios ID (or SPS ID for short).  That ID will live with your account and should be the same ID across all of our games.  So, if you play both Blush Blush and Crush Crush on Steam, you should find that both games show the same SPS ID.  This allows us to enable features like the Panda Pass, which allows you to have inventory items across multiple game titles.  Cool!

A typical player page in our custom server solution

There are a lot of pros and cons when writing your own server software.  The obvious con is that any downtime is probably attributable to us.  It’s one extra thing we need to worry about, and something we need to plan for.  Maintenance?  That’s on us.  Server costs?  That’s on us too.  On the plus side, the server costs are much cheaper now that we have migrated away from PlayFab.  Another benefit is having full control of the data that we store.  We’re very keen on privacy, and we want to store only the information that is necessary for you to enjoy our games.  For this reason, we don’t log IP addresses, or associate your geographic information, IP, computer type, or any other personally identifiable information to your SPS account.  The only information we store is your account ID for whichever platform you are connecting on.  For example, if you connect on Steam, then we store your Steam ID so that we can link that to your SPS ID.

So, if anyone ever asks you about the SPS ID, you can confidently tell them that it’s a unique identifier used by Sad Panda to link your gaming account with your user data and inventory stored on Sad Panda servers.  It allows us to keep bringing you new content, new events and fun updates, hopefully for years to come!  Thanks for playing Sad Panda games, and we hope you enjoyed this blog post!

~Programmer Panda

How we deploy Crush Crush

This post was written by Programmer Panda!

Have you ever wondered how Crush Crush is built, how it gets uploaded for testing, and how it ultimately ends up on your device?  Then this blog post is for you!  Let’s follow a copy of Crush Crush from the Unity Editor all the way to Android devices all over the World.

Here’s Crush Crush for mobile within the Unity Editor:

Unity is a multi-platform game engine, and is what Sad Panda uses to make its games.  A single project can be deployed to PC, Mac, Linux, Android, iOS, WebGL and many other platforms, with reasonably minimal code changes.  The mobile build is a bit special, because it was made from the ground up to support a portrait orientation instead of a landscape orientation (the landscape orientation is still used on Steam, WebGL and Kongregate).

The first step is to prepare all of the asset bundles associated with this build.  The asset bundles and most of the art assets are stored in a separate project, to reduce the number of art assets in the main project.  This allows us to quickly switch between iOS, Android or WebGL platforms, which all share the same codebase.  Here’s what the asset bundle project for mobile assets looks like:

Yup, it’s pretty boring.  It’s just a bunch of art assets and a few scripts to build asset bundles.  We very rarely open this project at all, since building these asset bundles is automated during the build process, but I wanted to show it for completeness.  Here’s Unity building the asset bundles:

Now it’s time to go back to the Android project.  The Android project has some editor scripts that will copy over the correct asset bundles from the mobile assets project, and place them in something called the ‘StreamingAssets’ folder.  Anything located in ‘SteamingAssets’ is included with the final build.  This means that any assets in ‘StreamingAssets’ will end in the final apk (the Android application) that is delivered to Google Play, and ultimately your phone.  We only include the assets necessary to play the early parts of the game.  Once you unlock some characters (such as Peanut) the game will download those asset bundles from our server instead of relying on the ‘StreamingAssets’.  This allows us to keep the download size of the apk a bit smaller.  Right now, the apk is around 50MiB, and we have plans to reduce this further to under 40MiB.  Not bad!

Any assets not included with the ‘StreamingAssets’ folder are uploaded to our website, and are cached by our CDN (CloudFlare) so that they can be served quickly to anyone playing the game that needs them.

Once this is done, we can actually build the apks for the Android version of the game.  Again, this is all automated on our build server, but I’ll show some pictures of how this looks running in my local copy of the Unity Editor.  From the ‘Build Settings’ menu we make sure that Android is selected as the build target, and that the correct scenes are included.  We have both landscape and portrait versions of the game, so the correct scene is very important!

Then we hit ‘Build’, and the waiting game begins.  We build multiple versions of Crush Crush when targeting Android.  One version targets 32 bit devices, and another version targets 64 bit devices.  Unity allows you to either make a single universal apk (which has the code for both 32 and 64 bit devices), or you can export each device type separately.  We choose to export them separately to keep file size lower, since including both copies of the code inflates the apk size by about 8MiB or so!  This can make a big difference when you’re downloading the game over cellular data.  We don’t want anyone to get a data overage charge because they wanted to play Crush Crush!

The build process takes about 5 minutes on my personal computer, and a little bit longer on the build server.  Once the build is complete, we have a folder with two apk files, which are ready for upload to Google.

The Google Play dashboard has several options for managing the release of a new version of the game.  There is an internal test track, a closed alpha track, an open beta track (where people can opt in to play a beta version of the game), and finally a production track (which is the version of the game that is live to everyone on Google Play).  We start with the alpha track, which has a list of test users (mostly studio employees).  Here we can upload the new apks we just created, and deploy them to our test users:

Normally, we’ll test this for several days.  We want to make sure that the transition to a new build is as seamless as possible for our players.  We have a full battery of tests we run against all of our builds before they go live, and Support Panda is in charge of signing off on those QA tests.  Once we are happy with the build, we can set it live on the production track as well.  Google does allow us to select a rollout percentage, and we normally start with something like 5% or 10% to ensure there are no major issues.

Then there’s nothing to do but watch the stats roll in (and sometimes to wait for Google to process the update, which can take up to 8 hours).  We use Fabric (recently acquired by Google, of course) for crash diagnostics.  Fabric allows us to see the deployment percentage of different versions of the app.  We’re pretty impressed with how quick most people update their devices!

If we did everything properly, and tested everything well, then the update process should be stress free, with minimal issues for our players (and for us).  The whole process takes about a week, and is similar(ish) for our other platforms.  We have, in the past, been able to hot fix a bug on Steam in less than half an hour, but we don’t want to make a habit of it!  Hopefully you enjoyed this look behind the scenes at Sad Panda Studios.  Thanks for playing our games!