What does a fairy dance look like when there are no clumsy, smelly humans around?
For Sierra fans everywhere: This is inspired from the Quest for Glory series. It is also in memory to my friend, mentor, and former co-founder, Carlos Icaza who passed away unexpectedly this summer.
Please make sure to watch it at 60fps. (Direct YouTube link here.)
Dance of the Fairies was first presented during Swift on Android at try! Swift Tokyo 2017.
Designed & Programmed by Eric Wing
Background Art by Judy Rosenwaig
Music: "Late Snows of Winter" by Jeffrey Roberts (jmr)
(remix of "The Magic Meadow" by Mark Seibert)
Made with Blurrr SDK
The origins of this “demo” (as in demoscene, for the lack of a better term) are the combination of loose ends I had from “Why We Loved Sierra Games”, and trying to find a way to honor and remember my friend Carlos Icaza. I have more to say about each below.
Sierra On-Line / Quest for Glory inspiration
Aftering completing the massive “Why We Loved Sierra Games”, there were still many pieces on the cutting room floor and in my head. The playful fairy dance in Quest for Glory I and the dryad dance in Quest for Glory V always stood out for me as wonderfully silly and special moments in those games. The don’t directly contribute meaningfully to the puzzles, story, or gameplay, yet they still felt naturally woven into the texture of the games. They did not feel like your typical cutscene that you wanted to skip through.
Other Sierra games had moments like these too, such as 'The Dance of the Wallflowers' and ‘Dem Bones’ in King’s Quest VI. And if you rewatch the Epilogue, I string together a bunch of dances and other interesting moments from a wide range of Sierra titles. And some may even consider all the artful death scenes in the Space Quest series as this same concept.
And now in hindsight, these scenes were an odd rarity, both in the fact that players would be willingly anticipating these for what ultimately amounts to a break in the gameplay, and that game developers would be able and willing to invest the time and money to create these kinds extra of scenes.
Just an observation: The Sierra fan community has created fan art, stories, music remixes, movie shorts, and of course some amazing video games, but to my knowledge, nobody has written a “demo" like this before. So, a first time for everything I guess, and ironically at the same time, also a last hurrah at something the industry decided it can’t afford to do any more.
Structurally, “Dance of the Fairies” may seem to take more influence from the dryad dance in QFG5. But actually, conceptually and spiritually, I found more inspiration from the original fairy dance in QFG1. We know that the playful, colorful fairies, each with their own personalities, like to dance. And it presents that natural question, "What does a true, all-out, fairy dance look like when there no clumsy, smelly humans are around to ruin it?”
I tried to give the fairies a more organic feeling. The dance in QFG5 had an algorithmic feeling to it. There is nothing wrong with that, and parts like the circling sine-wave paths are among my favoriate paths in the original. But I wanted to be different, and try to make the fairies feel more like organic individuals with imperfections. So, each fairy path was constructed by hand (trying to balance perfections & imperfactions), and not algorithmically in Dance of the Fairies. And also hence, the result leads to some of the really silly & playful dance configurations presented in this dance. But as a trade-off, at the beginning and end, I was trying to go for a meandering, sputtering, erratic, but care-free, casual flight path inspired by Woodstock, the little yellow bird from Peanuts. I don’t think I succeeded at nailing that feeling.
Since so much time has pass since the QFG series, I also wanted to utilize modern computer hardware capabilities. I’ll say more about this in the technical section, but one thing that always bugged me watching the the QFG5 dance is that the dryads (fairies) did not emit light via dynamic real-time lighting. This was even more apparent when you were wearing magic armor which appeared to glow, and it made it more noticable that the dryads were not emitting light in the scene.
Finally, the dynamic day/night lighting transitions are an intentional homage to QFG for being one of the earliest games that introduced real-time, playable, dynamic day/night cycles in-game. Thus, having the fairies turn night into day momentarily with their light “explosion” seemed like an appropriate finale on multiple levels.
RIP Carlos Icaza
Carlos was an engineer and serial entrepeneur, known by many different groups for different things.
• He was a lead/manager for several Adobe products such as Illustrator.
• He was a lead/manager for Macromedia Flash.
• He was the co-founder of the Corona SDK which allowed developers to write cross-platform native mobile games in Lua. (I met Carlos when I was hired for Corona and eventually became Chief Architect.)
• And Carlos was known as @CodingInSwift on Twitter with over 18,000 followers.
His death was a shock to all of us. Even to this day, I am at a loss for words. There are lots of random stories I could tell, like how understanding & supportive he was when I learned my father had stage 4 lung cancer. But so much of our time was related to developing video game engines and tools, I felt like I should code something in his memory instead. So I focused on a few technical events that had significance for us.
• Carlos loved splines. He was an expert at them, especially Bezier curves, for all the work he did at Adobe. I am far from an expert, but I have had a little experience with Hermite splines which pops up in 3D programming for keyframe animation. Carlos wasn’t familiar with these, so we had always wanted to do a spline project together. But with all the fires we were putting out, we never were able to prioritize this. Ironically, I finally started writing a new Hermite spline library and editor tool for Blurrr. It almost emailed him a copy a few days before he died, but I held off because I wanted to polish it up. I am haunted with regret for that decision.
• We had an tortuous and embarrassing history with particle engines. Carlos pushed hard for a good particle engine and designer tool at both his companies, but business politics always got in the way. I don’t want to dwell too much on it, but the results were humiliatingly bad and unusable in many cases. As a point of pride, I always planned to write a first-rate particle engine.
• For anybody in real time graphics, it has been a no-brainer that the programmable GPU and shaders were the future, even for mobile, even 10 years ago. But again, business politics. We had private strategic conversations on how to pitch why we needed the resources to implement all this. To clarify, our interests and focus were on 2D instead of 3D, so it was not obvious to non-real-time-graphics-experts how harnessing the full power of the GPU would benefit 2D. Carlos was a graphics expert, but not a real-time graphics expert. But his intuition that we needed a shader engine was correct, but he was asking me for ammunition so he could deal with the politics. Our personal favorite example was a normal mapping technique that could be applied to 2D sprites to make it look like the scenes were dynamically lit and even 3D.
• Finally, we were always fighting performance problems caused by bad architectural decisions. Again, politics. We wanted to push the hardware and sustain a constant 60 fps on mobile devices for real programs. (And hence, one of the reasons why Blurrr was conceived.)
• He was also kicking my butt to launch Blurrr already
• So in many respects, this demo is a bucket list of all those things we had hoped to do, but time was cut short.
A + B = Dance of the Fairies
Unfortunately, this no longer was just a tiny, throw-away project that could suck. The quality now mattered to me because it was now so personal, so I struggled fighting perfectionism. I was often de-motivated and depressed because I felt it could never be good enough.
But when I was given the opportunity to speak at try! Swift, with over 700 attendees, I knew that this was the venue I had to debut everything. Nail my speech, talk about Carlos, present Dance of the Fairies, and launch Blurrr.
I made it. I can see all the imperfections, but I hope you all will view this with generosity in your hearts.
But I know Carlos is rooting for me and smiling.
A final sad coinicidence is that the same day Realm posted my “Swift on Android” talk, another friend of mine had just died. So tragically, as I say goodbye to one friend, another is being laid to rest.
You probably already have a good sense of how things work from what’s been written above. But here are a few more details.
• All the fairy paths use Hermite/Coons curves and were hand crafted. The advantage of Hermite over Bezier is that that the paths are guaranteed to cross through every point. So imagine turning through a corner point, like rounding first base in baseball. With Bezier you will typically round the corner early without crossing through the actual point, missing first base. With the type of Hermite curve I’m using, it will round the corner in a way that it always touches first base.
• Pinky fairy as the Pong ball is the only time a non-Hermite curve is used. This is standard linear interpolation on the path to get the bouncy behavor.
• The particle system is implemented using Data Oriented Design techniques and also written with SIMD intrinsics (SSE2 for x86 CPUs and NEON for ARM CPUs). It is wickedly fast. This is the particle system Carlos always wanted.
• Data oriented design and SIMD were also utilized for the spline implementation. Each fairy point is actually composed of multiple values such as x and y and other things. So it is natural to think in terms of wide operations.
• The 2D normal mapping lighting system is derived from this tutorial: https://github.com/mattdesl/lwjgl-basics/wiki/ShaderLesson6, but with some changes such as resolution independence and N-light sources.
• Each fairy is an independent light source. Since there are 8 fairies, this is actually a expensive computation and is by far the dominant operation affecting performance. Modern hardware, including modern mobile hardware can handle this without problems, but very old mobile hardware does struggle with this.
• I used this online tool to general the normal maps for the background artwork. http://cpetry.github.io/NormalMap-Online/
• I used very conservative settings for the normal map generation. Thus the lighting effects are kind of subtle, maybe too subtle considering how much GPU is being consumed for this. They are most noticeable when fairies pass near the berry-like flowers. I didn’t like the look when I ramped up the values too high. When deciding between artistic demo vs. tech demo, I opted for artistic.
• I used stock background art from Judy Rosenwaig. Judy was a friend of Carlos and he hired her for various art needs. I had briefly inquired about getting more customized art for this demo, but due to my time constraints, I ended up just using her stock art.
• I built a custom editor tool to help draw, plot, and edit the fairy paths. One additional reason Blurrr supports both desktop and mobile is even if you are only focused on mobile, Blurrr encourages easily building your own customized private desktop tools to help you.
• In addition to the usual plotting/appending/moving points, I built a record/draw mode where I could just move a mouse (or finger) and draw a fairy path. But I soon discovered that to actually make this look good, I needed good puppeteer skills, and I am a poor puppeteer.
• I also built a particle designer (Sparkle Sparkle) on top of the particle engine. This one is general enough that I plan to ship it as a stand alone tool that everybody can use. Carlos would love this too.
• Performance was never an issue with the particle system (the lighting system is where all the time was spent). It was an artistic decision to start with fairly meek particle emission characteristics. I wanted viewers to focus on the fairy as a whole and not just the particle system. I perceived the fairy dust as an extension of the fairy. I gradually ramp up the particle behaviors as the dance becomes more intense. But I always tried to keep it in balance with the fairy itself and not get carried away just for the sake that I could.
• The light “explosion” near the end is actually a mostly natural consequence of intersecting all the fairies together using the normal mapping technique. I just ramped up a couple of values to intensify the effect at the right time.
• Pinky fairy’s good-bye message is randomized in the program, based on phrases used in QFG1 (which also were randomized).