# Kongregate Developers

## From a Dev: Optimizing Ad Revenue Through Gameplay Experiences

The following article is meant to highlight Ultrabit’s experience with ads and how we integrated them into our core gameplay to drive meaningful revenue. I will be speaking primarily about our latest title, Pocket Politics (iOS and Android, July 2016). Although Pocket Politics sits in the idle/incremental genre, we believe ads can drive meaningful results in almost any game category.

This will not be an exhaustive examination of all ads ever; instead, it is a single illustration of how we’ve found success with our current approach. If you haven’t thought about how ads might help drive more revenue from your products, we hope the below encourages you to explore ads as a secondary means of monetization. If you are already seeing gains from your current ad implementation, we hope you come away with ideas on how to further optimize.

Why do we care so much about ads?
Ads serve as a major pillar of revenue for Pocket Politics. At any given time we make 40-50% of our daily revenues from ads, which has proven especially significant at scale. Given enough users -- through user acquisition, re-featuring, cross-promo, etc. -- we end up with a sizeable amount of free players contributing to revenue that would otherwise not monetize.

What kind of ad metrics do we pay attention to?
The two key metrics we examine are the percent of daily active users watching at least one ad (%DAU engaging) and the number of ads watched per user per day (ads/DAU). Of the two listed, we find it more important to optimize %DAU engaging because you typically get paid more money for the first ad the user watches vs. their tenth. For reference, Pocket Politics currently lands around ~60% for %DAU engaging and ~5-10 ads/DAU; it should be noted that we run limited timed events which can spike ads/DAU -- more on that in a bit. For more information on why it is important to track ad metrics, see Kongregate’s Jeff Gurian’s post “Ads Count, So Count Your Ads.”

How about some specific examples/tips of how we’ve moved these metrics?
Certainly, move to next section.

Tips and Tricks
When Pocket Politics was moving through test markets, we were concerned about ads/DAU given we were clocking in around ~3 ads/DAU (in our opinion, target area is anywhere between 5-8 ads/DAU). Our %DAU engaging had always been relatively strong, so we didn’t try and move that metric too much until recently (no data to report on yet). That said, following are some key takeaways from our live operations that have proven useful in moving ads/DAU.

• We made the core ad stackable. For each core ad you watch we add 4 hours of “+200% production bonus” time and cap the player at 6 ads per day (i.e. 24 hours of bonus). Our original implementation required the user to log in and watch an ad every 4 hours, which depressed ads/DAU because we were restricting the user by their play session frequency. Instead, we made a change that allowed players to effectively “stack” all 24 hours of bonuses by watching ads whenever they wanted; e.g. some players stacked all 6 ads on their first play session each day, while others might do 3 ads on their first session and 3 ads on their second session.
• We added in a variety of different ad bonuses throughout gameplay (we call these “ad hoc” ads internally). There are a number of different ways to do this, but our approach was to focus on key areas of the core loop. For an idle game, the core is about increasing current rates of production or getting large resource allocations in preparation for a prestige loop (e.g. getting ready to restart the game with an additional bonus based on current production/accumulated resources). We implemented ads for when the user won an election (resource allocation); when a user returned from a long offline period (resource allocation); we made a special kind of ad available every 4-6 hours that could provide time warps (resource allocation), super-powered taps (production), super-powered one random resource generator (production), and even premium currency. With all of these different avenues -- all optional for the player -- we saw a general increase of ~2 ads/DAU, up to the desired 5 ads/DAU. You can see the lift as part of Figure 1 below (everything non-blue falls into this category of “ad hoc” ads).
• We integrated similar ad bonuses into our limited timed events. We launched our first event at the beginning of August 2016, and as you can see from Figure 1, events end up spiking our ad views. We offer the same ad bonuses/buffs within each event, and find that users engage with both sides of the game while the event is live (i.e. they continue to keep their core game ad bonus up while simultaneously working through the timed event).

Figure 1. Ads/DAU by Type

Any other takeaways or learnings?

