Pages

Monday, July 2, 2012

Developing a Real-time Android Game - Lessons Learned Part 2

Lessons Learned - Part II

We completed our 11 month journey of creating a realtime space shooter for Android using Scala programming language. We did the project in our freetime and you can check out the end result at www.scawargame.com.

We learned a lot during these 11 months. This is the second post in the series of blog posts about things we think went well and things we would definitely do differently if we were to start again from the beginning. It has been and will continue to be a mixed bag of topics about coding, project management, agile and marketing.

You can find the first post here and an off-shoot post about optimizing realtime android games here.

Issue Tracking and Sharing the Work

Really important part in any agile project is an efficient way of sharing the workload. Shared tasks should be available in a centralized place and you should try to find the easiest way to manage this task. The more difficult the sharing system is the less you want to use it.

We kept our code at Bitbucket as they now offer Git-repositories and have free private repos for small commercial projects too. In the beginning of our project we also used Bitbucket’s issue tracking. It was simple enough to use and the issue states where relatively easy to change. In the long run though, creating the issues was too slow and too verbose for a small project.

For an agile project it’s typical you add lots of small tasks on one go. These tasks usually contain quite little information. So adding them one by one, each time getting stuck on a page full of options, dropdowns and switches is far from efficient. So we opted for a simpler way, just using a simple Google Docs spreadsheet. It was easy to add lots of tasks, reorder them, mark their owner and then start working, calling dibs for the task you wanted to do in IRC. Simple, easy and fast.

Multi-site Project

Making a real time game itself is hard and needs lots of planning and work. Working with a multi-site team makes it extra hard. Multi-site team communication is the hardest part, you can use IRC and phone but really making them “see what you see” would require a face-to-face meeting.

It is also challenging to argue with equal members of the team with different visions and trying to find a proper consensus. It’s really easy to be misunderstood and sometimes it’s really frustrating to explain something on phone or in IRC.

Getting feedback is also more difficult and may take hours or days compared to instant feedback with onsite team. Feedback from our graphics designer usually took plenty of time since he didn’t have the environment to compile the game.

What we learned was that even if it’s difficult, you need to schedule frequent live meetings when everyone gets together and talks with the whole team. We will also start using video meetings in the future.

Don’t Let Engineers Do Your Graphics

How many times have you thought that the game logic of the game is awesome? Never, but damn those graphics! If you want to look good, get a real artist to do your graphics, graphics by engineers are not a real option. Our early stage versions had graphics that the programmers had salvaged/made and to be honest it really wasn’t pretty.

After we got our graphics designer we took a major leap towards to what the game is today. Cool graphics, awesome backgrounds and menus that were pretty easy to use.

Draw a rough version of your menus and UI designs before you start working with the actual implementation. This will save you plenty of time in development and possibly saves you from rewrites. The most important thing with the rough versions is to let your UI designer do the work! Having a proper UI Designer is more than having good game graphics. UI design is the key to make your game as easy to use as possible.

Keeping a Development Blog

When you are working with a game you should remember that marketing of your game starts from the day one. You should consider to keep a blog, be active on forums and try to create hype around the game.

Keeping a development blog is really hard during the development phase. Before sharing think what was the most important thing you achieved and what is the main idea you want to share. Write your ideas down, even though it’s not as fun as writing all the new cool features for your game, other developers could be working with the same or similar problems. Be professional because all of your publications are also good references in your CV.

Publishing your blog posts is a good start but getting people to find and read your blog is almost as hard as getting people to find your game. To get audience to your blog, you’ll need to forget all the modesty and work hard in Social Media. Share posts from your blog in Facebook, Twitter and on the forums where you are active. Also place a link to Hacker News and Reddit and be creative with the header.

In our case our blog had had around 6 000 page views, in 10 months, before we released the first part of the “Lessons learned”. We had done absolutely no promoting of the blog before that. We got 3 000 page views in 36 hours when we shared the post on Reddit and Hacker News. Sitting down and hoping to get audience is not a good tactic. Be open and work hard. Try to think outside the box and be creative.

Version Control Saves Lives! (Git)

When working with a project, use version control! If you haven’t used version control before, it’s about the time you do! Two main benefits are offsite backup of your source code and easier sharing of up-to-date code with others in the same project.

Use a version control that is flexible and easy to use. We used Git which is one of the best version control systems there is and got our central repository from Bitbucket. The reason we used Bitbucket instead of GitHub was that Bitbucket provided a free private repository that you could share with your fellow developers (4).

When you do development, keep your bleeding edge development in separate branch. Make lots of small working commits and merge your changes to the master branch when you are done. Small working commits are really important when you need to do bug hunting and you want to isolate a new problem in your game (see git bisect).

Always have a workspace without modifications or untracked files when you start working with new modifications and always make sure that your code compiles before you commit your changes. Also, avoid doing refactoring and bug fixing in the same commit.

Monday, June 4, 2012

Optimizing Realtime Games on Android

This post was originally intended as just another topic in our Lessons Learned series. But we have spent quite a lot of time optimizing our game in the past 11 months. So we noticed we have enough material to cover here to justify a whole post on game optimizations. I’m telling you this because it will shed light on what we will present in the following post.

This post is not supposed to be an exhaustive list on Android game optimizing. Some of these topics might not apply to your situation at all. But these are the topics that we feel to be important based on our experience in creating SCAWAR Space Combat.

Choose your battles

Optimizing code often compromises readability and maintainability of the code. It also takes a lot of time and effort. Time that could be used to create more content to your game and implementing those must-have features before your first release.

Only a very small portion of game code is really performance critical. For the rest of the code you should focus on making it readable and not worry about squeezing every bit of performance out of everything.

Only optimize code when it is really necessary and even then, choose the parts to optimize with careful measuring so you don’t waste effort where it is not needed.

Measure before Optimizing

