Saturday, January 28, 2012

Porting Unity3d's coroutines to Android/iOS

I have been quite away from Android development.
I have been coding a game for iOS: Shaman Doctor and now I am testing Unity3d.
This blog describes my wish to port that coroutines to other platforms.

Introduction

In Unity3d I am coding in C# and I learned about coroutines.
To give you an idea of how they work, check this blog posts:

Unity3d implementation for coroutines is somehow different.
To understand what I am saying, read the first link.
It gives an explanation of how it should be working inside Unity3d.

Usage
In the code where I use Unity3d coroutines is where I need to do a state machine code.
A super simple example would be:

Imagine you need to add a button but you can only click it once every two seconds.
I can imagine two possible implementations. Bare in mind that I didn't test this code.

Using time. objective-c code:

#define SECONDS_TO_ENABLE 2
@synthesize lastTimeUsed;

@implementation PotionController

- (id)init {
self = [super init];
if (self) {
self.lastTimeUsed = 0;
}

return self;
}

- (void)click {

NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSTimeInterval difference = fabs(self.lastTimeUsed - now);

// if two seconds haven't pass, return.
if ( difference < SECONDS_TO_ENABLE ) {
return;
}

self.lastTimeUsed = now;

// Click logic here.
}

Disabling and sending an enable msg to be run after 2 seconds. Android code.

In this case it's a done with the View's postDelayed() method. It could be done
with a Handler as well.

public void click(final View view) {
view.setEnabled(false);

// Send a postDelayed to turn it on again.
view.postDelayed(new Runnable() {

@Override
public void run() {
view.setEnabled(True);
}

}, 2000L);

// Click logic here.
}

The same thing done with C# inside Unity3d would be:

void OnMouseDown() {
StartCoroutine(this.ClickLogic());
}

private IEnumerator ClickLogic() {
// Click Logic
yield return new WaitForSeconds(2.0f);
}

What happens when you click more than once in a two seconds time frame?
Honestly, I am not sure what happens when you call StartCoroutine() when
a previous coroutine was started, but it works.
I hope that someone can clarify this.

Now try to port this code from Unity3d to android or iOS.

IEnumerator TellMeASecret()
{
PlayAnimation("LeanInConspiratorially");
while(playingAnimation)
yield return null;

Say("I stole the cookie from the cookie jar!");
while(speaking)
yield return null;

PlayAnimation("LeanOutRelieved");
while(playingAnimation)
yield return null;
}

How can this be used in Android/iOS

Ordinary coroutines
Although Unity3d's coroutines are different from the ordinary, I wanted to know if it was possible to implement them in Android/iOS.

Android
My first google search about this was "java coroutines" and I learned that ordinary coroutines would need one of this options:
  • Modified JVMs (Can't be used in Android)
  • Modified Bytecode (Can't be used in Android)
  • Platform-specific JNI mechanisms (Not sure if it would work in Android)
  • Thread abstractions (Not sure how performant would work inside Android)
I feel this is a dead end for Android.

iOS

I didn't research a lot about iOS.
Here is a list of links that look interesting:

Unity3d implementation alike

After reading Richard Fine's blog post I thought it would be interesting to achieve something similar to that in the different platforms.
My big doubt is finding a way to implement something similar to an IEnumerator.

Using scala

Inside cocos2d-iphone
I am not sure if cocos2d's internal would support something like this.

Inside cocos2d-x
This is the real challenge.
Finding a way to implement Unity3d's coroutines but keeping it multiplatform.
Perhaps finding a way of doing it in C++.

What do you guys think?

Friday, January 27, 2012

Google's Android Market vs Apple's App Store

Two years ago we created an app for ios and Android called SteamMobile.
One of our devs from NASA Trained Monkeys is a Steam user and wanted to have a Steam application in his device. There were a lot of forum post asking Steam to create one but there was no official response saying they would, so we made our own.


Yesterday, the official Steam app was released in the App Store and in the Android Market.
I would like to share with you guys what happened to our applications.


Application prices

iOS
  • Steam Mobile for iOS was released as a paid app (2.00 U$s)

Android
Android had two versions.
  • Free with ads
  • Pro version with no ads (1.00 U$s).

When we released the application we felt that selling an app in the Android market was harder so we opted for a free version.


Getting paid

This is how you we set everything up.
Remember we are from Argentina so it might be different for you.

iOS
  • The AppStore allows you to configure a bank account and Apple makes a deposit when you reach certain amount.
  • If you need to change your bank account you can do it without any issue.

Android

  • The Android Market lets you set up your account with a credit card from your country of origin.
  • You CAN'T change the credit card associated with your account once configured.
  • You get paid through Western Union.
  • Western Union limit on transactions per month is USD 8500.00
  • Western Union pays in ARS and the exchange rate is lower than the official.

Even though USD 8500 might be plenty for an indie it's a big limitation.
I would hope that if you make a big release, Google will do something different for you but it's a risk you might need to take.


When we learned about Western Union not paying in american dollars we wanted to find another way of getting the money. The only possible solution is to get a different country credit card to use a different way of payment. BUT you can't change your credit card. You would need to create a new one losing your stats. We also didn't find a way to deal with our taxes correctly since we can't make an invoice for a transfer via WU.

On the other hand, Apple pays in a bank account allowing you to clear your tax issues easily. We needed to change the bank account and there were no issues at all.

This really made us think over releasing stuff in the Android Market.
Although Apple has stricter rules, it's less risky.

Copyright issues

As you might have noticed, Steam Mobile comes with a copyright infringement.
It was clear that our application was going to be reviewed by Valve sooner or later.

That day has come and this is how Apple and Google worked it out.

iOS
On 10/3/11 Apple sent an email saying:

On 9/27/2011, we received a notice from Valve Corporation that Valve Corporation believes your application named "Steam Mobile" infringes Valve Corporation's intellectual property rights. In particular, Valve Corporation states that "...All images in (your application) are owned by Valve Corporation".

You can reach Valve Corporation through XXXXXXX (phone: XXXXXX, email: XXXXXX). Please exchange correspondence directly with Valve Corporation.

We look forward to receiving written assurance that your application does not infringe Valve Corporation's rights, or that you are taking steps to promptly resolve the matter. Written assurance may include confirmation that your application does not infringe Valve Corporation's rights, an express authorization from Valve Corporation, or other evidence acceptable to Apple.

Under our terms of agreement, Apple may remove your application from the App Store at any time. You may remove your application using the steps provided below, for example, while you make any necessary changes to your application.

Visit iTunes Connect at http://itunesconnect.apple.com

1) Access your app in the Manage Your Applications module.
2) Click on the "Rights and Pricing" button from the App Summary Page.
3) Click on the "Deselect All" button to uncheck all App Store territories.
4) Click on the "Save Changes" button.