• Make sure ads impact the core loop (i.e. they have value). Players will learn what ads are worth the trade in time and attention, and will engage accordingly.
• Make sure to provide multiple ad opportunities across each play session and at every stage of the player’s life cycle.
• In our opinion, make the ads optional. We would rather have players retain and potentially monetize in the future than hit a nasty interstitial in the middle of a play session. Opt-in allows the player to make a choice at their own convenience.

Thank you for taking the time to learn a little bit about how we use ads as part of our core gameplay in Pocket Politics. If you would like to learn more about how other games in Kongregate’s portfolio have leveraged ads, please see Tammy Levy’s article titled “Best Practices: In-Game Ads.”

### Author

#### Cooper Bachman

Cooper is the General Manager at Ultrabit, a San Diego-based game studio acquired by Kongregate in February 2016. Away from work you'll find him reading sci-fi or fantasy novels, binge watching the newest Marvel Netflix series, or watching live stand-up comedy.

## Kongregate's 10-year Anniversary Celebration!

We're celebrating our 10-year anniversary with a bunch of community- and developer-appreciation activities throughout the month of October! Tune in for a Game Jam, a chat update that includes Kongpanions, art contests, and more fun activities. There will also be a Reddit AMA (“ask me anything”) session where players can ask questions about the 10-year history of Kongregate.

To close out the month’s festivities, several Kongregate employees will participate in an Extra Life charity event on Saturday, November 5 to raise money for Children's Miracle Network Hospitals. The event will be live-streamed, so players can watch Kongregate employees playing the hottest mobile, PC, console, card, and board games.

Over the past decade, we've hit some awesome milestones:

• 30,000+ game developers supported (from 100+ countries)
• 110,000 games uploaded
• 315 Million badges earned
• Over 70 million play sessions in our most-played web game (Dawn of the Dragons from 5th Planet Games)
• 15.5 million global downloads in our most-downloaded mobile game (AdVenture Capitalist on Android and iOS)
• 9+ Million forum posts
• 55+ million "friendings"

It's been an absolute blast -- here's to 10 more years!

## The Math of Idle Games, Part I

I’ve given a few talks in the past about the appeal and general mechanics of idle games, but what if you actually wanted to make one? Theory and patterns are nice, but there’s some complicated math running behind it. And how on earth do you balance a game that has insanely large numbers?

This article is Part I of what will be a three-part series detailing topics covered in my most-recent talk. Part I discusses core ideas of growth, cost, prestige, and generator balancing. Part II will look into alternate growth methods (especially derivative-based). Part III will look at prestige cycles and balance.

The models for all of the charts produced in these articles are available as spreadsheets. Please feel free to duplicate, peruse, experiment, extend, etc.!

Let’s start by specifying some terminology to make talking about this easier.

• Primary Currency: This is the main number that is being incremented, generally the goal of the game. Usually it’s some form of money.
• Generator: The items in the game that produce primary currency. The rate of production, or income, is measured as currency per second.
• Primary Exchange Currency: In some cases generators produce a different currency that is exchanged for primary currency. For example, in Clicker Heroes the generators produce DPS, which is then converted into gold by killing monsters. That layer of separation can give you a bit more control over the growth of the primary currency in the game, since you can modify the “exchange rate” over time.
• Multiplier: Any of a variety of upgrades that multiplies your generator power. These can be explicit upgrades, based on number of generators owned, etc. Their purpose is to (temporarily) get production closer to, or ahead of, costs.
• Prestige: A reset of most elements of the game (especially generators and multipliers), but gaining currency (prestige currency) and/or persistent multipliers to accelerate the next time through. Similar to a “New Game+”.

At the most basic level, idle games are a seesaw between production rates and costs. Early on in a run, your production will exceed costs while eventually costs will become prohibitive. This is typically accomplished by having costs grow exponentially while production grows at a linear or polynomial rate. To put that into formulas:

$cost_{next} = cost_{base} \times (rate_{growth})^{owned}$

