Experimental v73b now up! [MONKEY NEWS]

Monkey Forums/Monkey Programming/Experimental v73b now up! [MONKEY NEWS]

marksibly(Posted 2013) [#1]
[edit]
v73b now up with some minor bug fixes and tweaks...
[/edit]

Hi,

Experimental Monkey73a is now up, featuring a new MonkeyStore class for making in-app purchases.

Notes:

* Only consumable and non-consumables are currently supported. No subscriptions or downlable content yet. Consumables are emulated on Android, so you must specify the type (consumable or non-consumable) of each product when initially adding products to the store. On iOS, this type *must* match the type you selected in iTunes Connect, or strange things will probably happen.

* It's up to you to track purchases and I've added a brl.json module to help with this sort of thing. There is a GetOwnedProductsAsync method in there for 'recovering' all non-consumable purchases in cases where the app is reinstalled, but you may not need to use it. Non-consumables can be safely bought multiple times anyway (the user is only charged for the first purchase), so if an app is reinstalled the user can simply 'rebuy' all non-consumables they already own. If you do use GetOwnedProductsAsync, I recommended doing so only in response to a user action (eg: via clicking on a 'Restore Purchases' button, not just in OnCreate) as on iOS it will cause an app store 'login' prompt to appear - which will look dodgy if it just happens out of the blue.

Testing IAP is *hard*. The general idea on both Android/iOS is that you create 'test' accounts to test with, and add these test accounts to GooglePlay Dev COnsole and/or iTunes Connect. Test are accounts are generally just email address/password combos, although on Android you'll have to provide more details the first time you use the test account.

* On Android, your app must be signed and a version uploaded (but not necessairly 'published') to your Google Play developer account. I've added an #ANDROID_SIGN_APP config setting to trans for signing apps - see: Android SDK in docs for more info.

* On Android, repeated use of a test account sometimes appears to trigger some kind of 'fraudulent transaction' logic, after which time you app will report 'cannot process transaction' when you attempt to buy something and you'll receive a 'transaction cancelled' email. Solution: wait until things return to normal, or create a new test account and use that instead. I have no idea what causes this, but I don't *think* it's anything I'm doing...

* On Android devices, you can create a new user for your test account, and it doesn't have to be the 'primary' user, but you will need to 'always allow' USB debugging for the primary user before using the test user. Also, you may need to uninstall old versions of your app from the primary user before testing.

* On IOS, your app's 'BundleId' must match the BundleId in iTunes Connect. Currently, the only way to change BundleId is in xcode.

* On iOS, DO NOT TO LOGIN TO THE APP STORE VIA SETTINGS USING YOUR TEST ACCOUNT! Instead, login when making a test purchase. Otherwise, you'll end up in a strange [sanbox environment] loop when trying to test IAP.

There's a bananas/mak/iaptest demo in the release, but it wont work 'as-is' - you'll need to add a keystore file for android and change the BundleID for ios, and change the CONSUMABLES and NON_CONSUMABLES arrays to match your product ids.

There's also some XNA fullscreen stuff in there which I'll eventually unify with the GLFW stuff, but should be usable as is for now - see bouncyaliens for a demo.


***** v73b *****

Fixed win8 image loader throwing exception if image not found.

transcc added support for mxmlc debug builds to flasher builder.

Fixed some flash audio issues - added flash support for ChannelState and MusicState.

Fixed win8 async image/sound loaders.

Fixed some compile errors in thread.cs and databuffer.cs


***** V73a *****

Added iaptest to bananas/mak.

Changed default MOJO_AUTO_SUSPEND_ENABLED to true for relevant targets.

Added brl.json module.

Added methods ReadString and WriteString to Stream.

Added methods ReadAll and WriteAll to Stream.

Added brl.monkeystore module.

Added CC_OPTS app config setting for stdcpp target only.

Added XnaGame and XnaDisplayMode classes to xna target:

Class XnaGame

Function GetXnaGame:XnaGame()

Method GetXnaDesktopMode:XnaDisplayMode()
Method GetXnaDisplayModes:XnaDisplayMode[]()
Method SetXnaDisplayMode:Void( width:Int,height:Int,format:Int,fullscreen:Bool )

End

Class XnaDisplayMode
Field Width:Int
Field Height:Int
Field Format:Int 'currently unused, always '1'.
End

eg: XnaGame.GetXnaGame().SetXnaDisplayMode( 1024,768,1,True ) 'always use '1' for format for now...

No 'window-less startup' support in XNA.

See bouncyaliens for a demo.




Xaron(Posted 2013) [#2]
Wohoo! That is great, thanks so much Mark!!

On Android, repeated use of a test account sometimes appears to trigger some kind of 'fraudulent transaction' logic, after which time you app will report 'cannot process transaction' when you attempt to buy something and you'll receive a 'transaction cancelled' email. Solution: wait until things return to normal, or create a new test account and use that instead. I have no idea what causes this, but I don't *think* it's anything I'm doing...


Yeah, this is something you can't do anything against it. Happened to me and others as well from time to time..


Tibit(Posted 2013) [#3]
Yes! Awesome :)

I recommended doing so only in response to a user action (eg: via clicking on a 'Restore Purchases' button, not just in OnCreate)
On Google Play, Google recommends that you do call it in OnCreate to catch that rare exception that something goes awry just at the purchase even for consumables. Here is a TALK from Google I/O where they show the GooglePlay IAP system: http://youtu.be/DgcJPIRpfSk (around 15min mark). On iOS (if you have non-comsumables) you "need" a button for this to get accepted, no persistent items and that button can be safely ignored.

So in Monkey, is it recommended/needed to have a restore purchases button on Google Play as well? Or should we #IF target= this functionality?


marksibly(Posted 2013) [#4]
> On Google Play, Google recommends that you do call it in OnCreate to catch that rare exception that something goes awry just at the purchase even for consumables.

It already does this behind the scenes for consumables - ie: in case something went wrong between the background 'buy'->'consume' steps the last time a consumable was bought.

> On iOS (if you have non-comsumables) you "need" a button for this to get accepted, no persistent items and that button can be safely ignored.

Ok, so this turns out to be an app store requirement:


"...if your application supports product types that must be restorable, you must include an interface that allows users to restore these purchases. This interface allows a user to add the product to other devices or, if the original device was wiped, to restore the transaction on the original device."



So yes, on iOS, if you have non-consumables, you'll need a restore button. I assume 'product types that must be restorable' means non-consumable...?

On Android, you can choose to either do the same, or possibly automate the process once the store is successfully open with some #If code...


Paul - Taiphoz(Posted 2013) [#5]
Something I wonder about when it comes to IAP is who handles things if the customer has a complaint, I worry that it might be the dev, I also worry about complaints where nothing can be done, so many people eager to take legal action these days, is there any protection for the dev ?


Paul - Taiphoz(Posted 2013) [#6]
oh how rude.. WOW SWEEEETT... thanks for the update.


Tibit(Posted 2013) [#7]
> I assume 'product types that must be restorable' means non-consumable...?
Yes that is how I have understood it

> It already does this behind the scenes for consumables
Sounds great. Did I get this right:
Having a restore-button and calling GetOwnedProductsAsync something I'll do on both Android and iOS if I have non-consumables, but never for consumables because it is already taken care of by Monkey. On iOS I need a button because of their app store requirements and on Android I can hide the button if I want and call GetOwnedProductsAsync in OnCreate using a #if target = "android".

And great that you added instructions for creating test accounts, it can definitely be a pain, especially that iOS login thing.

Note: It would be nice if all this went into the docs for future reference, if it isn't already :)

@Taiphoz - on iOS Apple takes care of it. You pay the cost. So someone buys for 100$ and then complains to apple. Remember apple took 30% of those 100$, which is 30$ but you get to pay 100$ back to the user, meaning you pay 30$ extra.

On Google Play the developer is responsible for handling the requests and issuing returns.

I doubt someone would sue a company that isn't filthy rich, but I have no idea if it has/can/ or does happen.


marksibly(Posted 2013) [#8]
> Having a restore-button and calling GetOwnedProductsAsync something I'll do on both Android and iOS if I have non-consumables, but never for consumables because it is already taken care of by Monkey.

Yep.

> On iOS I need a button because of their app store requirements and on Android I can hide the button if I want and call GetOwnedProductsAsync in OnCreate using a #if target = "android".

Almost - you should only call GetOwnedProductsAsync once OpenStoreAsync succeeds, eg: inside OnOpenStoreComplete (if result=0).


SLotman(Posted 2013) [#9]
IAPs? Woohooo! Wouldn't expect it that soon ^_^

Now that celebration is over... IAPs make my head hurt! x_X

All this 'consumables' and 'non-consumables' talk makes me dizzy - so in theory I can't sell coins that could be used to buy 'permanent' items, like weapons? I would have to sell the weapons themselves?

LOL, I just updated to .72b and was testing compiling to win phone 8 (still waiting approval on the MS store, and trying to figure out everything needed to submit an app there) - now .73a is here :)

Am I right to assume this works for iOS and Google Play only? IF I was to upload my game to other stores (Amazon, Samsung, SlideMe) a new store implementation will be necessary, right?

Edit: I can see other targets as well? Android v2, Windows 8 XAML game...? What are those??


John McCubbin(Posted 2013) [#10]
Good stuff especially the XNA resolution changes and fullscreen toggle, I think this pretty much means monkey can be used to create games for PC / Mac Game portals such as Big Fish Games.

The IAP stuff is also great, I've been using a self made module for a while but it did not cover consumables so this is great.


Paul - Taiphoz(Posted 2013) [#11]
John, you had any situations like that, if I recall you have some IAP in one of your games don't you ?

I's there a minimum IAP Price for either market ? and you mentioned iOS and Android is there anything on Windows Store IAP's?

If there is no minimum IAP price I think if and when I use it, I will keep all the prices really low, and spread the load over a number of items so that if, for example some poor guys son or daughter decided to buy everything I would not be the one footing the bill.

And WTF is with Apple, I really hate them some times, they take 30% and then expect you to still refund the full amount, whats up with that.


Xaron(Posted 2013) [#12]
At least for Apple you have to use their price tiers which is $0,99 minimum.


SLotman(Posted 2013) [#13]
And WTF is with Apple, I really hate them some times, they take 30% and then expect you to still refund the full amount, whats up with that.

Is this serious? Apple charges you the 30% when someone asks for a refund????


SLotman(Posted 2013) [#14]
Something wrong on GLFW: on Fullscreen mouse is always centered on screen, I can't move it or click anywhere!

Edit: Weird - it only happens in *one* of my games...
Even weirder: VMouseX() and VMouseY() reports the correct position. But the (real) mouse cursor is locked in screen center!

A-ha! I can reproduce the problem:



It was my custom "showmouse" routine! It only calls windows "ShowCursor" API, so I don't know why the mouse gets stuck like that.


Xaron(Posted 2013) [#15]
Regarding refunds: This is more a rare case with Apple. As long as you don't do some fraud stuff Apple very seldom does any refund at all.


Paul - Taiphoz(Posted 2013) [#16]
Is the apple process automated ? as in will they simply take the refund from your bank and then alert after the fact ?

I wonder how Android devs handle this then, if they themselves are responsible for handling refunds, is there not a possible No Refunds policy for mobile or do the markets prevent a dev from stating that in their games.

I mean clearly if some one blows hundreds of money on their dads credit card it needs to be handled, whats more got me curious is those people who stress over 99p and ask for a 99p refund, im sure the bank charges for dealing with a refund will probably cost more than the refund itself lol.

some of you must have dealt with a refund on Android, or iOS , would love to know how you dealt with it.


Xaron(Posted 2013) [#17]
The Apple process is not automated, it involves some people at Apple, so it's more likely for fraud apps but not the "normal" case.

Refunds on Android are possible within 15 minutes and I had those from time to time. As a dev I'm not involved in this.

Refunds at all are not a big issue to me as long as you don't rip off your customers.


Paul - Taiphoz(Posted 2013) [#18]
So those android refunds that you had, how did that process happen, what steps were involved, im not worried about fraud, just worried about customer satisfaction.


John McCubbin(Posted 2013) [#19]
Sorry Paul I was away shopping :P

The price tiers on apple atleast are fixed, so its like $0.99, $1.99, $2.99 etc you cant set them to an arbitrary amount.

I've never had anyone ask for a refund or accidently spend when they did not intend to, but I have never had consumable IAP items, and that is often where that arises.


Xaron(Posted 2013) [#20]
The Google refund is automated. Actually you don't have anything to do with it. So if one buys something for $0,99 and wants to cancel it, he can do it within 15 minutes without problems. You just never get that money. That's it. Easy.


dragon(Posted 2013) [#21]
what is the difference between consumables and non-consumables ?


Raul(Posted 2013) [#22]
non-consumables it's a 'product' that after purcahse will always be in the user account: for example the full version of a game.

consumables means 'products' which are used bu the user: "crystals, game money, lifes, etc.."


rIKmAN(Posted 2013) [#23]
This post has just made my weekend...thanks Mark! :)


SLotman(Posted 2013) [#24]
Consumables are things that can be consumed ^_^
Like money, energy, coins... things you buy, use and then you don't have it no more.

Things you buy only once are the "non-consumables". For example, a new hat for your character, or a weapon, or a permanent upgrade.

But back on the release... anyone knows what is the "Android v2" and the "Windows 8 Xaml game"?


dragon(Posted 2013) [#25]
here is NDK-path in config file

i think NDK is used for Android v2 (?)


I do not installed NDK
But v2 crate error: missing module

So i think this is for the future


Erik(Posted 2013) [#26]
Great stuff, here's how to set a borderless window in xna:

xnagame.cs:

#if WINDOWS
  public static void SetBorderlessWindow()
  {
    var _form = System.Windows.Forms.Form.FromHandle( _app.Window.Handle ) as System.Windows.Forms.Form; 
    _form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
    _form.Location = new System.Drawing.Point(0, 0);
  }
#endif


Perhaps we could have a
#if WINDOWS
	public static System.Windows.Forms.Form _form;
#endif

in xnagame.cs so we can access it in our own native modules and do whatever window manipulation we want for desktop targets without having to hack xnagame.cs.


Tibit(Posted 2013) [#27]
While this is probably not the best place to share knowledge about monetization...

A lot of games that sell Hats, Characters, Powerups, Extra Lives, Upgrades and so on and so forth don't have any non-consumable IAPs, such as Clash of Clans.

The reason is that they use a in game currency that you can buy for real money. These gold coins are consumable items. This means the developer does NOT need to keep track of what people buy except locally. You might want to in order to get tacking data and analytics, but you don't have to if you are making a simple game.

However even the most rudimentary game, say space invaders, in which the dev wants the user to "remove ads" needs a non-consumable IAP and then on iOS they "have to" add a restore button. Same goes with "premium in-game upgrade" and "buy level pack".

So remove adds can be more hassle than managing a whole in game shop system that is driven by an in-game currency.

An option to get away cheaper (less dev time) for those doing a premium version of their App is to release two apps, one free and one paid and simply LINK to the paid one from the free one instead of adding a non-consumable item.


dragon(Posted 2013) [#28]
yes, but it is possible to copy your game.
here are "black markets" available where you can download full versions for free.

Or amazon give you free game of the day...



But if you use IAP - you can protect both.
(If someone hack your game, you can do nothing).


Soap(Posted 2013) [#29]
If your game is closely tied to a backend service, and you have checks on the receipts of purchases compared to what they have/are trying to use in their profile, then you can even make hacked versions less usable.

https://developer.android.com/google/play/billing/gp-purchase-status-api.html#overview

http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/StoreKitGuide/VerifyingStoreReceipts/VerifyingStoreReceipts.html


SLotman(Posted 2013) [#30]
Bug(s) found on flash with sounds/music on v73a


MikeHart(Posted 2013) [#31]
What is the story about this Android Game V2 target?


ziggy(Posted 2013) [#32]
I supose it'll be a NDK targer


AdamRedwoods(Posted 2013) [#33]
the new docs are great! (i may be late in noticing this)


TeaBoy(Posted 2013) [#34]
Yup, the new docs are awesome!


Grey Alien(Posted 2013) [#35]
Great thanks Mark! This is good timing for my current game.