We look forward to receiving confirmation from you within 5 days.

Thank you for your immediate attention.

This ended in an exchange of emails with Valve and Apple and we modified the application to meet every copyright issue. We needed to change the name and place a text saying that the application was powered by the Steam API. You can see it here.


Android
Yesterday Valve released their official Android and iOS app and Steam Mobile was removed from the Android Market. We got an email from removals at google saying:

Hi,

Google has been notified, according to the terms of the Digital Millennium Copyright Act (DMCA), that your application, SteamMobile Pro, package ID com.nasatrainedmonkeys.steamMobilePro, allegedly infringes upon the copyrights of others, and has been removed from Android Market. Please review the Content Policies and Business and Program Policies before you create or upload additional applications. Please note that violations may result in a suspension of your Android Market Publisher account, and may also result in actions, including possible suspension, taken against any associated Android Market publisher, AdSense, Google Checkout, or AdMob accounts.

Please note that we have included a text copy of the Infringement Notice we received for your reference.

The DMCA is a United States copyright law that provides guidelines for online service provider liability in case of copyright infringement. See http://www.educause.edu/Browse/645?PARENT_ID=254 for more information about the DMCA, and see http://www.google.com/dmca.html for the process that Google requires in order to make a DMCA complaint.

Google may reinstate these materials into Android Market upon receipt of a counter notification pursuant to sections 512(g)(2) and (3) of the DMCA. For more information about the requirements of a counter notification, and a link to a sample counter notification, see
http://www.google.com/support/bin/request.py?contact_type=lr_counternotice&product=androidmarket

If you have legal questions about this notification, you should retain your own legal counsel.

Regards,
The Android Market Team.


Text copy of DMCA complain:
AutoDetectedBrowser: Internet Explorer 8
AutoDetectedOS: Windows 7
IIILanguage: en
IssueType: lr_dmca
Language: en
agree1: checked
agree: checked
android_app_developer_10: xxxx
android_app_developer_11: xxxx
android_app_developer_12: xxxx
android_app_developer_13: Nasa Trained Monkeys
android_app_developer_14: xxxx
android_app_developer_15: xxxx
android_app_developer_1: xxxx
android_app_developer_2: xxxx
android_app_developer_3: Nasa Trained Monkeys
android_app_developer_4: xxxx

...

android_app_name_10: xxxx
android_app_name_11: xxxx
android_app_name_12: xxxx
android_app_name_13: SteamMobile Pro
android_app_name_14: xxxx
android_app_name_15: xxxx
android_app_name_1: xxxx
android_app_name_2: xxxx
android_app_name_3: SteamMobile
android_app_name_4: xxxx

...

android_app_url_10: xxxx
android_app_url_11: xxxx
android_app_url_12: xxxx
android_app_url_13: https://market.android.com/details?id=com.nasatrainedmonkeys.steamMobilePro&feature=search_result
android_app_url_14: xxxx
android_app_url_15: xxxx
android_app_url_1: xxxx
android_app_url_2: xxxx
android_app_url_3: https://market.android.com/details?id=com.nasatrainedmonkeys.steamMobile&feature=search_result
android_app_url_4: xxxx

...

companyname: Valve Corporation
country_residence: US
description_of_copyrighted_work: Steam logo and/or Steam name
dmca_signature: xxxx
dmca_signature_date_day: 26
dmca_signature_date_month: 1
dmca_signature_date_year: 2012
full_name: xxxx
hidden_dmca_category: text
hidden_product: androidmarket
location_of_copyrighted_work:
https://market.android.com/details?id=com.valvesoftware.android.steam.community
represented_copyright_holder: Valve Corporation



Conclusion

Apple has shown that it has a more mature market and it has solved the issue way better than Google. Don't get me wrong, I still prefer coding for Android but this type of things makes me wonder.

Google, don't be evil!