Android ships with a debugging tool called the Dalvik Debug Monitor Server (DDMS), which provides port-forwarding services, screen capture on the device, thread and heap information on the device, logcat, processes and more. What proved to be most valuable for us was the Object Allocation Tracker. You would start your game, open DDMS, select your game from the process list, click Start Allocation Tracker, play your game, pause your game and then ask DDMS for a list of the allocated objects. This shows you what objects were created and who created them. If your garbage collector screams like a bottle rocket on steroids when you play your game, the Allocation Tracker is a good tool to start searching for the culprit causing all those unnecessary object allocations. You should avoid all object creations that you can and pre-create all the rest.

When your object allocations are in check, you can fire up traceview for measuring the execution performance of different parts of your program. You need to start and stop the trace gathering programmatically. We did this by overriding the phone’s ‘back’ button to either start or stop tracing. So a typical measuring goes something like this:

  1. Start your game
  2. Start playing a level
  3. Click the ‘back’ button to start method tracing
  4. Play for 10 seconds or so
  5. Click the ‘back’ button again to stop tracing
  6. A file with .trace extension is created to your /data
  7. Open the trace file with traceview

This will show you an overview of everything that goes on while you play. The items are ordered by inclusive execution time by default, so the method that takes the longest (including everything else called from that method) is placed on top of the list.

Usually, you will scan the list for something starting with your game’s own package name. If you then see com.mycompany.mygame.Game.justScratchingMyArse() method taking 30% of all execution time, you probably should do something about it. You can click on that method and you’ll see what exactly is taking that time inside the method call. Then you just keep drilling down the list in this way until you find something that you can act upon.

Especially with Scala, Proguard and Dalvik JVM doing tricks to your code, you should always make this kind of exploratory measurements before doing any optimizations. And then make the measurements again to see if you did something great or actually just made it worse.

Cheat if you can

Fortunately we are dealing with entertainment here, not science. Only the results matter, not the way we get there. So on a CPU and memory limited device, you cheat where you can. Here’s a few ideas on where you can skip some corners.

Checking collisions, updating timers that control game mechanics, moving dots on a radar and so on. These are things that are usually done in update methods. Update methods usually run on each frame. But do you really need these calculated / executed on each frame? How about every second frame? Or every third? There’s a lot of CPU power to gain here so experiment with these.

What’s not on screen, should be handled as lightly as possible. In our game, if an enemy explodes far from the sight of the camera, we just play the sound and skip the sprite animations, effects and particle engines we normally create our explosions with.

Collision Handling and Space Partitioning

Collision handling is one of the most computation-heavy activities in our game. If you have played it, you know why. The screen is full of bullets, enemies, mines, black holes, etc. So we had to do a lot of work with the algorithm.

Due to garbage collection, we had to rewrite our beautiful 10 lines of functional programming to something like 200 lines of while loops. It was a glum moment for us all. But, unfortunately, filter and map operations create way too many temporary objects and collections to be effective here.

The game engine we used offered collision detection, but it was still a slow process to compare collisions between every bullet and every enemy on every frame. Fortunately a technique called space partitioning came to our rescue. You could really go crazy here with complex data structures and tracking algorithms. But the basic idea is to split the game area into smaller partitions. Then you just do collision detections to objects inside the same partition. You can have a screen full of enemies, but if you are shooting in just one direction, most of your space partitions will be empty of bullets. So you start your collision handling by selecting a partition and seeing if there are any bullets or enemies inside it. If either one of these is missing, you can completely skip collisions for that partition.

We didn’t want to go overboard with this, so our poor man’s space partitioning did just a simple vertical slicing of the game area. But already this brought us massive savings in CPU time.

Functional Operations and Garbage Collection

Garbage Collection is your worst enemy in real time games. Every time garbage collection occurs it hoards the CPU time from your other threads. When you have lots of discarded objects to clean, GC occurs more often and tries to spend as much CPU time as possible. This makes your game lag and have poor FPS during gameplay. Here are some tricks to avoid unnecessary discarded objects.

Reuse your variables as much as you can.

Try to generate as few new objects (sprites, game objects, etc. ) as possible during game play and never discard them. If you must discard something, choose the objects carefully and try to discard them in a phase where lag is not noticeable, ie. in Menus, Scene switches, Between levels, etc. 

Methods

When you create methods, try to avoid creating variables. Here’s an exaggerated example of bad design:

1 def follow() { 2 val direction = getDirection 3 val xVelocity = velocity * FastMath.sin(direction) 4 val yVelocity = -velocity * FastMath.cos(direction) 5 setVelocity(xVelocity,yVelocity) 6 }

Now think of situation where you have objects using this method in every frame. If there are 30 objects in every frame (30 frames/sec) and the method creates 3 discarded objects (val direction, ...), you end up with 1200 discarded objects every second and this will drive the GC mad.

To make fewer GC operations, you could make the variables into class variables or put them directly to the setVelocity method call. The latter is not pretty but will do the job.

1 def follow() { 2 direction = getDirection 3 setVelocity(velocity * FastMath.sin(direction), 4 -velocity * FastMath.cos(direction)) 5 }


Pool everything

Besides the abovementioned point of Garbage Collection being your worst enemy, object creation is also slow on Android. Both of these points guide you to create everything you need in advance, not during the game. What you do is create pools for everything. If you can, create fixed-size pools so there will be even less garbage. Create your enemies, bullets, explosions, modifiers, timers, etc. all in advance, and put them in object pools. During the game play, when you need a new object, request it from the pool. The pool will return an object for you instead of creating one, and either remove it from the pool or mark the object in the pool as being in use until you return it.

Random number generators are not made equal

Random numbers are really common in game programming and it’s very important to choose the proper Random generator for your purposes. Do not use java.util.Random, it’s not random enough and it’s too slow. What we suggest is to use either MersenneTwisterRNG, which is faster than java.util.Random, or XORShiftRNG, which is twice as fast as the MersenneTwisterRNG. These can be found at http://maths.uncommons.org/.