$production_{total} = (production_{base} \times owned) \times multipliers$

With AdVenture Capitalist Lemonade Stands, the $rate_{growth} = 1.07$, $cost_{base} = 4^*$, and $production_{base} = 1.67/sec$. So if you own 10 Lemonade Stands:

$cost_{next} = 4 \times (1.07)^{10} = 7.87$

Meanwhile, the production rate is:

$production_{total} = (1.67 \times 10) \times 1 = 16.7 / sec$

$^*$It’s technically 3.738, since you get the first one for free and it’s actually the second one that costs 4.

Here are the actual values for AdVenture Capitalist (thank you AdCap wiki!):

So early on you’re earning well beyond the cost of a new generator every second. Let’s look at that in graph form. Note that when you own 25 and 50 Lemonade Stands, the rate gets a (stacking) x2 multiplier.

And we can see a slightly bigger picture if we use a log scale y-axis.

Early on, your production rate is high and you can keep buying, and the multipliers bump you back up whenever it gets close. But eventually the costs become overwhelming, and the time you would have to wait to be able to afford the next generator gets prohibitively long.

Mathematically, exponential growth (anything of the form $n^x$, for $n > 1$) will eventually catch and far exceed any polynomial growth ($x^k$) no matter how big $k$ is or how small $n$ is. This can take a very long time in some cases, but that’s where balancing comes in. (If you want a great overview about tiers of quickly growing functions, check out this post by Eclipse1agg, the developer of True Exponential.)

In this example, once things really start to slow down, you would be looking to do a prestige to multiply your production rate. Doing that looks like this, with each successive prestige sliding up on the graph. The result is that each prestige allows the player to get farther through the cost curve before falling behind.

But that’s for a single generator. What happens when you have multiple generators, each with different costs and rates? Now the player has choices about what to invest in, and things get more complicated. Fortunately, we can model optimal behavior too! In this model we define “optimal” as having the best income:cost ratio, and we determine that at every purchase opportunity.

Players aren’t going to follow this exactly because the optimal choice will often be far too micromanage-y for a human. "Buy one Generator 2, then three Generator 1s, then a Generator 3, then another Generator 1," etc. Instead, players usually buy in bulk to simplify the decision process...or to be super OCD (always keeping at multiples of 100). But over the long run, players will roughly be in this ballpark.

Here’s what it looks like for the first 5 generators in AdVenture Capitalist, with x2 multipliers kicking in when you own 25 and 50 of a generator. You can see the expected spikes in purchases right around 25 and 50 multipliers kicking in, since those are temporarily overvalued. Note: this model simplifies income to be per-second instead of requiring a timer to complete, so higher-end, slower generators get over-favored.

If we look at a log scale of income rates, though, you’ll notice that the newest generator is nearly always dominant once it can be purchased. That’s not very interesting for the player, though. It means that older generators are largely irrelevant and removes any interesting decisions. Even if smaller generators are technically “optimal,” they may not matter. For example, it may be that you can buy a lemonade stand that generates 10 currency/sec for 5 currency or a car wash that generates 10,000 currency/sec for 7,500 currency. Lemonade is a better deal, but as a player you’re not going to “feel” the impact and so it doesn’t seem worth purchasing, or perhaps more accurately not worth the effort to consider purchasing.

However, even with a simple model like this one, we can start to emulate the shifting priorities of the various generators. In the above image we don’t have any purchasable multiplier upgrades, and every generator gets the same multiplier count bonuses shown in the table below (only Gen 1 hits 100):

If we modify these numbers and keep everything else the same (including still not having any purchasable upgrades), we can create a very different picture. We’ll use these multiplier values instead:

And here’s the resulting income graph:

Now that’s much more interesting! As you progress through the game, different generators take priority and have the biggest impact on income. The player gets to try to identify these priorities (they won’t always be obvious right away), and this provides more variety and less predictability. And if you have purchasable upgrades, you have even more options for providing this sort of variation for the players.

BONUS CONTENT!

