In this post, I'll share how I brought my Flash game Frog Fractions to the modern platform. As a result, I created a partially automated port on Unity using Haxe. The post will be of interest to anyone trying to upgrade their codebase to Flash. The post will contain spoilers about the structure of Frog Fractions: Game of the Decade Edition and its DLC Hop's Iconic Cap .
After Frog Fractions 2 failed to make me rich, I spent about a year doing contract work and sketching / prototyping . Then my wife got pregnant, and I decided it was time to find a real job so that I could support my family. Before the start of GDC 2018, Iposted a tweet about looking for a job , hoping to find the right people at the conference. I was interviewed in several locations, but the most important thing was that I was able to find funding for my next project.
The project was like this: hide the next Frog Fractions game inside Frog Fractions 1 and sell it on Steam.
Frog Fractions is approximately 13k lines of code in Actionscript 3 and is built using the Flex compiler. I figured that after adding new remaster content, the volume would triple, to about 40k lines of code. (And my estimate turned out to be quite accurate - it turned out 28k C # code and 3k lines of scripts for cutscenes / dialogue trees in addition to the original game.)
I considered several possible options for further work:
- AS3 Adobe AIR. , :
- Frog Fractions 640x480. . 2012 , , 2020 Steam .
- Flex , 10k , . 40k ? ( , , .)
- Flash . AIR 2020 ? (, ! .)
- , - . , Scaleform (The Banner Saga, Road Not Taken), , Scaleform - 2020 . (, 2018 Autodesk Scaleform, โ UI.)
- Flash VM -. Flash , . Ruffle. , ?
- C#/Unity. .
- : Flash, , Unity. , ยซ-ยป . , , , Unity, Windows. ( , , , TCP- . Flash , , Unity, .)
- Haxe OpenFL. as3hx AS3 Haxe, OpenFL Flash API. OpenFL , .
I want to emphasize here that all these approaches were based on the fact that Frog Fractions was essentially a program that I wrote to compile to SWF. I can't judge how my solution is applicable to your game, if it is a Flash animation timeline, the interactivity of which is provided by scripts.
I asked around for advice on how to move forward, and the most useful one was given to me by Lars Duset, who among other things said that Haxe has a C # backend and its target platform could be Unity. He also advised me to first come up with a workflow and port a small project using it.
(Note to myself: Add Lars Dusset to the credits of the game. I couldn't imagine how much of an impact he had on the project until I reread our correspondence.)
After a week of experimenting, I was able to run Frog Infarctions (a game I wrote Sosa Sosovsky's 0-hour game jam ) in the Unity editor. The result was not perfect, but it was enough to understand the feasibility of implementation, so I started working on the main project.
This is how my workflow turned out. These operations must be performed once:
- Use as3hx to convert the code from AS3 to Haxe.
- If necessary, manually clean up the generated as3hx code.
After that, iteratively perform the following operations:
- Port your codebase to Haxe to use the Unity API instead of the Flash API.
- C#- Haxe Haxe C#. Haxe, UnityEngine.dll, API hx. Assembly-Csharp.dll C#, .
- Unity.
The first week of work was very tedious, you had to clean up the expressions that as3hx marked as inconsistent, fix the compiler errors it added and deal with I / O calls. Fixing bugs in Haxe isn't perfect, so there were about 30 errors every time I tried to build, no matter how hard I tried, so I had no idea how close to completion until everything compiled without errors. Also, it seems to me that as3hx is a search and replace translator, not a real transpiler with translation to and from AST, because it seems to add errors such as placing the code on the wrong side of the parentheses when in my flow control uses a specific brace style.
With that done, I got a Haxe codebase that successfully compiles to a C # target. After that, I have never touched the AS3 code. (Except for the graphical asset export process described below.) At this point I decided to ditch Haxe and just work in C #, but although the output of as3hx is quite similar to the original code, while maintaining the brace style, code order, and comments, the output from Haxe is C # is obviously not meant for the human eye. So from now on, if I didn't create new scenes, I edited the Haxe code and compiled it in C #.
At this point, the code was compiled and run in the Unity engine, but without I / O. The next step was to recreate all the I / O code using the Unity API. This and the resource conversion took about four months, mainly because there are many different resource types in Frog Fractions:
- Vector graphics drawn in the Flash editor. I rendered it as 4k, making AIR build the original game, but doing nothing other than rendering the animation frames and writing them to PNG files. Then, using a TexturePacker, I assembled them into sprite sheets.
- , Flash Shape API. Flash , , Photoshop . . Unity . , , 9-slices, .
- SVG, OpenClipArt.org. , , .
- , Flickr. preserve details Photoshop, , 4k- , .
- . , . , 4k. , , โ !
- . Flash- , Marching-Cubes . 4k, , . , .
- , .
- . 2015 Unboxing Story Unity API . 2018 . !
- . .wav .
- MP3 64kbps mono, , , Amazon S3, , OST.
Everything in the remaster except for the full screen shaders and video playback, and most of the new story is rendered using Graphics.DrawMesh calls, not as objects in the Unity scene graph. So the question is, is Unity really the right fit for this project?
While Craig Tympani and I were choosing the engine for Glittermitten Grove , we settled on Unity because of its good cross-platform support, because FNAnot ready yet, and because building your own engine is a great way to never finish a game. Ultimately, while I was saddened by the poor 2D support in Unity, it allowed us to release versions for Mac and Linux with almost no problems, which in my opinion is a huge success. (Presumably, 2D support in Unity has improved since 2015, but I haven't studied it. Graphics.DrawMesh works fine for me. Maybe even FNA now has a working resource processing pipeline!)
For this project, I chose Unity mainly by inertia - I didn't want to bother studying a new engine, because I had to implement the research project described above; Unity supports all platforms I wanted to port the game to, including consoles.
Oh, and then I created an additional game! I'll probably talk about this creative process in another post, here I will only mention that I put together a transition scene in Haxe and wrote the rest of the new game in C #. In addition, I made significant changes to the main menu inside the Haxe codebase. Therefore, it seems to me that it is quite possible, after porting to Haxe, to continue releasing code updates by doing development on Haxe.
I also made some optimizations to the original code. AS3 code was deliberately written without efficiency in mind because I was trying to avoid striving for "flawless code". For example, I couldn't believe I could get away with allocating a Vector2 for the heap on every arithmetic operation! The resulting result worked well on 2012 computers, but the worst-performing parts after double transpilation caused significant overhead, so to work well on modern PCs, I had to rewrite some of the code in native C #.
It's also worth noting that if I hadn't planned to significantly expand the size of the original game and were just trying to keep it from death along with Flash, then OpenFL, AIR or Ruffle would probably be a smarter choice.
Releasing the game was like saying goodbye to her. I enjoyed working in Flash. At the time, it was the best way to show your games to people with the least effort and it seemed like they would live forever - SWFs from the 90s still work flawlessly in the latest Flash player, even though decades have passed. Watching the world try to move to HTML5 when it was clearly not ready for it was excruciating. (And frankly, things get worse rather than better . I believe that the browser will never be a playable platform again as long as the owners of the two most popular browsers have their own phone app stores.) I created a remaster in part because of this. that he wanted to sell a new game, but also out of a sincere desire to keep his part of the game history. Thank you for coming back to her with me!