Another good question is: do you really need real random numbers? Here’s a simple example of how to get a random spawn point from predefined point collection.

1 val rand = scala.util.Random 2 val spawnObjectWidth=10f 3 val xPoints = (0 to 10).map(item => item*spawnObjectWidth).toArray 4 5 def getRandomXPoint:Float={ 6 xPoints(rand.nextInt(10)) 7 }

Nothing special here, but when used in spawning this could return the same point twice when spawning multiple objects to the screen. Also, as was stated above, random number generation is a slow operation. When you need plenty of random numbers, pre-generate them! Memory is cheap, CPU time on the other hand is not!

Here’s another example how to handle random spawn points without using random number generation. Since we are spawning to predefined points, we can make the spawn points random instead of getting a point from a random location of the list.

1 val spawnObjectWidth=10f 2 val xPoints = (0 to 10).map(item => item*spawnObjectWidth) 3 val randomXPoints = scala.util.Random.shuffle(xPoints).toArray 4 val randomXPointsSize = randomXPoints.size 5 var index = 0 6 def getRandomXPoint:Float={ 7 index = (index + 1)%randomXPointsSize 8 randomXPoints(index) 9 }

Looks horrible, but it does the trick. With this, there can’t be two objects in the same location when spawning the objects to the screen, unless you spawn more objects than there are spawn points in the array. The second point here is that it’s random enough.

Mathematical operations

In almost every game, you will need to do some mathematical operations, for example calculate a new position of an object (bullet) which is relative to its parent object.

1 def shift(shift: Point, direction: Float) = { 2 Point(this.x + shift.x * math.sin(direction), this.y - shift.y * math.cos(direction)); 3 }

math.sin and math.cos are mathematically accurate calculations, but they are too slow when you have to use them a lot. What you could do is pre-calculate your mathematical functions to a table and use these pre-calculated results. The values in the table are not mathematically accurate, but yet again you are not doing science but cheating your way to better performance.

Loops and Conditions

Containers
Selecting the best containers for your game is very important. You have to decide how you are going to access the data and what you are doing with the data in the container. If you’ll need to access data in the container with an index, your obvious choice is to use Arrays, but if you need a container with mutable size, using a linked list instead of an array is a much wiser choice. 

Loops
If you are using a functional language like we did, do not use ‘foreach’ in performance critical places. Foreach is often many times slower compared to a ‘while’ loop, and for that reason your optimal choice is to use ‘while’ as much as you can.

If you are iterating your container and only need a certain object from the list, try to make the loop short-circuit as fast as possible. Or if it suits your situation, instead of looping, use another data structure, for example a set or a map. Try to save time where you can.

Proguard switches

Proguard contains plenty of peephole optimizations for arithmetic operations, like turning divisions into multiplications, multiplications into bit-shifts, and so on. In performance critical loops, these optimizations can make all the difference.

Most examples of Proguard configurations you see on the internet, including Proguards own examples for Android, contain the following line:

-optimizations !code/simplification/arithmetic

This will tell Proguard not to use these arithmetic optimizations. And it’s because Dalvik, the Android JVM, had problems with these optimizations on Android 1.0 and Android 1.5. But they haven’t been a problem after that. Currently there are basically no Android 1.0 devices and 1.5 devices have a 0,3% market share. So if you are not developing for 1.5, remove the above line from your Proguard configuration and let it do its own optimizations.

Monday, May 21, 2012

Developing a Realtime Android Game - Lessons Learned - Part I

Lessons Learned - Part I

We just completed our 11 month journey of creating a realtime space shooter for Android using Scala programming language. We did the project in our freetime and you can check out the end result at www.scawargame.com.

We learned a lot during these 11 months. This is the beginning of a series of blog posts about things we think went well and things we would definitely do differently if we were to start again from the beginning. It will be a mixture of topics about coding, project management, agile and marketing.

Plan Well

We did pretty much everything in our project in an agile way: very low bureaucracy, development in sprints, work lists in backlogs, used pair programming and weekend hackathons. We also did stuff in the usual way, wrote production code while still very much in learning phase. All this is well and good, but what we forgot and paid dearly for is that design decisions have a so-called last responsible moment of making.

Planning too much ahead is risky but if you delay your design decisions past the last responsible moment, the decisions are made by default. So instead of a concious group decision, you just implement what think is needed. Soon after you realize you just implemented something that was just your reflex and if you would have thought this through with your team earlier, you would have come up with a better way of doing it. Now, you will come up with the better idea but it’s too late to avoid rewriting major part of your work. Repeat this often enough and it will get frustrating.

So plan well here means: plan enough, just early enough and plan it with your whole team, don’t just make quick decisions to get on with your implementation.

Hard Work Makes You Hate Your Game

One thing about projects that take a long time: you are going to hate them! They eat all of your free time and make your significant other mad. Working with the same thing for months get really boring very easily. And since we were using our free time, it was sometimes really hard to get motivation to start working again after a long day at work.

Best solution what we discovered was don’t work alone! When you have pressure from other developers, the pressure is the best motivation to make you work harder. Nothing makes you feel better than getting feedback from your fellow developer saying “Shit, that is awesome!”

Also remember to take some time off from your project. Fresh mind and body will give you new ideas and perspective on what should be done. Spend time with your family, they seem to nag less if you do so.

Motivation from Goals (SPEC)

Well planned goals are a key in enabling you to finish your game someday. In the very begining of our project, we didn’t really make goals, we just did stuff. Doing stuff without goals is a good way for getting to know your tools and platform, but for advancing your project, not so much. Better way to do proof-of-concept is to do Spikes: time-boxed research / development tasks that should be thrown away. You’ll avoid plenty of mistakes in your project code and design this way.

After a while in to our project we started planning what we should do and tried to prioritize what was important and what wasn’t. Working with the prioritized list made it easier to get the important features completed. Completing an important feature will boost your motivation through the roof. Prioritizing is a good way to help you create goals. Also when working with a team it’s easier to divide tasks with your fellow developers when you know where you need to focus.