While putting all this together, I derived two very useful formulas that will save you from brute-forcing with some lengthy for-loops. The first will calculate the cost of bulk-buying generators, the second will calculate the max generators you can buy with your current funds. These will only work for simple exponential growth that doesn't have shifting costs or exponents, so make sure your particular application works for it. For both of these, the variables are:

$n$ = the number of generators to buy
$b$ = the base price
$r$ = the price growth rate exponent
$k$ = the number of generators currently owned
$c$ = the amount of currency owned

$cost = b * \frac{r^k(r^n-1)}{r-1}$

$max = floor(log_r(\frac{c(r-1)}{b(r^k)}+1))$

Or, if your language can't do a non-standard $log$ base, you can use a standard $log$ or $ln$ and divide it like this:

$max = floor(\frac{log(\frac{c(r-1)}{b(r^k)}+1)}{log(r)})$

(For those who are curious, all formulas in this post were created dynamically with an embedded script called MathJax that lets you render LaTeX or MathML very easily and cleanly.)

If you have questions, find a bug, decide to make an extension to a sheet, or have an awesome new idle game you want to share, please feel free to reach out and email me at anthony@kongregate.com.

### Author

#### Anthony Pecorella

Anthony has been at Kongregate for 7 years and is the director of virtual goods for browser games. He works to bring great games to the platform and help developers make a living with their games. He was the lead producer for the mobile version of AdVenture Capitalist.

Anthony also designs and develops games on the side with his indie game studio Level Up Labs, including the acclaimed tower defense RPG Defender's Quest: Valley of the Forgotten, and a MacArthur-grant-funded educational biology game, CellCraft.

October 4th, 2016 11:11 1 Comments

## Dealing with the 64K Method Limit in Your Unity3D Game

dex limit.md

Could you ever imagine a Unity Android game that used more than 64K Java methods? Neither could the architects of the Dalvik bytecode. Perhaps they did (I haven’t read the spec) and the blame falls on other elements in your toolchain. The long and short of it is if your game taps against the 64K method limit per DEX file you’re going to need to get down and dirty with your native plugins and/or build workflow. This post will attempt to walk you through the various ways to deal with it.

## First Things First

There’s no shortage of forum posts and blog entries on this subject. The most important takeaway is if you can manage to keep your game comfortably below this number, you will save yourself a lot of trouble.

### Know Your Plugins

The most common way to hit this limit in Unity is through the use of native plugins. Android native plugins are a necessity for almost all Unity games. Unfortunately, some plugins are quite large. Google Play Game Services, for example, is close to 25K methods on its own, a significant chunk of the 64K you are allotted.

### Super Brief Anatomy of Unity Android Plugins

Unity Android Plugins typically consist of some C# Unity code along with native Android code and resources. The native code and resources will be packaged either as an Android Library Project or Android Archive (AAR) under the Assets/Plugins/Android/ directory. Library Projects are the old way of sharing components in the Android ecosystem and AARs are the newer way. You will find plugins that use both.

