Happy Fishing - Ludum Dare #29
- Happy Fishing
Update 26/06/2014: I'm a bit late with the update on this one, but the votes were counted and Happy Fishing took second place for Innovation! Well chuffed.
This weekend was the 29th Ludum Dare, and I was in it again with Alexis. The chosen theme was Beneath the surface. Of course, as soon as the theme was announced, my mind went blank, so we spent the first few hours dumping any sort of relevant idea onto paper. We toyed with a number of ideas, including a facial expression simulator, but eventually we settled on... Happy Fishing!
About the game
Flash would control the game, capturing input and sending messages to Unity when game objects passed out of the screen. Unity would then take over execution until it came back to Flash. Each game could focus on what it does best: Flash on 2D and vector graphics, Unity on 3D and fancy screen effects that take about a minute to apply.
You have a boat and a endless supply of Love TNT. There is an ocean, with a lot of fish that need some loving. You swan around dumping Love TNT barrels and exploding them when they're close enough to the fish. When the fish are affected, they're driven crazy with love, causing them to leap in the air, the one place their love can be expressed.
If two fish fish-slap in the air, a bond is formed, magic happens, and a new baby fish is born! Thus your job is complete. As long as they don't land in your boat and die of a broken heart, of course.
A rant about ExternalInterface
I'm going to segué into a quick rant about
We were originally sending over position coordinates and such every frame or so (the original game had a fishing line rather than Love TNT barrels), but pretty soon we were seeing some lag. A quick
getTimer() later, and we found that calls could take between
80ms to complete (at least on my computer). Basically, if you made a call, you dropped a frame or two. Or three.
I tried a lot of things to try and speed it up; I wasted about 6hrs on it, when I should have just changed tack and moved on (in a 48hr game jam, you don't have time, you just work around any problems).
The problem seemed two fold: 1) Flash would take what you send it, convert it to XML, eval that, take a wee rest, convert the rest to XML, then pass it as a String, and 2) Because
ExternalInterface by default returns the result of the function, it needs to wait the full loop (Flash->JS->Unity->etc) so it can do that.
To try and solve it, in no particular order, I tried:
- Adjusted message length - they were pretty small to begin with, but it made no difference anyway
fscommandinstead, but this didn't seem to matter - it didn't work in IE anyway
- Tried to rewrite the JS functions declared by Flash for
ExternalInterface- this only worked in IE
- Used a
Workerthread in Flash to send the messages so at least it wouldn't block the UI -
Workersdon't have access to
- Used a
WebWorkerto send the message to Unity, so at least it could return immediately -
WebWorkersdon't have access to the DOM
- Used a
WebWorkerto introduce a short asyncronous pause, so at least it could return immediately - this helped a bit, but now you're introducing lag (i.e. Unity was always behind Flash as it was receiving the message late)
- Tried to connect Flash and Unity directly using sockets - Flash can only be a socket server in AIR, and Unity disallows this in the web player
- Tried to connect Flash to a WebSocket and thus to Unity - I'm not sure if you can have local WebSockets - I didn't find much info and couldn't really spend much time on it
In the end, we had to change the game logic - instead of sending position, we send Start and End messages, and simulate the ship in both games - and change the gameplay entirely - gone was the fishing gameplay, hello dropping barrels. Also gone, was capturing input from anywhere - not it was in Flash or nought.
ExternalInterface code is pretty shameful, and it's ridiculous that you have to wait for a return message, or that you can't access it from a
Worker thread. In short, it's good for once-off messages, but not for anything real-time.
If anybody has a good solution to this, I'd love to hear it though.
OK, rant over.
Overall the experience was pretty good - I love game jams because you just go into this hyper-productive, focused state. To be honest, I spent way too much time trying to fix the
ExternalInterface problem (and on more modern hardware, it's less of an issue), but other than that, it's crazy how quickly you can knock out a game once you drop all that baggage around architecture, maintainability, and bug-fixing :D
The game itself is available to play at https://divillysausages.com/ludumdare/29, and you can find the game page at http://www.ludumdare.com/compo/ludum-dare-29/?action=preview&uid=12329 if you want to vote on it.
Also attached at the bottom of the page, is the Flash source, if you want to see what half a commented project looks like.
A huge shout-out has to go to the Ludum Dare Paris organisers for setting up the shared space, the sponsors, etc. We got to meet a lot of other game dev people, and got to see some interesting games. The next one should be even better ;)