Our first release version, which actually wasn’t released, changed our way of working more dramatically. We got a huge motivation boost from squeezing the first release candidate ready, or should I say the first actual beta. We had good features but... not enough content, not very polished version and loads of optimizing to be done.

This was the point where we started to do actual “sprints” with features that needed to be completed. We already had done the Spikes and the prioritizing, now all we needed was some planning poker and set of features to agree on. When planning and doing the estimation, it is really important to get your team into the same place. Talk about the features and do the estimations as a group. Every member of the team has to participate in the planning poker! It’s not important if every member knows how long it takes to program a feature, but they can and will provide some other useful information to the planning.

Finish your goals. Make plenty of release candidates. When you complete a full list of planned and estimated feature, you get a motivation boost. Completing a “release” ready product boosts your motivation even more.

So here’s our mantra on how you should do your stuff.

Spike - Prioritize - Estimate - Complete = SPEC

Make Builds Fast

Make your builds as fast as possible. This chapter might as well be known as “do what we say, not what we did”.

Your build times affect your productivity. If your build times go up, you spend longer periods coding blind and this way you’ll also spend more time debugging. More debugging means more test builds. You get the picture, it’s a nasty circle.

But we were building an Android game with Scala. And as long-time enterprise programmers, we were building with Maven. So we had few problems, namely:

  • Scala is bad for your build times
  • Android is bad for your build times
  • Maven is bad for your build times

We should have never chosen Maven. But then again, building for Android involves lot of extra steps, dexing, signing your code and zipaligning your packages etc. So you definitely need automated builds. By the time we started our project, SBT, Scala’s not-so-aptly-named Simple Build Tool was constantly and completely rewritten, it seems, every few days or so. Well not quite, but enough to encourage us to stay away.

Scala’s library is pretty big. And maven scala plugin stopped supporting incremental builds. So compile times are pretty bad as you always load the whole language library and always compile your whole project. Dalvik, Android’s JVM, can not survive the amount of classes included in the Scala library. So you need to run Proguard, to shake off all classes that are not really needed by your application. On our machines this takes as long as compiling.

We tried several things to shorten the build time. Mainly how to skip the proguard phase. After proguarding your application, you can grab scala-part of the resulting classes, put them in jar and use that package as a dependency instead of the full scala library. We wrote a short blog entry about this a while ago. This allows you to skip the proguarding entirely, but every time you use a new API from Scala, or a new implicit conversion or something subtle like that, you need to create a new jar with the new required classes included. So this might have some uses in a stable and mature project project but it will get tedious really easy.

Other option was to hack the Android bootloader to load Scala libraries on startup along with other libs provided by the OS. We did this on the Android Emulator but were reluctant to do it on real devices. Partly because it’s a bit sketchy and partly because we then would not have had regular devices to test on.

To top things off, once your package is done, you need to uninstall the previous version from your phone and install the new package. You can’t use Android Emulator as it’s pretty much one of the worst pieces of software known to man.

End of Part I

Well that's it for part I. We got plenty of topics lined of next parts. As always, comments, diggs, +1:s etc are very welcome.

Saturday, March 3, 2012

Proguard performance and Scala versions

We have been holding back from moving to Scala 2.9 for a long time now. The reason is that Scala builds for Android need to be treated with Proguard to reduce their size. And on Scala 2.9, Proguard is incredibly slow. I think this has to do with the trait bloat that was creeping up on Scala library while it gained more and more features. Now that it's "fixed" by introducing more abstract classes to Scala 2.10 I was interested in seeing if my guess was correct and if the proguard performance would back to 2.8 level.

After fixing some issues in our build introduced by Scala 2.10, I run our build for Scala versions 2.8.2, 2.9.1 and 2.10.0-M2 (the currently latest milestone release). Timing information was gained from Lasse Koskela's maven-build-utils which I've done some work with lately.
Our build includes 7346 lines of Scala and some Java. Here's the performance information:

Scala 2.8.2

[INFO]   compile                                  32.6s  45%
[INFO]     maven-compiler-plugin:compile           3.0s   9%
[INFO]     maven-scala-plugin:compile             29.6s  90%
[INFO]   process-classes                          18.7s  26%
[INFO]     android-maven-plugin:unpack             0.7s   3%
[INFO]     proguard-maven-plugin:proguard         18.0s  96%

Scala 2.9.1

[INFO]   compile                                  32.0s  19%
[INFO]     maven-compiler-plugin:compile           3.0s   9%
[INFO]     maven-scala-plugin:compile             29.0s  90%
[INFO]   process-classes                         110.3s  67%
[INFO]     android-maven-plugin:unpack             0.8s   0%
[INFO]     proguard-maven-plugin:proguard        109.5s  99%

2.10.0-M2

[INFO]   compile                                  32.8s  41%
[INFO]     maven-compiler-plugin:compile           3.0s   9%
[INFO]     maven-scala-plugin:compile             29.9s  90%
[INFO]   process-classes                          24.0s  30%
[INFO]     android-maven-plugin:unpack             0.8s   3%
[INFO]     proguard-maven-plugin:proguard         23.2s  96%

As you can see, Proguard takes over 6 times as long on 2.9.1 that it does on 2.8.2. And on 2.10.0-M2 it's almost back to what it was on 2.8.2. So that's really good news for Android developers using Scala. Compile time differences between different Scala library versions are negligible.


Tuesday, February 21, 2012

Scala saves you lines

Very brief post about Scala programming

Few days ago I played a bit with Scala's fold operations.

I had a list containing rules that all needed to be completed to continue.

Because I have a long history with Java, the first version:
def areRulesCompleted(ruleList:List[Rule]):Boolean= {
var isCompleted:Boolean = true
ruleList.foreach(rule =>{
if (!rule.isCompleted) isCompleted = false
})
return isCompleted
}

