Overboy's Recent Forum Activity

    Industry Standard

    Please understand that any mention of "Industry Standard" does a disservice to Construct here. The industry standard in game engines is to remove as many obstacles as possible when it comes to making our games (by being able to extend the engine capabilities for example) and to support and endorse third-party developers. Regarding vanilla features, there is also much to say about the industry standard: for example, the industry standard is to provide some in-editor tools to create UI for our games.

    Encapsulation

    Regarding encapsulation, perhaps indeed, many tools are doing that. But you must realize that popular engines were often designed from the start to provide a vast set of APIs. Because in those engines, the exposed API are used to develop many vanilla features (while again C3 vanilla features don't and won't use SDK2 but the SDK1...)

    Even worse : most of the other engines mentioned here offer significantly more power thanks to their exposed APIs than what the undocumented features of the C3 runtime have allowed us to do until now

    That's right: being able to access 100% of the undocumented features of C3 Runtime/SDK1 is still not as powerful as the publicly exposed APIs of other game engines that do encapsulation. So what about SDK2, which only exposes 1 or 2% of it?

    Given the fact that you're such a small team with limited resources and you have no time to implement popular community suggestions requested for 5-6 years + the track record of rejected suggestions for exposing existing hidden APIs for both the Runtime and the Editor (which sometimes would take a few seconds/minutes) + the overall lack of acknowledgment from Scirra about the issues we're facing in our production:

    How could anyone believe we will still be able to do anything relevant with addons once SDK2 is enforced as the only way to extend the engine ? The current process is already incredibly tedious and painful using 100% of C3 power.

    It looks like the balance that existed with SDK1/Undocumented feature wasn't perfect but at least it was a good compromise

    "Group Handler" addon

    This is a perfect example of what won't be achievable at all soon, and how small the compatibility break issue was before all of this SDK2 madness started. The plugin is 6 years old, totally based on undocumented features, and still works perfectly and would probably keep working as long as Construct exists since the Event Group feature will never be deprecated. (Worst case scenario, a method would have to be renamed in a few years, that's all.)

    This WackyToaster plugin inspired me to create a similar Group Management addon with different features to make it more modular and usable for large games, and it allowed me to solve several major performance issues that I had with my game. Soon it will just be impossible to do that, and my game performance will suffer a lot.

    I made a bunch of private addons that use at least some undocumented features, but those features are used extensively by the C3 codebase and are very unlikely to ever change (I never had to fix any of them since I started making addons). These addons allowed me to solve all the performance and usability issues I was facing when making my Roguelike game using Construct. They also allowed me to get rid of some systems that required 500+ events (unreadable/impossible to maintain) and involved a bunch of weird tricks and workaround, or to overcome many limitations such as the lack of modularity in many aspects of C3 or things that are just 100% impossible to achieve with vanilla stuff.

    >>> This is why I really think you should let advanced users access undocumented features forever at their own risk if they enable the hidden Developer Mode. <<<

    ^ This would be the perfect solution and would solve the issues for Scirra + Addondevs + Gamedevs users, for the reasons i explained in my previous posts : SDK2 would be the default way of doing things, and most of the users would only use SDK2 addons, but powerusers/complex game productions can still use C3 to make their games with the help of SDK1/C3Runtime (because the alternative is that we're forced to use an other engine to make those games)

    Overall the C3 runtime code (SDK1 + undocumented features) is just far more pleasant to use than SDK2/Scripting interfaces, because SDK1 is used across the whole C3 codebase, as Scirra itself is using it to make any features of the engine, it provides a bunch of handy things that are useful to create new stuff.

    SDK2/ScriptingInterfaces on the other hand, is incredibly limited because it's not written by someone who will actually have to use it to create relevant stuff, it's incredibly verbose and the APIS often assume way too much about how the user might want to use them, there is many situations were it does way too much things under the hood VS what i actually wanted to do, so it's sometimes not performant enough for no reason.

    Also Scripting interfaces have been here for 4+ years and they still lack a bunch of obvious APIS, so SDK2 isn't even on par with the most basic stuff we could find in the already very limited documented features of the SDK1

    Among the many many obvious things missing in SDK2 : what about all the methods to manipulate the SOL/picking of an ObjectType in the current eventblock ?

    Even if in several years, the SDK2 implements enough APIS to port the publicly released SDK1 addons that already exists (such as Spriter/Spine/ProUI among many other), with a time-consuming and tedious dialogue between Scirra who have no time for this, and addon dev who have no time for this either, arguing for days/weeks for every single missing APIS :

    What about all the private addons that were made for ambitious productions ?

    What about the wasted potential of all the addons that could have been created and largely enhance the capabilities of C3 in the same spirit as 3DObject/ProUI/Spriter/Spine ?

    Mikal : As guidance I would be very interested to hear what some of your top 2-3 3rd party addons are - that you think substantially help the C3 community and Scirra? I think this would help us understand what type of addons you are thinking about as you update the V2 SDK.

    Ashley : The addon SDK is best at integrating additional platform features or third-party services. For example third-party addons that provide support for ad networks (of which there seem to be dozens), or back-end services like authentication, high-scores and analytics with various third-party providers, or enhanced platform services such as advanced IAP or other monetization features (perhaps through Cordova plugins, which I think the addon SDK has reasonably good support for), or integrating with third-party platforms like itch.io and Newgrounds, are all good examples of the kind of thing the addon SDK was designed for. All the possible integration work with different services and platforms is a huge amount of work which is infeasible for us to complete alone, and if we do it anyway it takes development time away from core engine features that only we can do. Allowing third-party addons means all that integration can happen without needing us being involved. None of that needs addons to access the internal engine, and that is partly why the originally documented API was quite thin.

    So what you're saying is service integration is "the kind of thing the addon SDK was designed for", and it is the "type of addons you are thinking about as you update the V2 SDK"

    So apparently this is part of the reason why we're about to go from being able to use 100% of the features of the C3 runtime when we need them, to only 1-2% with the locked/restrictive SDK2.

    (even though SDK1 and C3 Runtime will still exist and still be used by every single official Plugin and Behavior under the hood)

    But service integrations (like firebase/ads provider) require a very active maintaining, and the fact they break so often has absolutely nothing to do with official C3 updates. Most of the popular existing service integration addons require to be updated every few month to keep working, because external services themself are evolving pretty fast. So if 80% of the addons are service-related post SDK2, then the average addon would break much more frequently than today.

    It looks like a few big 3rd party services like GameAnalytics made their own C3 integration in the past, but then never updated them since then, so you're about to do the opposite of the stated objective (supporting external services) by making the few solutions that exist today obsolete and by restricting everything else (actual engine/gameplay extensions)

    As opposed to Scirra vision about 3rd party addons, every single competitor understand the value of letting anyone to create and share actual tools and game engine extension (besides just service integrations), here is the industry standard in gamedev :

    • Game Maker: just *open sourced* their runtime this year (while you plan to lock/hide yours even more), this week they also announced support for in-editor extension + JS support coming this year btw
    • Unity: source available, thousands of great tools on Github and the official Asset Store, used by probably >95% of commercial Unity games and often more robust than official features
    • Godot: open source, fastest growing engine in term of resources, game releases, addons and popularity
    • Unreal engine: source available, huge asset store
    • GDevelop: open source (closest alternative to C3), a bunch of community-made addons are officialy endorsed by the GDevelop team and can be directly added from the editor as official behaviors
    • Phaser: open source
    • PlayCanvas: open source
    • Defold: source available
    • ... and many more

    One of the main reason why some of those indie engines (like GMS or Godot) have 100x more indie games hits is because there are 100x less frictions for addon devs to create powerful tools to extend the engine, which also means 100x less friction for any gamedev using of those engine to make the game they envision thanks to those tools

    For example YellowAfterLife, one of the best GameMaker Studio 3rd party dev, is credited in those games : Nuclear Throne, Forager, Shovel Knight Pocket Dungeon, Voidigo, Cave Blazrs, Samurai Gunn 2, Knight Club, Rivals of Aether, Nidhogg 1 & 2... and many more because all those games use their amazing GMS tools

    RexRainbow, who was the most prolific and talented Construct addon dev at the Construct 2 era, decided to quit C3 because of all the restrictions that were added to addon making a few years ago (and it was nothing compared to what's about to happen here), so they instead became a profilic Phaser addon dev and a bunch of their Phaser tools were used to develop one of the biggest indie hit ever : Vampire Survivor.

    I'll advise my clients and the users of my addons to keep using the last version supporting SDK 1 so i'll still be able to help them to achieve their vision and to develop powerful tools for them.

    The addons i made for private use + all the addons the community made are worth about 4-5 years of vanilla update at the pace features targeting actual gamedev are pushed. (Not even counting all the very specific addons I made to target my own production needs, and not counting services integration like Chadori addons, just speaking about stuff that feels Vanilla here).

    => The tradeoff is not worth it : even if some top suggestions requested for many years like Hierarchy View, Better 3D or Family Inheritance gets added in the upcoming years - which i doubt, it would still not worth dropping the modularity/flexibility Addon SDK1 allows, all the custom features already made by 3rd party devs and the fact I know i can implement almost anything I want when i need it.

    Overall it really hurts my faith in the engine, as such unilateral decisions hurting gamedevs subscribers keeps happening again and again and i'm not confortable with the feeling i don't have any ownership over my own work, so i'll keep digging in the free Open Source alternatives, made by gamedevs for gamedevs, that are growing at light speed in term of popularity/features/resources such as Godot (for full desktop/console/mobile games) and GDevelop (for little no-code/web games). It's disheartening but it just feels too risky to bet long term in C3.

    Coincidential timing but TODAY, Godot just announced big improvements coming for their Web export in the upcoming 4.3 and 4.4 releases. Given the ease of use of GDscript, the incredibly prolific content creator/addon dev community in Godot, and the fact every single addition is targeting actual gamedevs and adressing their actual issues (Open Source)...

    web export is one of the last main competitive advantage i find when using C3 (especially if C3 addons allowing to overcome limitations are all about to be broken and addondev is about to become 10x more restrictive) and it looks like that C3 web export advantage won't last very long.

    Because unless we remove it, people will just carry on using it, and the disasters will still happen

    Well if there is a clear warning, the user would know they're taking the responsibility, if they complain to you, you could just copy paste the link to the documentation page telling "If you use a Addon SDK 1 addon, it could be broken by accident and we won't provide support". You could make it totally inaccessible for child/student by restricting Education Licence and hide the SDK 1 compatibility behind the hidden developer mode setting, so only the advanced users that actually want/need to extend the engine would do it.

    Before the warning was adressed to addon developers, but now the warning would be addressed to users of the addons, which is far better.

    Also hiding risky features behind a Developer Mode is an "industry standard" everyone understands.

    There is no valid reason benefiting any C3 user to justify the fact to permentently remove so much possibilities and control over our own work, the only person on earth that think they might benefit from this situation is you. And we're several to think you're actually wrong and you're hurting your product/community by doing so, this just is a lose-lose situation while every single competitor out there understands how a prolific 3rd party dev community is a win-win scenario.

    Disasters have happened, are happening, and will continue to get worse.

    I get that "disasters have happened" at the C2 era or 5+ years ago when everything was different.

    But the "disasters ARE happening" is just false, since worker mode support introduction (4-5 years ago) that involved some changes on how addons should be made, the vast majority of addons made never broke. Also the very few time there was disruptive change like that, there were clear benefits for all users in the balance. (it is the opposite here, you dedicate months/years of work to LOCK the engine instead of enhancing it and acting on features requested for years)

    I'm not sure if there is a single Construct 3 addon made over the past 6 years that would be impossible to fix in the current version thanks to SDK1 even if it broke 3 years ago. Currently there is always a workaround, or a simple fix to find. SDK2 is the guarantee there would be no workaround at all in a tremendous amount of situations

    Construct 3 runtime codebase never changed on many aspects, because all vanilla Plugins and Behaviors (or any other features) are relying on it and you've always been reluctant to make even the tiniest change to those official Addons to make sure they still behave exactly the same. (so the reason it's so stable never was to avoid breaking 3rd party addons but to make sure games using official addons still do the exact same thing)

    Even when something changes (if it ever changes), it's very quick and easy to fix, like just renaming a method or rewriting 1 or 2 lines do the trick, because, to keep working, the C3 codebase still need in some way the same feature we were accessing.

    It's nothing like having to rewrite EVERY addon from scratch with a 50% chance it won't ever be portable at all.

    You forgot to answer one big point, why isn't the warning for addons made with SDK 1 enough ?

    • You could even put a link to a detailed documentation page explaining the risk in the warning.
    • You could also totally prevent Education licence to use those
    • It could just be available to users who enable the hidden developer mode.

    This way only ambitious/professional production would use it when they need it (because they actually need it)

    There is no reason to just destroy/hide/lock everything for everyone.

    Also you keep saying your only goal is to avoid a compatibility disaster and avoid dealing with disappointed customers.

    But soon, every addon and every game using at least one of them will break, EVERY addon will need to be rewritten from scratch and some of them (I would even say most of best addons) won't be portable at all. All of this by purpose and for no gain for any C3 user, so there will be actual reasons to be mad at Scirra + it will put more pressure on Scirra to implement every specific features any production needs while Addon Dev are currently doing it easily

    Imagine if Unity did what you're trying to do : breaking all 3rd party stuff and enforcing everyone to use vanilla features only, the drama and exodus would have been 10x worse than the Runtime fee disaster.

    It's as if Unity announced the whole Asset Store + any private tools made by game studios/companies are obsolete, and 80% of the best ones would be totally impossible to remake in the future, because the engine is about to be 10x more restricted and limited.

    You're doing the opposite of the goal you're explaining to us. You're creating the problem and saying at the same time it's the solution. It makes no sense

    I think there is a very simple solution that would solve everything :

    ✅ do Milestone 3 (showing a warning for addon made with SDK 1 in 6 months)

    ❌ but just don't do Milestone 4 (removing support/access to Addon SDK 1 on purpose, while it will always be there under the hood at it's litteraly the whole C3 runtime codebase every official Plugins/Behaviors/features rely on)

    This way Scirra could remove all references of Addon SDK 1 in the documentation and totally replace them by Addon SDK 2 Documentation.

    There would be a warning to tell all users using SDK 1 addons that they're risky because the runtime sourcecode could change and some things could break BY ACCIDENT (instead of hiding/breaking/removing access to everything on purpose).

    => It totally solves the problem Scirra is raising

    However any poweruser, any commercial/ambitious production would still be able to use powerful addons, extend the engine and implement features by themself at their own risk if they need it (as almost any full game ever made in C3 that use a few addons using at least a few undocumented features, and as 99% of any commercial games made with any game engine out there)

    SDK 1 will always exist under the hood, SDK 2 is just scripting interfaces calling methods from SDK 1, so there is no valid reason to 100% remove the access to us if any addon using it shows a clear warning that some stuff can break inadvertently due to C3 updates.

    In case anyone is interested in getting more context about this, many addon developers voiced their concerns about this change in this thread:

    Thread about why Addon SDK2 is a massive regression in what's achievable with Construct (making it less powerful and less trustworthy, for no valid reason) :

    construct.net/en/forum/construct-3/scripting-51/method-access-engine-181244

    Construct will remove support for SDK v1 addons. The addons will no longer be loaded in the editor, and projects using them will fail to open

    This post is even more worrying than what we were all thinking in this previous thread, because not only everything will be hidden/made inaccessible on purpose, making the engine 10x less powerful and making many of its limitations impossible to overcome (no matter how skilled you are at eventsheets/JS/AddonDev),

    but it looks like you also plan to break every single addon ever made for C3 (6 years of collective work making the engine way more powerful and being used in thousands of projects) in approximately 1 year, while you always promised that at least the documented features of Addon SDK V1 would be supported forever.

    Here is what you said on the thread I linked above, 2 months ago :

    The exception to all this is the documented, supported APIs. If you use those, we promise to support them indefinitely

    You can of course stick to the documented APIs and do anything you like, and we promise to support that indefinitely

    So are those promises not worth anything anymore ?

  • So, as I said before, we are not actually going to remove all undocumented features in the next release. However we will move forwards with a plan for a v2 SDK over the next year or two, which should give enough time to design a suitable SDK and deal with the inevitable difficult backwards compatibility issues that come up. Let me be clear: we did not have to do this, as we reserved the right to say "tough luck". However as it is clear this is untenable and obviously unpopular, we are promising to do the necessary work to make sure this transition goes smoothly. This does mean designing a new API in co-operation with the addon developer community, and I would hope this ultimately ends up a comprehensive, capable API that does pretty much everything addon developers could reasonably want to do, short of unfettered access to the internal engine. I would ask for co-operation during that process so we can end up with a reliable, robust, maintainable SDK in the long run, and not the risk of disaster that we are constantly running at the moment.

    Ok that's a bit better. (The part I quoted above I mean... in disagreement with everything else as explained in previous messages)

    Still worried about this decision, we're just loosing possibilities with no benefits, we'll depend on the feature request process for everything not knowing if and when we'll be able to fix our issues and overcome the limitations we'll face...

    But I think everyone here is hoping for a cooperation in the transition process, as you plan to remove access anyway. Please let's not make it a Scirra VS C3 users again. You can't just hurt our trust and faith again and again. I think we're hoping to see notable improvements in the communication and the way our feedbacks/concerns are treated.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Once again, repeating myself, source code is not an API.

    Yeah i know I just point out that here, you're about to dedicate your limitated ressource and work hard to lock everything for your users and to do the opposite of what your community wants.

    Meanwhile, the creator of Godot, the most promising alternative for your disappointed advanced users (free forever, open-source, enabling total customization, with the most active creators and 3rd party dev community, getting updated at light speed based on actual user issues) is teaching anyone how the internals of this engine is working

    I haven't been talking about obfuscation here, only encapsulation. I am not sure where you got the obfuscation point from

    The obfuscation interrogation comes from several post you wrote in this thread, such as this one which is the first one that worried us.

    > Question: Or is it that there is a plan to obfuscate all internals at some point?

    Answer: This could well happen, and it could mean whatever internals you are accessing become permanently unavailable.

    At least 5 person asked you about it after that to understand concretly what you meant by that and it's still not clear.

    Does encapsulation solve any concerns we raised ? To me encapsulation means the exact same outcome we want to avoid. (and it's likely you would do both Encapsulation AND obfuscation).

    Encapsulation OR obfuscation (or both of them) means we depend on you for anything and makes the engine 10x less powerful for its advanced users, it removes a bunch of control over our own work. Besides that i'm not comfortable knowing that I don't have ownership of my own work, into which I'm putting all my soul.

    > Question: This is probably what you meant, but isn't the best way to deal with it is to FIRST make improvements to the SDK with an active cooperation with 3rd party dev during several months/years and only then starting to progressively encapsulating ? Is it what you're planning to do ? Improvements to SDK first, encapsulation second ?

    Answer: No, because the current SDK is unmaintainable and risks disaster, and the longer it is used, the greater the risk.

    It seems that promise you made a few post ago to do your best to make the transition as smooth as possible didn't last very long. You just want to remove us what makes our projects feasible without even working on a decent solution to mitigate it first ?

    I think this thread has shown, if we say "don't do XYZ, it's unsupported and we won't help you", in the end people do it anyway and then still expect us to help them

    We're not asking for your help, we're asking you to not depend on you to get help and to not obstruct our way to make our games.

    When it comes to 3rd party dev/community initiative and how Scirra reacts to it, what should be an obvious win-win often becomes a lose-lose

  • Anyway a few questions to understand :

    I am talking about encapsulation, not obfuscation.

    So you guarantee the runtime will never be obfuscated like the Editor SDK ? Just better encapsulation but everything will still be readable for us ?

    (Would still make us dependant on the feature request for everything but at the very least we could read the code to get inspired for some stuff)

    We will likely start moving to a better designed SDK in the future, and we will try over the coming months and years (as this will be a very long term project) to make good faith efforts to mitigate

    This is probably what you meant, but isn't the best way to deal with it is to FIRST make improvements to the SDK with an active cooperation with 3rd party dev during several months/years and only then starting to progressively encapsulating ? Is it what you're planning to do ? Improvements to SDK first, encapsulation second ?

    Releasing the feature requests towards better Addon-Making that are currently hibernating on the feature suggestion platform would be a good start to show your good will btw

    Linking a few of them, starting from the most popular on the current platform (some of them are just repost from older suggestions platforms)

    1. Add support in vertex shader to output world position (would unlocks new possibilities for 3D shaders)
    2. Debugger: more granular Behavior and Plugin processing
    3. Missing Editor/Runtime Hierarchy methods to create UI Systems
    4. Allow behaviors to have object type/link/info properties.
    5. Add scripting interfaces for Custom Actions
    6. Effects SDK: down and up-sampling
  • While we are arguing for days why we don't want Construct to be even further black boxed, the creator and technical lead of Godot just started a Youtube series where he explain in details the Engine internals.

    He posted the second episode a few hours ago.

  • People provided you some solution to fix the main issue that you're raising and that we're trying to understand (basically protecting people from using risky 3rd party addons).

    An other idea to solve this :

    • The addon developer check a simple bool if the addon is considered as "risky".
    • A pop-up warning saying "If you use [insert risky addons names] in your project, it could break your project in a future update and Scirra won't help you to fix the issues related to your 3rd party addons" with a link to a new documentation page explaining everything you explaind here. ( you could list a bunch of potential issues here such as the Android publishing requirements).
    • The warning popup could have a button "make a backup" to let the user save an alternative c3p of his project before opening this.
    • You could pop up that warning each time a project with a risky addon is updated to a newer version, and suggesting to open the last version the project was saved instead (so people could stick to this version)

    This kind of thing would do the trick, there are actually easy solutions to the issue you keep mentionning. It just requires a bit of good will.

    However what you're about to do WILL absolutely create a disaster. It could potentially break all the most advanced projects currently developped using C3 + thousands of more simple projects using 5 years of community work

    It would be throwing off those 5-6 years of collective work, for litteraly no rewards for the community who put so much effort in it.

    As C3 users and a community we know the long dark times Construct went through when it hurted its own powerusers / 3rd party devs with some decisions. At least, the last times there were clear benefits for us in the balance : Construct 2 => Construct 3, worker mode support, but those were still painful trade-offs.

    How should we expect you to create a better Addon SDK (merging it with Scripting API) when we know getting obviously missing Addon SDK and Scripting API from you, related to already existing features is such a painful, time-consuming and hopeless process ?

    Here is just one of the most recent example I personnaly experienced : github.com/Scirra/Construct-bugs/issues/7735

    Skymen also wrote a blog post mentionning that exact issue 2 years ago : construct.net/en/blogs/skymen-13/flexbox-weird-characters-1590

    (If anyone wants to know how bad an obfuscated Runtime would be, the part of the blogpost about the already obfuscated Editor API is insightful btw)

    Also if 3rd party addon dev, relied on Scripting Interfaces, it would be even worse than the current limited Addon SDK in some ways because it would mean that we'll have to develop plugins and behavior TOTALLY differently than the way Scirra is developing vanilla addons.

    Anyway C3 is moving in the opposite direction of Game Engine history here with the rise of Open Tech. (by that i mean having an Open Philosophy not necessarily Open Source)

    A bunch of game engines/frameworks targeting web are growing pretty fast with a similar Open philosophy such as Defold or Phaser.

    Game-maker very recently OPEN-SOURCED their runtime.

    Godot has become the biggest Engine in term of itch releases, social media interaction, exponential growth of commercial releases and is relying on a Open philosophy letting devs customize their experience both at Edit and at Runtime. They probably have the most capable 2D engine and each Godot user has a guarantee to keep the full ownership of their own work indefinitely, no worries about unipersonal decision that could destroy years of work (+100% free, 100% open source). They are also planning to enhance their web exports a lot by providing options to reduce the build size and manage load times efficiently.

    The 3rd party dev communities are big and prolific in all those engines, this is probably one of their biggest and most resilient strength.

    From a gamedev perspective, C3 advantages over its competitor are already narrowing, and this single decision would makes things worse really fast.

Overboy's avatar

Overboy

Member since 21 Oct, 2013

Twitter
Overboy has 8 followers

Connect with Overboy

Trophy Case

  • 11-Year Club
  • Entrepreneur Sold something in the asset store
  • Jupiter Mission Supports Gordon's mission to Jupiter
  • Forum Contributor Made 100 posts in the forums
  • Regular Visitor Visited Construct.net 7 days in a row
  • Steady Visitor Visited Construct.net 30 days in a row
  • Enduring Visitor Visited Construct.net 90 days in a row
  • RTFM Read the fabulous manual
  • x18
    Quick Draw First 5 people to up-vote a new Construct 3 release
  • x15
    Lightning Draw First person to up-vote a new Construct 3 release
  • x25
    Great Comment One of your comments gets 3 upvotes
  • Delicious Comment One of your comments gets 10 upvotes
  • Email Verified

Progress

23/44
How to earn trophies