Porting old Flash games using Windows Forms - How to Embed Flash Player dll?

Viewed 1091

I developed some somewhat popular Flash games around a decade ago, and recently people have been asking me to port them to Steam. I've been researching how to do this for a few days, but it feels like trying to figure out how to get a GameBoy cartridge working on an iPhone, and googling for answers feels like archaeology since nobody talks about Flash anymore.

Flash can build to an exe projector with the Flash Player bundled, but it stores saved data in fragile cookies, so I need to build a wrapper that can exchange data with it to save data more reliably. I've managed to build something simple in Windows Forms (with which I have only limited experience), but there are two possibilities, each with different issues:

One is that I load in the exe win projector version of the Flash file as a Process:

game = Process.Start ( "MARDEK.exe" );
game.WaitForInputIdle ( );
game.EnableRaisingEvents = true;
game.Exited += ( sender, e ) => { Close ( ); };

This works, and doesn't require the user to have Flash Player installed, but I don't know if it can exchange data both ways with C#.

Another possibility is to embed the swf directly:

swf = new AxShockwaveFlashObjects.AxShockwaveFlash ( );
Controls.Add ( swf );
swf.Size = new Size ( 720, 528 );
swf.Location = new Point ( 10, 10 );
swf.BringToFront ( );
swf.LoadMovie ( 0, "MARDEK.swf" );

I think the swf could then use something called ExternalInterface to communicate back and forth with C#. A huge issue though is that I don't think the Flash Player is being bundled, so the user's expected to have that installed separately. That's not acceptable.

I've found some .dll files for the Flash Player installed on my system, but I don't know if it's possible to bundle them in and have the AxShockwaveFlashObjects use them instead of what the user has installed. That'd probably be the ideal situation.

I know this is an obscure issue - which is why I'm having to ask because Google's telling me so little - but any help would be greatly appreciated!

1 Answers

Yo, I've published both AS2 and AS3 Flash games on Steam. Here's what I can remember right away:

The easy way is to make an AS3 Adobe AIR wrapper that loads a swf game file using SWFLoader (if you want to use AIR's Flashplayer, EBF3 uses this) or HTMLLoader (if you want to use the web Flashplayer, EBF5 uses this) and communicates with it using LocalConnection. This works similarly with both AS2 and AS3 swfs. LocalConnection is pretty reliable unless the user's computer is under a lot of stress - then the connection may be closed - so it may be worth checking/remaking it every once in a while.

I'm not actually sure if you need the web Flashplayer, or if AIR's flashplayer is sufficient. Either way, AIR's Flashplayer removes the LOW and MEDIUM stage quality options, which may be a good reason to use the web one if that's a feature you need.

The latest versions of AIR will not include a web Flashplayer in the package (expecting the user to have it installed). You can either use an older version of AIR (AIR 21 or earlier, requires pirating Flash CC2015) to enable a "captive" Flashplayer, or use this obscure work-around in newer versions:

  1. Install NPAPI flash player from https://get.adobe.com/flashplayer/npapi/
  2. Download the latest AIRSDK from https://adobe.com/devnet/air/air-sdk-download.html then remove/rename these files: \runtimes\air-captive\win\Adobe AIR\Versions\1.0\Resources\NPSWF32.dll \runtimes\air-captive\win64\Adobe AIR\Versions\1.0\Resources\NPSWF64.dll

And replace them with: C:\Windows\SysWOW64\Macromed\Flash\NPSWF32_32_0_0_192.dll (paste it in the above location and rename the file to NPSWF32.dll) And: C:\Windows\System32\Macromed\Flash\NPSWF64_32_0_0_192.dll (paste it in the above location and rename the file to NPSWF64.dll)

Basically you're just changing some placeholder files to trick the compiler into including Flashplayer. If you publish your AIR application after changing the files, the user won't need to have Flashplayer installed.

You wouldn't be able to figure this out yourself. I got help from Adobe programmers after my complaints went viral on Twitter. It's poorly documented but once you know what to do, it's not a lot of work.

That's the hard stuff done.

You can use the FRESteamWorks() ANE to easily implement Steam achievements, leaderboards, and other features. ( https://github.com/Ventero/FRESteamWorks ) You'll just need to include that in your wrapper source files. The game swf should tell the wrapper when you want to unlock an achievement etc.

As for save data for games, the lazy option would be to keep using Flash sol files. They seem to be less likely to be deleted if they are made by a desktop app. Otherwise you'd have to send your data though LocalConnection (possibly in several parts, I think the limit is 40kb at a time) to the wrapper, which could then create a text file in whatever format you like. If you make the save files in the installation folder, then Steam cloud can automatically back them up without any extra code needed from you.

Another thing to watch out for: The Steam Overlay will freeze if your swf graphics are not being updated. If you have any moments with no animation, you must hide some animation in there so that the overlay keeps updating correctly.

Get in touch if you want more details!

Related