As you can see there's plenty of rows and it's not very functional. Then with foldLeft
ruleList.foldLeft(true)((resolvedValue,rule)=>(resolvedValue && rule.isCompleted))
Better! But we can do it even simpler way
ruleList.foldLeft(true)(_ && _.isCompleted)

so combining this with the method declaration:
def areRulesCompleted(ruleList:List[Rule]) = ruleList.foldLeft(true)(_ && _.isCompleted)
Here's even shorter version (short-circuit) by: Ilkka.
def areRulesCompleted(rules: List[Rule]) = !rules.exists(!_.isCompleted)
I also checked that foldLeft is short-circuiting but foldRight is not.

Sunday, January 22, 2012

Beta testers needed


We are looking for beta testers for our game, SCAWAR Space Combat. All you'll need to do is send us an email and tell us why we should choose you. When the beta starts, we'll send you a link to download the game. Then just play the game and give us feedback. Simple as that! Be among the first ones to play it.

What we want:
- Feedback on our game
- Issues you've discovered
- What would you like to have in the game?
- What you didn't like?
- Active participation 

From active participation you'll get:
- Our game for free! (Ads removed and extra content when the game is released)
- Your name in the credits.
- A letter of reference for participating in the game testing.

Here's a trailer of our game:


Send your application to scawargame (at) gmail . com

Thursday, January 5, 2012

Shrinked Scala jar from proguarded files

Ok short post how to shorten package time when using Scala.

So after you've run your packaging with proguard you should have your scala files under:
target/android-classes

so what you want to do is run the following:
jar cvf shrinked-scala-1.0.jar scala

This will create a file called shrinked-scala-1.0.jar which contains all the Scala files and methods you've used in your project so far.

Next we'll add the file to our local maven repository:
mvn install:install-file -Dfile=./shrinked-scala-1.0.jar -DgroupId=com.punchwolf.scala -DartifactId=shrinked-scala -Dversion=1.0 -Dpackaging=jar

Now that we have the package in your repository we can create a new profile that uses the original Scala for compilation only but takes the shrinked version in to the package as a dependency.


