[MUSIC PLAYING]
PATRICK MARTIN: Hello, Android games devs.
I've been making games long enough to remember the days
when I could just spend a year in production,
spin off a gold master, and kick a game out the door to start
focusing on something new.
This just isn't the case anymore.
Especially in the mobile space, you'll
be competing with literally hundreds
of new games every day.
To be successful and stand out in the crowd,
you need a really awesome game that your fans
love and will keep talking about long after you
click that Publish button.
That is you need some way to be able to operate
your game once it's live.
But this can be a lot of work.
First, you need to figure out what your players think
of your game, what they like and don't like,
where they're stuck, and how your game might improve.
Then, you need to be able to roll out changes
to your player base based on these insights
and decide if you're going to keep them.
And this needs to happen fast, which can be challenging
for C++ and Unity developers who can't just published new code
to their servers at a whim.
This is why I'm here talking about Firebase, a development
platform that helps game developers build games
with backend tools, like Firebase Realtime
Database and authentication, release games
with live monitoring tools, like Crashlytics and analytics
and operate games with tools like Remote
Config and A/B testing, which I'll be talking about today.
So let's see how I can monitor the behavior of my live player
base, roll out a change, and measure
how successful that change is all
with free tools in the Firebase suite.
I found this really cool demo project for our mobile game
and started building on top of that.
If you want to follow along at home,
there's a link in the description below.
I've made a couple of changes already.
I added a quick title screen where I initialize Firebase.
That way, I can ensure that check and fixed dependency
is async, was called before I used Firebase features.
This includes Remote Config.
And I log an event when a user dies with how many points
they've earned and how long the round took.
I've already hooked up Google Analytics via the Firebase SDK.
And this is my Analytics dashboard.
I can see key stats such as my daily user engagement,
retention reports that even be able to see my revenue reports
here if I had AdMob set up.
I also have game over event with the data
I'm logging on player depth.
Of course, if this is all new to you,
you should check out this Getting Started Video
for Google Analytics and Unity.
I cover how to log events, how to track key performance
indicators, and way more about this Analytics dashboard.
Thanks to this data, I can see how my players are doing
and build a hypothesis about how to improve my game.
For example, here, I see that players
are playing for 6 to 12 seconds and not
getting much more than 1 point on average.
Maybe they'll stick around longer
if I gave them really big scores.
And if they stick around longer, maybe I'll
be able to make some money with super cool in-app purchases
I've planned, like the Chicken Launcher.
If I'm going to start testing my hypothesis,
I need more control and faster iteration times
then I'd get from just submitting this
to the App Store.
So I'll pull in something called Firebase Remote Config.
You may be asking, what is Firebase Remote Config?
Really, it's just a very bandwidth-efficient key value
store that lives in the cloud that
has fairly robust controls over which users get
which pieces of data.
You'll generally want to pull most tweakable and configurable
bits of gameplay into it.
So let's do that.
First, I'll add the Remote Config Unity SDK.
Now, most of the interesting bits in the sample
are in a class called GameControl.
So I'll open that up.
And here, I have scroll speed.
That is how fast the game goes and score++ and Bird Score
for how many points I get.
Let's Remote Configify this.
First, I'll make serializable private fields
for both the scorer and the scroll speed.
Then I'll make constants for what their keys will
be in Remote Config.
At the end of a wait, I'll create a dictionary
with each of these values and use that to set the defaults.
At this point, I have values configurable
in the Unity Editor by making a couple of public accessors
that call GetValue on Remote Config.
The game is right back to where it was when
I started with extra steps.
First, I went to verify that nothing changed.
And now, it's time to hook up the magic.
That is, I'll call FetchAsync so these local defaults can
be replaced with server values.
To activate the fetch values, I'll
call ActivateFetch on the main thread when this completes.
If I want to get crafty, I might hold onto this
until the end of the frame to make sure everyone's operating
on the same data or even wait until a scene changes
so nothing changes on players mid game.
I note that at this point, you're
dying to see how you can push a change down from the server
like I promise.
But something to be cautious about
is that Remote Config has the potential
to push a changed live to all of your players.
One way to lock down a change to specific players
would be to use user properties in Google Analytics--
user properties that you categorize your players
based on criteria of your choosing.
So you might set a property for when
users reach a certain level.
To identify certain players as admins or GAs
or to save what a player's favorite food is.
It's really important to know whether or not
an affinity for waffles is correlated with higher scores,
right?
In the case of Remote Config, I'll
be able to deliver certain configurations to players
who match a qualifying criteria based on a user property.
Just be a little cautious with user properties.
You only get 25 of these per project.
So you probably don't want to give each of your developers
their own property.
Note that until this point in this video, everything
I've done has been testable in the Unity Editor.
Analytics will be the exception, though.
And since recent versions of Unity
no longer support the Android emulator,
anything involving analytics has to be run on a physical Android
device.
The upside, though, is that thanks to Remote Config,
once I get the integration working,
I can test gameplay changes on a game that's
physically running, potentially actually
improving your iteration times despite this restriction.
This is one reason why I moved everything
interesting into game control and Remote Config.
So if I go back to game control, I'm
going to use Debug.IsDebugBuild to determine
if I'm developing the game.
First, I'll create a constant string for my developer user
property.
And I'll jump over to the Firebase dashboard,
select User Properties, and copy, paste it here too.
Then I'll set the user property to match IsDebugMode.
Remember that since I only get 25 of these,
if I want each developer on my team to have their own config
values, I would want to use a single user
property with a string or ID rather than making
an individual Boolean for a developer.
If this is a debug build, I'll also
set FirebaseRemoteConfig.settings
IsDeveloperMode to true so I can pull down data quickly.
Finally, this is a debug build.
I'll drop the update timespan to zero.
This will allow me to make as many fetch calls
as I need when developing, which will
be important for tuning these value.
Typically in production, you'll want to update your data once
every 12 hours or so.
It will cap out at something like one update per hour.
But up to 10 developers on your account
can retrieve data as frequently as needed.
So now, my game is set up to change the point values based
on a Remote Config setting.
And we'll update this as frequently as needed
in development mode.
Let's go put up some test data.
If I build and run this on device,
I should see that I'm still getting 1 point per pullar.
So I'll go into the Remote Config dashboard, Can
copy my default values up here for like-- but since this will
replace whatever I have set up in the editor,
I'll only do that as needed.
There's also some sample code in the Firebase extended repo
that you can use to set Remote Config values
right in the Unity Editor.
I'll put a link in the description below.
So I'll create a condition for Developer mode.
And for developer, I'll set the score to something big,
like 100.
You get 100 points per pillar, and also 1 point
for normal players.
And Publish.
I'll make sure I switch to the development
build if that's not already configured.
I'll launch my game and see those changes instantly
on device.
I can even add a button to make fetch happen if I want.
That's so fetch.
If you recall, my hypothesis at the beginning of this video
was that players in my game would like it better
if they had bigger scores.
So now that I can update scoring on the fly,
I need some metric to say, hey, they do like it better.
I think that I'll want to see an increase in my two-to-three day
user retention.
That's one of those metrics that I just
get for free after integrating Google Analytics.
So let's do some science.
Naively, I can apply a remote configuration
to some percent of my player base.
But we can do better.
Firebase actually has a product called A/B Testing.
I'll just scratch the surface here.
But check out our A/B Test Like a Pro Series to really dig in.
Link in the description below.
Here, I can create an experiment to measure if more points leads
to better retention.
I'll say that I want to use Remote Config.
I'll name the experiment Bigger is better!
And add a description, like Bigger numbers
are likely to increase user retention.
I'll target players in my Android game, say, 5% of them.
And I could have an activation event
that's required to qualify a player for this test.
But that doesn't apply here.
My goal will be to drive up two to three-day retention.
And you can see that I've pulled in four to seven-day retention
automatically, as well as a metric measuring my game
stability as secondary metrics.
My control will be my current default--
a score propeller value of one.
My variance will be a score of 100.
I'll review and accept this experiment
and wait some time for data to start rolling in.
So for a normal game, now, I'd be
able to grow out my test and my player base
and see how it's received.
Unfortunately, this is a small demo game
that I've made just for this video.
To use A/B testing effectively, you'll
need a sizable number of testers in order
to have a reasonable amount of confidence
that the test results will scale.
5% of this player base might not even pull in one person.
I already know that I want a bigger scorer.
Luckily, we have this game Bingo Blast running live.
And we've done a few A/B test of our own
against the player base.
So let's take a look at this test
that we call Rewards and ad revenue.
Basically, Bingo Blast has something called rewarded ads.
These are ads that a player can actually watch
in lieu of spending real money in order
to earn some premium currency.
Balancing the amount of currency you
give a player can be difficult. Too much,
and you risk sacrificing in that purchase revenue.
But if you don't reward enough, your players
won't bother to sit through the short video.
And you'll lose potential ad revenue
from non-paying customers.
The thing about this test is that I've been in this meeting
or trying to balance various methods by which
players can earn or buy in-game currency without testing.
You're just gambling with your game's future
and with the literally hundreds of design and engineering hours
you spent getting to this point.
But thanks to A/B testing, we have another option.
If I expand the details here, you
see that our hypothesis is that giving a player more chips that
is more premium currency will encourage
them to seek out rewarded ads and drive up
our estimated AdMob revenue.
That is we'll make more money from ads.
I also want to see what happens to our four
to seven-day retention.
It's useful to know if somehow our game gets crashy.
And I want to see what happens to our total revenue.
Remember that the balance I want to strike
is that I don't want to break our holistic monetization
strategy by giving away too many chips to non-paying players.
The target audience is 25% of our Android users.
And we're splitting that 50/50 between the control group, who
gets 10 chips per ad in the experiment with 20
chips per ad.
Of course, the results are already
spoiled by the headline.
But down here in the improvement overview,
I see that we're significantly increasing our AdMob revenue.
47-day retention is also up where
users are actually crash-free, although, I don't quite
know why.
And the total revenue is up a slight tick.
For our Android users, at least, I
can say with science that 20 chips per rewarded ad
is the way to go.
But an important note.
This video is about improving your life operations, not
the best way to monetize your game.
Remember that your audience may have different preferences
than ours and that the willingness
to watch an ad versus spending money
may depend on platform, region, or some other selector.
So don't just lift these numbers,
even if 20 chips is something meaningful in your game.
But run this experiment yourself.
The tools I used here are all freely
available from the Firebase suite.
That means that no back in cost to you.
And with a few minutes of coding,
your engineers can build a powerful live remote deployment
system into your game that helps even
non-technical decision-makers interact with your living
player base.
This doesn't just stop at testing though.
You can use this to slowly roll out new features, nerf
that power up to analytics indicates is a little OP,
or even as a quick and dirty way to set up a double XP weekend.
And since this is all configurable in the Firebase
console, you're not stuck waiting for your engineering
team to cut a new build even for that spur of the moment XP
event.
Once you have the proper Remote Config hooks implemented,
it's just a matter of setting the correct keys in the Remote
Config dashboard or using the Admin SDK to tie
into your own bespoke tooling.
That's all I have time for today.
If you'd like to learn more about Firebase,
check out our YouTube channel, link in the description
below, or follow @firebase on Twitter.
There's also a playlist for all of our Unity videos
also linked in the description.
And don't forget to let me know what you're
building either in the comments below or @pux0r3
on the Twitter.
So long and have a wonderful time.
[MUSIC PLAYING]