Adventures in the Unity3d Asset Store
Extracurricular: Michiel Frankfort
At Little Chicken we have a lot of talent. Usually, we only get to show this talent as part of our productions. But some ‘chickens’ release amazing tools, artwork and games in their spare time. In our Inspiration Lab we celebrate these endeavours and give these home-grown projects a spotlight. One of our most experienced developers, Michiel Frankfort, shares his adventures in the Unity3d Asset Store in this blogpost.
Problem: Realtime-Raytracing
Solution: Multi-Threading framework
Result: Asset Store adventures!
Almost three years ago, I wrote a piece of software as part of a hobby project. As a stand-alone framework it keeps generating money ever since, thanks to the Unity Asset Store. Curious how it works? How it sells and what the sales-numbers are? Keep reading.
The ever lasting quest for better performance:
Every now and then we run out of means to further optimize code, but we have to anyways. This can be a real pain, because there are only so many places you can look for improvements. Thanks to Unity’s great (deep) profiler blogpost, it’s easy to spot hiccups and costly routines in general, but sometimes its just not enough…
Then what?
We live in the great age of parallelism and simultaneous computing. But it’s scary, often buggy and difficult to implement. On top of that, Unity is not thread-safe, preventing the developer from accessing any property from any Unity.Object derivative. Even a simple Debug.Log(myObject.name); will cause errors when fired from a separate thread.
Why did I need it?
I started investigating multi-threading in combination with Unity when I was working on a little hobby project regarding Ray- and Voxel-cone tracing. I used Unity 3.0 at the time and there were some exciting examples online of people and game-engines fiddling around with Voxel-cone-tracing.
The voxel-cone-tracing feature-demo from Unreal-engine 4 proved to be compute-intensive for final shipping. Now replaced by less-compute-intensive set of visual tricks. It is said that ‘the disappointing next-gen console specs’ were to blame for this feature to be removed.
Enlighten’s first big-title implementation gave us a sneak-peek on what to expect from BattleField 3 at the time. Enlighten is now the default lighting-engine of Unity 5.
So on to multi-threading
All these beautiful video’s made me realise something. Unity needs real-time-radiosity! Of course there were some other developers that felt the same way and they were miles ahead of me. Later to be crushed by Unity’s 5 Enlighten implementation. But hey, it was fun while it lasted.
Although this process taught me a lot about Vector- and Matrix-mathematics, BSP-grids and next-gen visual graphics, it also became more and more evident that simple single-core routines weren’t enough.
What do Unity-developers need to make Multi-Threading even possible?
Thats when I builded some multi-threading tools:
- A nice thread-pool, that uses several worker-threads to process the work managed by the provider-thread.
- Dispatch-to-main-thread tool, allowing external threads to interact with Unity-objects quite easily without all the thread-safety issues.
- Some helpers that check for Unity-Inactivity, blocking all worker threads to prevent IOS for example from killing the app when app/process is send to the background.
Once all these helpers and building blocks worked properly, I rewrote a part of the my Ray-trace software. It really improved performance with a huge leap forward, depending on the amount of threads available. At the time I used an quadcore CPU and indeed performance improved by an almost perfect factor of four!
But I wasn’t happy by the amount of work required to split the computational-workload into even blocks of ‘work’ to be handled in parallel by separate threads. That’s when I decided to turn all my new knowledge into a single framework that handles all these difficulties and spreads the workload with absolute a minimum amount of implementation-effort.
LOOM was born.
How does it work?
The info-graphic found below is the best way to explain how the flow of computational-data is being processed. Data comes in on the left-side and over times is processed by multiple threads.
Once all work is done, the Main-Thread collects all data, ready to be used in-game. If we need to access a Unity.Object-derivative property (like: enemy.transform.position) during computations on a worker-thread, we can use the ‘MainThreadDispatcher’ to briefly handle these requests, making it thread-safe and usable within Unity.
How to implement?
Well, you came so far reading this highly technical blogpost, I will not bore you with actual code examples and explanation. I figure this is not the kind of matter that reads like a good novel, or top-gear magazine for that matter (assuming you are male programmer of course).
That’s why this visual code-snippet is a better way of showing its practical use. If you keep reading, I will reward you with actual sales-data from the Asset-Store, so hang in there 😉
Show me the money: Unity3D Asset Store!
LOOM was to be my first Unity Asset-store project, therefore I did not know what to expect. I know Unity had 2 million users registered at the time. Only a small percentage of the users where to considered ‘professional’. A small percentage of this group would be software-developers and small percentage of this very very small group would be interested in such a product… And LOOM wasn’t even the first of its kind in the Asset Store.
‘Niche’ is the word I’m looking for I guess.
So why would I even bother? I reckoned I would sell only a handful of licences in a year. Still I was willing to do it, because my code was there, tested and proven and all I needed was some promotional art and a kick-ass demo project. After spending some time coding, tinkering with good-old Maya, Photoshop and spending some time writing documentation, I was ready to submit!
My first month in the Asset Store
Not only did I sell more than anticipated (yeah, I became a hundredaire), I wasn’t sure what to charge the buyer. There are pricing guidelines, but the same thing happend to Unity as what happened to paid-apps in the Appstore and Play Store: The industry starts with a price based on guidelines and gut feeling, soon to be replaced by ever decreasing prices till you hit rock-bottom because of competition. Experimenting with the price worked out great, but in the end, it was much lower than the Unity guidelines suggested it would be worth.
Is it safe to charge more for your product than the competition?
At first, I knew I needed to be competitive with my pricing. The nearest competitor asked only 10,- dollars a licence while the Unity-guidelines clearly stated a price range of 50,- dollars was applicable.
But after a while I realized that my product had (yes, this is going to sound cocky) better store-visuals, better rating, better documentation and most importantly, more features.
I realized that when people search for a product in a store (any type of store for that matter), it’s a coin-flip what they will pick as long as the price, promo-visuals and features are somewhat equal. That’s why I started to highlight all the differences and optimize my store description-text (there are no keywords unfortunately) for the Asset Store’s search-engine.
Playing with numbers!
So the big question remains… what’s it worth?
Thats when I increased and decreased the price a bit. To see if I could maximize the ‘profit = buyers * price’ equation, but the numbers proved to be too small to make a clear statement about that. All I can say is that very low prices (10 dollars for example) do not make the same profit as 30 dollars, although more people would probably buy it.
In the end it dropped slightly, after more than 2.5 years of a fluctuating monthly sales. Unfortunately it’s near its point-of-death. (Don’t mention vBug, thats a story for a different blogpost)
Why are sales decreasing?
It makes sense that a product with little to no innovation drops in popularity, but lets not forget, its not the app-store with millions of apps ready to kick your product of its socket. Besides Unity keeps bragging it has more users than ever, more than 4 million by 2015.
I think there are several explanations for its decreasing sales:
- Bad support: I admit… I wasn’t always able to help people at the time they needed it, resulting in poor reviews… my bad.
- Piracy: You know for sure your product is popular as soon as you can download it from torrent-websites and fora. Great compliment on one hand, significant noticeable drop in sales on the other…
- Competition in the Asset-Store: There wasn’t much ‘new’ competition around, but my decreased ratings due to some bugs and poor support on my side made them look ‘better’.
- Competition in Game-Engines: Unity claims it reached more than 4-million registered developers… but one thing is clear to me and my colleagues whom also sell stuff through the Asset Store: Sales dropped when Unreal-Engine announced it’s ‘free of charge’ licence model….Sorry Unity, I love you but this is a fact…
Post-mortem?
I will keep selling and supporting it till Unity sells itself or whatever happens, but clearly the good times are over. Not only with LOOM, but also with my new tool VBug. VBug started magnificently, is highly rated and appreciated, but the sales dried up completely.
O well, it was fun while it lasted! Much fun indeed!