<profile>
<id>hacked</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<properties>
<use.lazy.unpack>true</use.lazy.unpack>
<compile.scope>compile</compile.scope>
</properties>
<dependencies>
<dependency>
<groupId>org.scala-lang</groupId>
<artifactId>scala-library</artifactId>
<version>${scala.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.punchwolf.scala</groupId>
<artifactId>shrinked-scala</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
</plugins>
</build>
</profile>
The above profile uses the original scala-lang as provided scope (used in compilation) and the shrinked is used in compilation scope (is packaged in the APK).

what you'll also need to do is to have a default profile that uses proguard and the scala-lang in compilation scope.

now that you have these separated, you can run the following:
mvn clean package -P hacked

Now the compilation should be done without the proguard and your new package should be executable in your phone.

The drawback is that if you use a new Scala feature that you don't have in your shrinked-scala, the program will fail saying that there's no class found. So you'll need to run the proguard profile package again and generate the shrinked-scala.jar from the proguarded scala files.

This is not very useful in the early stage of development, but it's very useful when you have pretty stable set of Scala features you use in your project or if you are debugging something.

Monday, January 2, 2012

Useful terminal with git in osx

Here's some small modifications how you can get more out of git and bash with OSX (maybe Linux too).

Add following to the .bash_profile:


#for white terminal
export CLICOLOR=1
export LSCOLORS=ExFxCxDxBxegedabagacad

# Set git autocompletion and PS1 integration
if [ -f /usr/local/git/contrib/completion/git-completion.bash ]; then
. /usr/local/git/contrib/completion/git-completion.bash
fi
GIT_PS1_SHOWDIRTYSTATE=true

if [ -f /opt/local/etc/bash_completion ]; then
. /opt/local/etc/bash_completion
fi

PS1='[\u@\h`__git_ps1` \W]\$ '

enjoy.

thanks to:

Tuesday, December 13, 2011

SCAWAR Space Combat trailer

We have just published the first trailer from our forthcoming Android game SCAWAR Space Combat. Click the youtube player below to check it out.


We are also really close to starting our Open Beta round so if you want to know when that starts or anything else related to our game, follow us on Facebook:

facebook.com/scawargame

Saturday, November 5, 2011

First screenshots

Our game has finally reached a point where I'm comfortable with posting few preview in-game screenshots. So here we go:






Few more shots are available from our facebook page.

TexturePacker

While working on our first Android game, I came across a tool that let's you combine all your small sprites in to a single sprite sheet that will be loaded by your game engine. The tool is called Texture Packer.

The tool will try to fit all the images you throw at it in the smallest possible spritesheet. If you want, it can also crop and rotate the images to make it possible to fit even more images to same space. Several different game engines are supported, so for example AndEngine which we currently use, the tool will create one image file, one XML data file that contains the locations, rotation etc. information of the sprites in the image file and one Java file which has a constant for each of the sprites for typesafe handling of sprite loading.

Packing all your sprites to one image has multiple benefits. OpenGL ES requires the textures dimensions to be a power of two. This way, if you have a single texture buffer for each sprite, you end up reserving lots of extra space for nothing. With single, tightly packed spritesheet you usually can get away with considerably less empty buffer space. Using a single TextureAtlas for multiple textures has performance advantages in both loading the textures as well as drawing them. Details about advantages in drawing performance are explained here.

The tool is easy and intuitive to use. The developer is friendly and fast to response to any problems you might have. And it does now have a version for Ubuntu, which was perfectly timed as I had just moved my development to Ubuntu from Windows as I kept having issues with Windows filesystem and Maven.

As I'm starting to sound like a marketing droid here, I will state here that I don't have contacts to TexturePacker or it's author, I didn't receive any payment from this post. Andreas Löw, author of TexturePacker, was kind enough to provide me with a free Pro license of TexturePacker.

Sunday, October 9, 2011

Integrating Scoreloop to your Maven build

I’m a big fan of automated build process. Especially on Android where creating a release-ready package is a really multi step process: you need to compile, strip with ProGuard, dex, package, sign, verify and what not.

When it came time to integrate Scoreloop to our game, we had some problems. Scoreloops offers a nice UI ready for use. But this means you can just put it in a jar and use it like normal dependency, because UI’s need graphics, layout xml’s and other resources. Finding info on how to get this to work with Maven proved difficult. Thanks to Julien Donguy at Scoreloop for pointing me to Android Library Projects.

Here’s how you would go about adding Scoreloop to your Maven build:

Download the Scoreloop SDK and unpack it somewhere. Inside you’ll find two directories: ScoreloopCore and ScoreloopUI. ScoreloopCore contains scoreloop-core.jar which you can install to your local maven repository like any other jar:

mvn install:install-file -Dfile=scoreloop-core.jar -DgroupId=com.scoreloop -DartifactId=scoreloop-core -Dversion=2.4 -Dpackaging=jar

Next you want to create a zip file from the contents of the ScoreloopUI directory (so that AndroidManifest.xml is in the root of the zip) and rename that zip to scoreloop-ui.apklib.

We can then add that package also to your Maven local repository with command:

mvn install:install-file -Dfile=scoreloop-ui.apklib -DgroupId=com.scoreloop -DartifactId=scoreloop-ui -Dversion=2.4 -Dpackaging=apklib

Note the different packaging parameter.

Next you’ll add both of these packages as dependeciens to your pom.xml.

        <dependency>
            <groupId>com.scoreloop</groupId>
            <artifactId>scoreloop-core</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>com.scoreloop</groupId>
            <artifactId>scoreloop-ui</artifactId>
            <version>2.4</version>
            <type>apklib</type>
        </dependency>

Now running mvn clean package should create an apk that includes all necessary parts from Scoreloop. You can see the apklib getting included with something like this:

[INFO] --- android-maven-plugin:3.0.0-alpha-11:generate-sources (default-generate-sources) @ YourGame ---
[DEBUG] Expanding: C:\Users\someuser\m2\repository\com\scoreloop\scoreloop-ui\2.4\scoreloop-ui-2.4.apklib into C:\ideaworkspace\examples\YourGame\target\unpack\apklibs\com.scoreloop_scoreloop-ui_apklib_2.4

We did experience problems with earlier versions of maven-android-plugin so we suggest using Maven 3 and android-maven-plugin 3.0.0 alpha’s.

Atleast for Intellij IDEA, there’s one more step to go. Apklib’s, unlike regular jar dependencies, are not visible inside IDEA, so if you start coding, you’ll find none of the classes from the scoreloop-ui.apklib available. To fix this you can add the ScoreloopUI as a module dependency inside IDEA:

  • Select File –> New module.. –> Import module from external model

  • Point the file explorer to the location where you unpacked ScoreloopUI.

  • When it’s imported, select your game’s module and “Open Module Settings”

  • Select “Dependencies” tab and click Add.. –> Module Dependency and select ScoreloopUI.

Now the sources for the UI classes are available to your IDE, and this doesn’t affect the maven build process.

From here on forwards you can follow the User Guide that comes with Scoreloop.

Comments and feedback are welcome as usual!

Thursday, August 25, 2011

Proguard optimize for Scala and Android

Our game is progressing nicely and we are planning on starting closed beta phase soon. So it was time to get ProGuard’s optimize and obfuscate features working. So far they had been disabled.

Optimizing seemed to go through just fine but dexing the end result failed with:

[INFO] UNEXPECTED TOP-LEVEL EXCEPTION:
[INFO] com.android.dx.cf.code.SimException: local variable type mismatch: attempt to set or access a value of type java.lang.Object using a local variable of type long. This is symptomatic of .class transformation tools that ignore local variable information.

So I knew I needed to limit the optimizations, but what exactly I didn’t know. Most of the exceptions referred to different Scala classes like

[INFO] ...at bytecode offset 00000022
[INFO] locals[0000]: Lscala/collection/IndexedSeqOptimized;
[INFO] locals[0001]: Lscala/collection/Iterable;
[INFO] locals[0002]: I
[INFO] locals[0003]: Lscala/collection/IndexedSeq;
[INFO] locals[0004]: Lscala/collection/mutable/Builder;

and one exception from AndEngine’s classes.

I finally got my solution by combining the typical optimization flags for Android with something I found from the simple-build-tool wiki. Resulting string to add to your proguard.cfg is:

-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*,!code/allocation/variable

That did it for me, so I thought I’d share it.

Tuesday, August 9, 2011

Functional Programming and Android Game Development, a Happy Couple

For the past few months I’ve been writing a game for Android using Scala. I’ve been really impressed with the syntax of Scala after almost 15 years of Java programming. When we started doing the game, it seemed like proper object-orientation and game programming didn’t really fit. Doing nice object constructs and class hierarchies, although easier to read, develop and debug, is not well suited for a mobile device with limited memory and the tips that Google gives on Android development (avoid unnecessary objects, getters and setters etc) seems to guide you away from good OO principles too.

But the more I learn from the functional programming side of Scala, the more I feel that it goes well together with mobile game development.

Garbage collection seems to be your worst enemy in real-time gaming on mobile devices. It’s the one thing that can bring your game to grinding halt in the middle of best action and surely drive your gamers away.

FP concepts and Scala’s syntax help you to avoid unnecessary objects and garbage collecting. Creating and loading objects is expensive so in game programming you load and create in advance and pool what ever you can instead of creating on the fly and discarding after using.
Different collections and operating on them directly are in the heart of Scala and functional programming. So in game programming, pool what resources and game objects you can and instead of taking single objects from the pool, use Scala’s different advanced collection operations (filtering, mapping, collecting etc.) directly on the pools.

Scala’s syntax also allows returning values/objects/functions from pretty much any code block. With value-returning if/else blocks and object yielding for loops you are able to avoid using a lot of unnecessary temporary variable and mutable states.

One Scala's feature that wasn't a good idea with regards to memory and garbage collection was implicit conversions. I was using AndEngine library for the game and wanted to richen the Sprite implementation with few convenience methods. So I created a RichSprite and made and implicit def that when needed, converted Sprite to RichSprite. This unfortunately uses a constructor call to create a RichSprite. So you'll end up with one Sprite instance and one RichSprite instance, so you'll have more memory usage and eventually more garbage collecting. So I just ended up using the traditional class RichSprite extends Sprite which is a bit of a disappointment but works better for this purpose.

I’ll try to give you some code examples in the future blog entries, but in the mean time I’m happy to answer any questions, comments and would love to hear your opinions on using Scala on game programming.

Tuesday, July 26, 2011

Dropbox and Git bare repository

Here's a nice tip for those who want to make development with Git but don't have a place to put their shared repository. You could use Github, but remember that any sources you put in the free version of Github are open for all users. So if you don't want to share your sources with everyone you could use e.g. Dropbox to share your code with your fellow developer(s) or just to backup your sources.

Create a bare repository
Create the directory which you want to share:
mkdir mydev.git
cd mydev.git

Initialize the repository and modify the Git config to enable shared mode (not needed for Dropbox but good to have if you move your bare repository to a proper server).

git init --bare

add sharedrepository=true to the config file.

Now you have a proper bare repository.

Share the repository in Dropbox
Copy the folder you initialized in your Dropbox folder. If you like, you can share it with your fellow developer(s).

Connect to your "Central Repository" and share your work
You can connect to your bare repository by executing the following command:
git clone PATH_TO_DROPBOX_FOLDER/mydev.git
cd mydev

Create some work to share
touch my_example_file.txt
git add my_example_file.txt
git commit -m "my first commit"

Git commit commits your work to the local repository but doesn't commit it to the central repository, so to share your work you need to push your work to the central repository.

git push

To get the work from the central repository, you need to do a pull operation:

git pull

Last I should warn you that we've had some issues with corrupting the central repository. We got everything working again by doing a new commit and push by the person who last changed the repository. However, despite the occasional corruptions in the central repository, there are several advantages to using Dropbox as the central repository, and it will make the development work a lot easier.

Monday, July 25, 2011

Adding Scala libraries to the Android emulator

After a couple of weeks' development we recognized that the compilation took vast amounts of time to complete and it really slowed us down. We tried using Android plugin's lazyunpack with rather poor results, as well as tweaking the Proguard, but clean compilation still took us almost 2 minutes.

After a short search we stumbled on a really interesting article about preloading the Scala libraries to the Android emulator. All we needed to do was predex our Scala library and create a custom ramdisk with some extra rules in the init.rc file for loading the Scala libraries during the emulator startup. Jan Berkel also had a really good tutorial about how to preinstall the Scala libaries to the emulator (and also to a rooted phone). With these resources at hand I first cloned the scripts provided by
Berkel from the Github (derived from Stéphane Micheloud's scripts).

git clone git://github.com/jberkel/android-sdk-scala.git
cd android-sdk-scala\bin
createdexlibs.bat

I needed to set SCALA_HOME and ANDROID_SDK_ROOT, to get the scripts to run correctly.
set SCALA_HOME=PATH_TO_SCALA
set ANDROID_SDK_ROOT=PATH_TO_ANDROID_SDK

I also had to manually modify the createdexlib.bat, since Google had changed the location of the dx compiler.

Then I configured the Scala 2.9.0 version into my SCALA_HOME variable and ran the scipts. I also downloaded the custom ramdisk.img (avd.v10 [2.3.3]) from Micheloud's article. I tried to get the emulator to start with the new custom image by giving it as a parameter in the emulator start-up, but without success. So I had to replace the original ramdisk.img with my custom one.

The original image is located in the ANDROID_SDK_ROOT/platforms/android-10/images/ folder.

Then I started the Android emulator and ran the following commands in the
ANDROID_SDK_ROOT/platform-tools/ folder:

adb.exe shell ls / (you should run this command until you get a proper list of files)
adb.exe shell mkdir -p /data/framework

adb.exe push PATH_TO_ANDROID_SDK_SCALA\config\framework\scala-actors.jar /data/framework
adb.exe push
PATH_TO_ANDROID_SDK_SCALA\config\framework\scala-collection.jar /data/framework
adb.exe push
PATH_TO_ANDROID_SDK_SCALA\config\framework\scala-immutable.jar /data/framework
adb.exe push
PATH_TO_ANDROID_SDK_SCALA\config\framework\scala-library.jar /data/framework
adb.exe push
PATH_TO_ANDROID_SDK_SCALA\config\framework\scala-mutable.jar /data/framework

After this I restarted the emulator, but for some reason the emulator couldn't load the scala libraries correctly. So I had to do this again with the Scala 2.8.1 configured into the SCALA_HOME variable. With these libraries the loading went a lot better, but I still got this weird error message: DexOpt: mismatch dep signature for '/data/dalvik-cache/data@framework@scala-library.jar@classes.dex'. Despite the message, the emulator worked alright.

Compilation times

with Proguardwithout Proguard (Scala:Provided)without Proguard and with lazyunpackagewithout Proguard with scala cc (fcs:false) and lazyunpack
mvn clean package 1 min 56 sec 35 sec27 sec 21 sec
mvn package 1 min 32 sec 25 sec24 sec 14 sec


If you want to try this too, I have provided the Scala libraries (2.8.1) and also the custom ramdisk.img here so you don't have to do as much work as I did to get this working.

Big thanks to:
Stéphane Micheloud for this exellent article http://lamp.epfl.ch/~michelou/android/emulator-android-sdk.

Jan Berkel for making a really clear and easy step by step tutorial on how to do the emulator customization http://zegoggl.es/2011/07/how-to-preinstall-scala-on-your-android-phone.html

Monday, July 11, 2011

Improve your maven android build speed

Here’s a nice way of shaving around 10 seconds off your average maven builds total time when building Scala Android applications.

You know the part when you need to unpack everything to have ProGuard go through all your classes to remove that extra fat. Well, even if you make a lot of changes to your code, most of the time is spent unpacking the libraries (Scala and Android mainly). And these libraries don’t change that often. So after you’ve done it once, and they have already been unpacked to your target directory, why do it again? Well, someone figured that out and now it’s added to maven-android-plugin in version 2.9.0-beta-5, so switch to that from 2.8.4 which is what you are probably using.

Then all you need to do is add the line:

<lazyLibraryUnpack>true</lazyLibraryUnpack>

under the <configuration> of your maven-android-plugin.

If this causes force closes on your device/emulator, check that your ProGuard settings are not too aggressive.

Wednesday, July 6, 2011

Andengine application with Scala

Let's take a look at how to make a simple application with Scala and Andengine. This is the quick and dirty conversion from Andengine ParticleSystemSimpleExample made with Java.

Folders
Folder paths are only for example and you can change them from the pom.xml.

/src/main/resources/ - all none code stuff
/src/main/resources/assets/ - folder that contains all loadable content
/src/main/scala - all code
/src/main/android -all android specific stuff (configured in the pom.xml)


You can get the Android specific content to the /src/main/android folder by creating an empty Android module with IntelliJ Idea. Then copy AndroidManifest.xml and the res folder from the generated module to the /src/main/android folder in your Maven project.

Android config
Set the executable applications package as well as the executable file name in AndroidManifest.xml

/src/main/android/AndroidManifest.xml
Give a proper name to your application
/src/main/android/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">ParticleSystemSimple</string>
</resources>


Code

This is the good stuff, finally!

First create a proper package by right clicking the /src/main/scala folder


Next, create the Scala class. Right click the newly created package and select new -> Scala Class

package com.studfarm.example

import com.studfarm.example.ParticleSystemSimpleExample._

ParticleSystemSimpleExample {}



Create a companion object for the class. Companion objects are used to store all static methods and variables. An object is called a companion object when the object is in the same file with the class and has the same name as the class.


Add these to the companion object:


val CAMERA_WIDTH:Int = 720

val CAMERA_HEIGHT:Int = 480

Remember to import the companion object so you can use the static methods and variables more easily.

package com.studfarm.example

import com.studfarm.example.ParticleSystemSimpleExample._

class ParticleSystemSimpleExample {

}

object ParticleSystemSimpleExample {
val CAMERA_WIDTH:Int = 720
val CAMERA_HEIGHT:Int = 480
}

Next we need to inherit the BaseGameActivity. Add extends BaseGameActivity to your class and accept the import. Implement the following methods:
  • onLoadEngine:Engine
  • onLoadResources
  • onLoadScene:Scene
  • onLoadComplete
The easiest way to do the implementation is to right click the code region of the class and select generate (or just alt+insert) -> implement methods... -> select the methods.

Unfortunately the result is not clean and you'll need to add an override keyword in front of every def generated.

package com.studfarm.example

import org.anddev.andengine.ui.activity.BaseGameActivity

class ParticleSystemSimpleExample extends BaseGameActivity{

override def onLoadScene() = null

override def onLoadResources() {}

override def onLoadEngine() = null

override def onLoadComplete() {}
}

object ParticleSystemSimpleExample {

}
Next we'll implement the methods.

OnLoadEngine

When the program is loaded, show a text to the user and set the camera.

override def onLoadEngine:Engine= {
Toast.makeText(this, "Touch the screen to move the particlesystem.", Toast.LENGTH_LONG).show
this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT)
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
}
onLoadResources

Loads all resources for the application/game

override def onLoadResources {
this.mTexture = new Texture(32, 32, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mParticleTextureRegion = TextureRegionFactory.createFromAsset(this.mTexture, this, "gfx/particle_point.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
particle_point.png is placed under /src/main/resources/assets/gfx/ folder

Create the Scene:
override def onLoadScene:Scene= {
this.mEngine.registerUpdateHandler(new FPSLogger());

val scene = new Scene(1);
val particleEmitter = new CircleOutlineParticleEmitter(CAMERA_WIDTH * 0.5f, CAMERA_HEIGHT * 0.5f + 20, 80);
val particleSystem = new ParticleSystem(particleEmitter, 60, 60, 360, this.mParticleTextureRegion);

scene.setOnSceneTouchListener(new IOnSceneTouchListener() {

override def onSceneTouchEvent(pScene:Scene, pSceneTouchEvent:TouchEvent):Boolean= {
particleEmitter.setCenter(pSceneTouchEvent.getX(), pSceneTouchEvent.getY());
true;
}

particleSystem.addParticleInitializer(new ColorInitializer(1, 0, 0))
particleSystem.addParticleInitializer(new AlphaInitializer(0))
particleSystem.setBlendFunction(GL10.GL_SRC_ALPHA, GL10.GL_ONE)
particleSystem.addParticleInitializer(new VelocityInitializer(-2, 2, -20, -10))
particleSystem.addParticleInitializer(new RotationInitializer(0.0f, 360.0f))

particleSystem.addParticleModifier(new ScaleModifier(1.0f, 2.0f, 0, 5))
particleSystem.addParticleModifier(new ColorModifier(1, 1, 0, 0.5f, 0, 0, 0, 3))
particleSystem.addParticleModifier(new ColorModifier(1, 1, 0.5f, 1, 0, 1, 4, 6))
particleSystem.addParticleModifier(new AlphaModifier(0, 1, 0, 1))
particleSystem.addParticleModifier(new AlphaModifier(1, 0, 5, 6))
particleSystem.addParticleModifier(new ExpireModifier(6, 6))

scene.getLastChild().attachChild(particleSystem)
});

return scene;
}
All done. Run the mvn clean package. You should now have a working application. You can test it with the Android emulator or with a real Android phone.