Search Unity

Serious question here, do you even need AOT on iOS?

Discussion in 'General Discussion' started by techmage, Nov 7, 2014.

  1. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085
    So as I understood, AOT was necessary on iOS because apple disallowed all interpreted languages to be used on Apps in the App Store. Primarily as I understood for security reasons.

    But did anyone notice that they updated that clause?
    http://www.gamasutra.com/blogs/KerryJones/20130604/193593/iOS_interpreted_code.php

    You CAN have interpreted code on iOS just as long as all the code and interpreter comes in the original App download.

    Did I miss something here? Doesn't this mean that AOT is not needed on iOS anymore? That AOT can be scrapped, the hangup for Mono iOS licensing can be left behind, and the new Mono put onto the current Unity without IL2CPP?

    Why is Unity still AOT compiling for iOS? I presume theres a reason that I don't understand, and all of UT didn't just miss that clause change in Apple's TOS.

    Also on another note. For some of my projects the inability to essentially put new code and functionality into an App remotely, by download, has been a huge hindrance. I would think that, given that Unity is like the #1 game engine on iOS and making Apple lots of money. That Unity could actually work with Apple directly to better enable Mono, and it's full flexible feature set, to be used on the App Store. Like the ability to include new classes with new levels in the AssetBundle.

    ALSO, given Apple's clause, how did the the apps that let your run user-made Python and LUA code get onto the App Store? Clearly there is some set of conditions or something in which Apple will allow new interpreted code to be put into the App externally. It'd be really nice if Unity could get friendly with Apple to figure this out.
     
    Last edited: Nov 7, 2014
  2. makeshiftwings

    makeshiftwings

    Joined:
    May 28, 2011
    Posts:
    3,311
    As I understand it, it is not that there's a policy against interpereted languages; it is that the iOS kernel specifically doesn't allow executable code to be generated at runtime, so Reflection.Emit doesn't work.

    The reason that Unity can't upgrade Mono doesn't have anything to do with JIT or AOT specifically; it is that both iOS and Android do not allow DLL's; all code in an app has to be statically linked, including the Mono Runtime, and the Mono Runtime is under the LGPL license. The LGPL license basically means you can use it for free if you use a DLL, but if you statically link it, you have to buy a separate license, and Xamarin is apparently demanding extortion-level amounts of money from Unity in order to let them upgrade their Mono license. IL2CPP will allow us to avoid needing to include the Mono runtime in builds, which means Unity only needs the Mono runtime in the editor where a DLL can work, thus getting around the block from Xamarin.
     
  3. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    7,960
    Sort of. What you are missing is that you shouldn't give any consideration to some random blog post from over a year ago by an arm-chair lawyer getting worried about something he clearly doesn't understand. ;)

    A) the apps mentioned are not actually executing code. It is using scripting to trigger existing events within an app (which in the python case is python wrapped in the app). It is an abstraction that is in line with intent. It cannot do anything outside of the scope of the app (lua is just scripting). And more importantly, if you are downloading an app is designed to runs scripts you input or initiate, it is functioning as described. If I download a match-3 game, it sure as hell better not be running patches or executing code/injecting new functionality,

    B) The ability to add new functionality or change the core functionally outside the scope of the intent and description of the downloaded app is very, very bad. When I download any app from the app store is expected to function as expected and presented. If a developer can change any aspect of that by simply internally download new "code", it is a massive fail on every level (but mostly security).

    You can inject content, but not code/functionality that alters the app. If a developer needs to change the functionality of the app, they need to do a client update (or just plan ahead). This ensures that it goes through a verification process, and more importantly that the user is notified about (and given the option to reject) changes.

    Nothing to worry about, nothing has changed, and it is not a "problem" because some blogger is confused.
     
  4. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,075
    uh IL2PP is a really good thing. It's faster. This isn't just licensing, it's an exciting thing for performance too, and not to mention a path for WebGL.

    Lack of AOT probably means your entire source code is also up for grabs. Having it AOT compiled is an extra layer I'd probably like on desktop and console too.
     
  5. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085
    I thought that the reason that Reflection didn't work on iOS was because of it being AOT compiled and that's it. If you compiled a MonoTouch app (non-unity) to iOS without AOT, and let it run as interpreted byte code, then reflection would just fine.

    And I thought the dynamic linking clauses were no longer in effect either?
     
  6. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085

    A) But thats all Mono is too... although the byte code is technically not a 'script'. But when you submit your app to be reviewed, Apple scans through your code and sees what calls into the OS you are making to prevent trickery. The python interpreter I imagine gets through because they can scan the actual interpreter and see it's not doing anything unwanted. In the same way they should be able to just scan the Mono byte code interpreter and see too that it isn't doing anything unwanted.

    B) This is a thing... But still I imagine some solution could be had.
     
  7. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085

    I agree in most instances it'd be ideal. But I do a lot of enterprise applications and really the ability to stick a new C# DLL into a unity app by just downloading it and not having to install a new IPA would seriously like be life changing.
     
  8. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    7,960
    It's not about ability, it is about expectation and intent. A user downloads the python interpreter to run python scripts. Scripts entered and executed by the user. That python app would be rejected if it updated itself by downloading scripts and executing them.

    It IS the solution. You are viewing it as a problem, or limitation or something that was overlooked. It isn't, it is by design for very good reason. If you need to update the client, you distribute it as an update through a trusted channel and the user is informed.

    Again, what some random blogger got all worried about isn't actually a real concern. It doesn't present a problem to developers, it doesn't limit what you can do with your app. There simply is no valid reason a game needs to download and execute code that would justify having a massive security hole. It's just a part of developing games for iOS.
     
  9. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085

    It would be nice if you could, for example, release a game with 1 level included in it. Then release additional levels later, that include new classes, not requiring the user to update through the App Store before download.
     
  10. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,562
    Reflection actually does work on iOS, it's just finnicky and things like Emit are not allowed. You cannot dynamically generate code. You also can't construct objects that you haven't constructed somewhere in your code because the AOT compiler has no idea what to do with it and chucks a wobbly.

    That being said, I think everyone missed a very important bit about the OP's comment.... although it was touched upon in the comments about "scripting". The comment and the terms he was referring to were about "Interpreted" code, of which Unity games certainly are not. They are compiled... and the compiled code is translated either via AOT or JIT but never interpreted.

    A good example of intepreted code is in-browser Javascript, or PHP or classic ASP. .NET / Mono / C++ are not interpreted. :)
     
  11. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    14,992
    Both V8 (Chrome's JavaScript) and SpiderMonkey (Firefox's JavaScript) compile their code.
     
  12. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,562
    So does IE actually but I didn't really count it because it's a browser feature and not really part of the spec. By definition, JavaScript is still an interpreted language... browsers have just broken that mold. ;)
     
  13. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    12,312
    Why would a new level require new classes or other low level code?

    As is you can easily release new levels that don't require client updates (in its early development this was the exclusive manner of loading levels for Master Thief), and with little difficulty and/or a little planning they can have new functionality. I'm with Zombiegorilla, I don't see a problem that this would solve which is worth the additional problems it would create. And if you are releasing an update that adds functionality I can't imagine why you'd want to hide it - I for one happily tell my players if I release an update which improves the game!
     
    zombiegorilla likes this.
  14. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    7,960
    We do that now. (And in the past). All of our levels are data driven, I could go in our level editor right now and create as many as I want and push them to the game. Including assets (characters/buildings/rules/etc).

    The trick to doing this well is planning ahead. Again, using our game as an example, there are tons of features, abilities, hooks and things of that nature that are currently in the live game that are not used. They are there for content that will be added over the upcoming year. If you are familiar with Star Wars, there are some pretty common aspects that aren't in the game, or at least don't appear to be. In reality, they are all there under the hood, ready to be used by content that requires them. Building flexible and abstracting where it make sense, means you don't need to push clients all the time. Also planning ahead.
     
  15. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    7,960
    Exactly. And a side effect is that you are designing better code/structure ultimately (if you weren't already). Like when you switch to a strongly typed language, it may seem like a bit of burden, but pays off. If your level feature are modular, and well planned out, you are less likely to have problems than if you are bolting on new classes for every little thing. If you are creating levels that require new classes/code, your methodology for handling content is flawed in the first place, or just didn't think ahead.
     
  16. lmbarns

    lmbarns

    Joined:
    Jul 14, 2011
    Posts:
    1,474
    Are you guys using asset bundles for loading content after the fact? I haven't really utilized them but would like to.
     
  17. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    7,960
    Heh... we kinda go a little overboard. ;) Pretty much the installed game is just core game code and some ui assets. We load virtually everything after the fact via asset bundles. Upshot is that pretty much all the game content can be modified without a client update. Downside, it makes the pipeline a huge aspect of development, and quite a bit cumbersome at times. I wouldn't recommend going the route we have, there
     
  18. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    12,312
    Master Thief is tile based with an XML-based level descriptor format. Each tile has an ID, and levels are just XML files which essentially list what ID and orientation goes where. Tiles are loaded as resources and... job done. On top of that there's stuff like key, loot and guard locations, properties for some tiles (like doors), and of course the paths which guards walk along - all just simple data.

    A cool thing about this is that early on we made a level editor which let us browse, load, edit and save levels stored on a web server. So we could all sit around making levels on our iPads or laptops, save them back to the server, and then play each other's levels all without ever using the Unity Editor.
     
  19. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,540
    No. AOT is necessary because you can't JIT (just-in-time compile code) on iOS (and most of consoles too). Technically, the OS does not allow to create memory pages that are both "writable" and "executable".

    Sure. Interpreted code is also very, very, very slow.

    I don't see how this relates to Mono at all, really. Also, Mono does not have an interpreter; it's either JIT (can't do that on iOS) or AOT (can do that on iOS, which is what we're using).
     
    Meltdown, Ryiah and makeshiftwings like this.
  20. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085
    Is that still true... People in this thread would indicate the write and execute memory limitation was removed to.
    https://code.google.com/p/v8/issues/detail?id=1312

    Also, not that I doubt you, but I am curious to know, if performance is such a big issue, then why is Android not fully AOT compiled like iOS?
     
  21. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    14,992
    Not according to the last comment on the referenced github page.

    Further one of the Google Code comments indicates that, while the program does use a Just-in-Time compiler, it isn't actually running the code on the CPU natively but rather through a processor simulator. Essentially it is interpreted.

     
    Last edited: Nov 12, 2014
  22. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    26,075
    Because interpreted code != AOT or JIT.
     
  23. techmage

    techmage

    Joined:
    Oct 31, 2009
    Posts:
    2,085
    oh I thought JIT fell under the context of interpreted code...

    I will admit I am very retarded in some way. That is why i make these threads before I go off repeating such things in mass.
     
  24. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,562
    performance between AOT and JIT is very similar as well. AOT just generally gives you a little quicker startup time since it's not compiling everything up front.
     
    shkar-noori likes this.
  25. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    12,312
    They generally produce the same thing, right?

    My understanding is that the main benefit of JIT is hotspot optimisation - re-compiling localised parts of the native binary from the bytecode to take better advantage of the CPU based on data the compiler can't have, such as statistical analysis of the execution characteristics for the current run.
     
  26. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,562
    sort of. I didn't actually explain it well. JIT compiles the main bits up font and the methods at runtime. It takes a bit of a performance hit there but gains back because it can do runtime optimizations based on platform.

    AOT compiles everything ahead of time. It does this when building, before even deploying to the device. Then it loads those precompiled blocks at runtime. Problem is, you get no runtime optimization. That's also why it has trouble with generics and reflection. Generic interfaces require static code analysis for some things which it can't do. Also, reflection fails when trying to use the activator to construct objects that have never been manually constructed elsewhere because the aot system has never seen the constructor and if that block of code hasn't been previously loaded it doesn't know how to execute it and pukes.
     
  27. isidro02139

    isidro02139

    Joined:
    Jul 31, 2012
    Posts:
    72
    I have a question regarding:
    I'm making an RPG in Unity for iOS. I want to be able to update the damage functions to rebalance the game after launch without requiring users to download a new binary.

    If I store simple arithmetic functions that take (non-changing) player stats as input in strings in the backend, can I update them in the App and run an interpreter included in the original binary like http://www.moonsharp.org/getting_started.html without worrying about Apple's review process negging this as a violation of their iOS SW terms?

    Thanks in advance for any feedback or ideas!
     
  28. zombiegorilla

    zombiegorilla

    Moderator

    Joined:
    May 8, 2012
    Posts:
    7,960
    Yes.