The classes in both Library projects and AARs exist in JAR files, which are simple zips of compiled Java class files. The AAR file is also simply a zip of various Android resources, some of which will be libs/*.jar (a.k.a. Java class archives). Library projects are simple directory structures, and again the JARs will be in libs/*.jar.

## Steps to Minimize Method Counts

The only way to reduce the number of Java methods included in your game's APK using the standard Unity build system is to remove or modify the JAR files included with your Android native plugins. The alternative is to export your Unity Project as an Android Project where you can apply more advanced techniques.

You should try each of the following techniques in order:

• Remove any plugins your game is not using
• Since Google has broken Play Services into a set of modules, only include the ones you actually use.
• Use the Jar Jar Links tool with the zap rule to remove unneeded classes from the plug-ins JARs. You could also simply unzip, delete unused classes, and rezip the JAR.
• Export your project as an Android Project so you can apply ProGuard or MultiDex. This is where things get dicey.

Most of this blog post will focus on the last bit because, at the time of writing, there aren’t a lot of resources that walk you through this approach. Exporting as an Android Project will be more disruptive to your development and build cycle. Until ProGuard or MultiDex are directly supported by Unity, you're best off going down this path as a last resort.

### What to Look for When Testing

Once you have your game under the 64K limit and are able to generate the APK again, the key thing to look for while testing your game is ClassNotFoundException and VerifyError errors in logcat. This indicates your code is trying to use some class or method which is unavailable. Usually the error will be associated with a crash, so it’ll be quite obvious. Sometimes, however, the plugin may attempt to fail gracefully and, though your app does not crash, some feature you hope to be available will not function as expected.

## ProGuard and MultiDex

ProGuard is a tool used to obfuscate and trim unused classes and methods. MultiDex is technology that enables multiple DEX files within your APK, thus removing the 64K method limit for your game. Unity does not have direct support for either of these techniques, but you can make use of them if you export your project to an Android Project.

When all else fails, ProGuard will hopefully bring you below the limit. If not, you can turn to MultiDex. MultiDex has the added strike of only working in API Level 14 (4.0) and up. It is natively supported in Android (5.0) and up. Support libraries must be used for 4.X. Finally, MultiDex comes with a set of Known Limitations.

## Exporting to an Android Project

If you need to use ProGuard or MultiDex, the first step is to export your Unity Project as an Android Project. Depending on the complexity of your Project, this in itself can be a daunting task. It also likely means no more Unity Cloud Build. When done correctly, however, it can work similarly to exporting to XCode for iOS. The Android Studio or Gradle project will need to be set up after the export, but this should be a one-time task. You will be able to re-export your project without having to set up the Android build configuration again.

I’ve found three ways to successfully work with a project exported to Android. I’ll briefly cover the first two because they are simpler and may be preferable if your project is not too complex. The last approach requires a little more manual setup, but is probably the cleanest way to organize your project. It also may be your only option if you need MultiDex.

### A Few Words of Caution

Even after exporting your game to Android Studio, it’s possible that the plugins your game uses depend on Unity Post Process scripts that will not translate to Android Studio or Gradle builds. You may still hit a dead end.

## Approach 1: Simple Unity Export/Android Studio Import

This approach will work for games that do not use too many plugins. I imagine Unity and Android Studio will continue to improve this approach.

1. Under File -> Build Settings -> Android click the Google Android Project checkbox and the Export button. Create/Choose a directory to export. Android would be a good choice.
2. Open Android Studio and choose Import project (Eclipse ADT, Gradle, etc.). Navigate to your exported Unity Project, which will be a subdirectory of your export directory (e.g. ./Android/Your Unity Project).
3. You will need to choose a destination directory. You may leave the various checkboxes checked.

At this point, if all goes well, you should be able to run the project within Android Studio.

### Pros & Cons

• Pro: It’s simple.
• Pro: The imported Android Studio project is also a standard Gradle project, allowing easier integration of Gradle-based tasks.
• Con: Every time you export from Unity and import into Android Studio, a brand new project is created. Any manipulation you need to make to the studio project – for example, configure ProGuard – will need to be done every time you build. This would pretty severely impact your development cycle.
• Con: Depending on the complexity of your project, it simply may not work without significant modification to the Android Studio Project.

## Approach 2: Import the Exported Unity Project from Source

In this approach you directly import the exported Unity Project into Android Studio from sources and then manually update the various modules and dependencies. The difference from the first approach is rather than importing /Android/Your Unity Project, you import /Android, and Android Studio will attempt to set up modules for your main application and each exported library project.

The nice thing about this approach is that once you have the Android Studio project set up, you can re-export the Unity Project to the same location and in general will not need to update Android Studio Project.

The downside to this approach is that your Android Project will be tied to Android Studio Project files. Configuring and managing the dependencies will be a challenge.

Since I’d like to focus on the third approach, I’ll simply say once you have your project in Android Studio, it isn’t too difficult to enable ProGuard. However, the process of setting up the Android Studio Project involves correctly configuring each of the modules and dependencies using Android Studio’s UI. Depending on your familiarity with Android Studio project modules, this could be a tricky task. Further, I found getting MultiDex configured through the Android Studio UI challenging, which led me to the third approach.

## Approach 3: Configuring a Gradle Project for an Exported Unity Project

Gradle is the build tool Android settled into a few years back. Android Studio Projects may be synced with Gradle Projects. Though old Android Studio Project modules are still supported, new projects are based on Gradle files. In this approach we correctly set up the Gradle files for the exported Unity Project, at which point we can either work with them and build from Android Studio or from the command line. We are given access to useful Gradle tasks such as ProGuard and MultiDex.

### Set Up the Gradle Wrapper

In the directory where you exported your game, set up the Gradle wrapper with the following command:

gradle wrapper --gradle-version 2.14.1


Gradle comes with Android Studio, so you should have some version of it installed. The above command will create a gradlew script that will lock your build script to a specific version of Gradle. At the moment 2.14.1 is a good choice.

### Create Root build.gradle file

In the same directory, create your top level Gradle file build.gradle. You may simply copy and paste the following:

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.0'
}
}

allprojects {
repositories {
jcenter()
}
}


### Create Your Application build.gradle File

Place the following file in the main project sub-directory created for your Unity Project under your export directory (e.g. Android/Your Unity Project). This file also must be named build.gradle.

apply plugin: 'com.android.application'

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}

android {
compileSdkVersion 24
buildToolsVersion "24"

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}

debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}


### Create Your settings.gradle File

Back in the root directory of your exported Android project, create a settings.gradle file with the following contents. Of course, replace :Your Unity Project with whatever the directory Unity created for your exported project.

include ':Your Unity Project'


At this point, if you had a super-simple Unity Project with no plugins, you should be good to go. Within Android Studio you may choose Open an existing Android Studio project. Navigate to and open the settings.gradle file you created and work with your project within Android Studio. You may also build your project from the command line like so:

./gradlew assembleDebug


You can see the complete list of Gradle build tasks with:

./gradlew tasks


### My Project Wasn’t That Simple :(

Chances are if you are reading this, it’s because your project wasn’t that simple. When you export from Unity, in addition to a main app directory (e.g. Android/Your Unity Project), it creates a directory for each library project and AAR used by your native plugins. For the AARs, they were extracted into Library project format.

Add the following file for each library project subdirectory created by the Unity export. Again, name this file(s) build.gradle

apply plugin: 'com.android.library'

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
}

android {
compileSdkVersion 24
buildToolsVersion "24"
publishNonDefault true

defaultConfig {
minSdkVersion 9
targetSdkVersion 24
}

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}

debug.setRoot('build-types/debug')
release.setRoot('build-types/release')
}
}


Next, back in your settings.gradle file, add include rules for each subdirectory.

include ':appcompat'
include ':google-play-services_lib'


Finally, back in the build.gradle file for your main application (e.g. Android/Your Unity Project/build.gradle), update the dependencies section to include the library projects.

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':google-play-services_lib')
}


### Resolving Dependencies

In some cases, you may have one library project that depends on another library project. For example, this output is shown because the MainLibProj module depends on Google Play Game Services.

.../MainLibProj/build/intermediates/manifests/aapt/release/AndroidManifest.xml:31:28-65: AAPT: No resource found that matches the given name (at 'value' with value '@integer/google_play_services_version').


There is no hard and fast rule to interpret these dependencies, but in general, the name of the missing resource gives you a pretty good clue. For this case, google_play_services_version pretty clearly points to the Google Play Game Services. We can use grep to figure out which of the Google Play game services modules contain this value.

grep -r  google_play_services_version .
./MainLibProj/AndroidManifest.xml:            android:value="@integer/google_play_services_version" />
...
./play-services-basement-9.4.0/res/values/values.xml:    <integer name="google_play_services_version">9452000</integer>


We see the resource is defined in play-services-basement and referenced by MainLibProj. Open up <export_dir>/MainLibProj/build.gradle and update the dependencies entry like so:

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':play-services-basement-9.4.0')
}


Now Gradle knows the MainLibProj module depends on play-services-basement-9.4.0.

### Resolving Duplicate Class Conflicts

When Unity exports the plugins as Library projects, it’s not unusual to see errors along these lines:

Dex: Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Lcom/unity/purchasing/googleplay/BuildConfig;


The BuildConfig class is generated by Android build tools. They are often included when a plugin is constructed as an AAR and then a second one is created by your build process when the AAR is converted to a library project and re-compiled. You can fix this by deleting the class from the expanded library project.

zip -d GooglePlay/libs/classes.jar "com/unity/purchasing/googleplay/BuildConfig.class"
deleting: com/unity/purchasing/googleplay/BuildConfig.class


Since you’ll need to do this every time you export, you probably want to write script to clean up all the JARs after export.

An alternative solution is to use the AAR, if one exists for the plugin, rather than the extracted Library Project Unity creates for the AAR when exporting. For this example, we find GooglePlay.aar, which is included with the UnityPurchasing plugin, and copy it over to a new aars directory we create in our exported project tree.

cp /Assets/Plugins/UnityPurchasing/Bin/Android/GooglePlay.aar <exported_proj>/aars/


Next we add a line to our root build.gradle file to add the new aars directory to the repository search path.

allprojects {
repositories {
jcenter()
flatDir { dirs '../aars' }
}
}


Finally, add the dependency to Your Unity Project/build.gradle. Note that we use a slightly different format to reference the aar instead of the library project.

dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile ':GooglePlay@aar'
}


### Other Issues

There is a host of other issues you may or may not encounter converting your exported Unity Project to Gradle/Android Studio. In general, the two classes of issues include (1) conflicts between the AndroidManifest.xml included by plugins and (2) the behavior the post-process scripts native plugins depend on may not translate properly to the exported project.

The former will typically occur in regular Unity builds as well, during the manifest merging task. Resolving them requires tweaking the manifest entries. Usually, the errors tell you what the conflict is and provide some clue about how to resolve them. If possible, it’s better to resolve these in the main Unity Project, so you don’t need to re-perform the steps every time you export.

The second issue regarding post process scripts is a lot more tricky, and may end up being a blocker for effectively working with the exported project. There are no general guidelines here.

## Resolving 64K DEX Method Limit in Your Gradle Project

Now that we have our Unity Project in Gradle, we can use ProGuard to attempt to bring our method count below 64K, or we can enable MultiDex to support greater than 64K.

### Enabling ProGuard

A whole separate blog post could be written on how to configure ProGuard for exported Unity Projects. Here we’ll show how to add ProGuard to your Gradle build script. Add the following to the android section of Your Unity Project/build.gradle to enable ProGuard for release builds.

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
}
}


We specified two ProGuard configuration files – the standard one that’s included with the Android SDK (proguard-android.txt) and one which is exported with the Unity Project as of Unity 5.4, (proguard-unity.txt). You almost certainly need to maintain another ProGuard configuration file with rules specifying which classes and methods need to be kept for the plugins your game uses.

To disable ProGuard, simply change the value of minifyEnabled to false.

### Enabling MultiDex

To enable MultiDex for your exported build, add the following lines to the android section of Your Unity Project/build.gradle.

defaultConfig {
minSdkVersion 15
targetSdkVersion 24

// Enabling multidex support.
multiDexEnabled true
}


This will enable MultiDex support on Android 5.0 and up devices. To support Android 4.0 and up devices, you must make a few additional modifications. First, add a new dependency for the support library com.android.support:multidex to New Unity Project\build.gradle.

dependencies {
compile 'com.android.support:multidex:1+'
compile fileTree(dir: 'libs', include: '*.jar')
// other dependencies
}


Next, update the <application> tag in your main AndroidManifest.xml to specify the MultiDexApplication support class.

<application android:name="android.support.multidex.MultiDexApplication"
... >


If your Unity Project does not already have a main AndroidManifest.xml file, you probably want to add one to /Assets/Plugins/Android/AndroidManifest.xml and update the application tag there, so it’s included with future exports.

## Complete Application build.gradle File

Here’s what the complete build.gradle file looks like for our simple application with a single dependency. A complex project bumping against the 64K method limit will likely have quite a bit more dependencies.

apply plugin: 'com.android.application'

dependencies {
compile 'com.android.support:multidex:1+'
compile fileTree(dir: 'libs', include: '*.jar')
compile ':GooglePlay@aar'
}

android {
compileSdkVersion 24
buildToolsVersion "24"

sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
debug.setRoot('build-types/debug')
release.setRoot('build-types/release')

signingConfigs {
myConfig {
storeFile file("<path-to-key>/private_keystore.keystore")
storePassword System.getenv("KEY_PASSWORD")
keyAlias "<your_key_alias>"
keyPassword storePassword
}
}
}

defaultConfig {
minSdkVersion 14
targetSdkVersion 24

// Enabling multidex support.
multiDexEnabled true
}

buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'
signingConfig signingConfigs.myConfig
}
}

}


This snippet also adds entries required to sign your app with a private key. The key password is drawn from an environment variable. If all is good, you can build your minified/multidexed game like so:

KEY_PASSWORD=XXXXXX ./gradlew assembleRelease


## References

### Author

#### Rusty Kinnicutt

Rusty's spent over 15 years working in the gaming industry. From engineering games to frameworks and SDKs, he's witnessed many exciting twists and turns. Rusty just enjoyed his six-year Kongregate anniversary. Most of his energy at Kongregate is directed toward supporting our mobile game developers. He does all this as the lone East Coast engineer, operating out of a home office in an attic of a 200-year-old house in Providence, Rhode Island.

## Quest for Progress: Numbers Behind Idle Games

A more in-depth version of this short post is available at The Math of Idle Games, Part I.

At GDC Europe this year I gave a talk that took a deeper look at some of the numbers, formulas, and patterns underlying idle games. The slides for the talk are on Slideshare and the GDC Vault, if you have access there.

In the slides you’ll find information about growth curves, formulas for bulk purchases, purchase optimization models, a variant on growth based on derivatives, a look at prestige cycles, callouts for some great new idle games, and an aside on stupidly large numbers.

However, what I hope becomes the biggest value from the talk is that all of the charts generated for the slides come from spreadsheets that I’ve opened up for general use. If you’re planning on doing a lot with them I recommend downloading the Excel versions, as Google Sheets starts to cry on some of these simulations.

These sheets allow you to play around with values in a variety of situations to see how the curves change. While it’s unlikely you’ll be able to fully model and balance an idle game with these, they will hopefully allow you to better understand the tools that you have available to build an engaging and compelling progression.

As a specific example, Sheet 1e models optimal player choice for buying generators (i.e. the buildings, investments, or whatever generates the main currency), with the ability to set multipliers for the generators that trigger when the player owns a certain number of them (similar to AdVenture Capitalist bonuses). By setting these carefully, you can create a progression that varies over time in terms of the most valuable generator, keeping the gameplay more varied for the player, like this:

I hope these turn out to be useful! If you have questions, find a bug, decide to make an extension to a sheet, or have an awesome new idle game you want to share, please feel free to reach out and email me at anthony@kongregate.com.

### Author

#### Anthony Pecorella

Anthony has been at Kongregate for 7 years and is the director of virtual goods for browser games. He works to bring great games to the platform and help developers make a living with their games. He was the lead producer for the mobile version of AdVenture Capitalist.

Anthony also designs and develops games on the side with his indie game studio Level Up Labs, including the acclaimed tower defense RPG Defender's Quest: Valley of the Forgotten, and a MacArthur-grant-funded educational biology game, CellCraft.