Intro : This is a serious game designed to teach players a bit about how water treatment and supply works; specifically how its organized in the Île-de-France region – around paris. The game map is loosely based on that region and divided by areas which corresponds to the master water supply facilities that share connections around the region. The map shows you which levels are accessible to play or re-play, you can zoom it or out with many graphical details. The three areas need to be completed and in order to complete one, you need to connect all buildings together by playing the game levels, and also buy the missing buildings using the coins you collect.
This is not a management game however, you do not have to save money or buy things in advance, it is balanced so you can easily get to the end without worrying too much. The action of buying or clicking buildings on the map will tell you more about what these buildings do and how they relate to others… Their in-game worth also gives players a hint on how important they are.
The challenge here was to keep the package size as low as possible yet keep the graphics at maximum quality.
The game had to be created for the web (that would be published on an educative game portal) , and as a mobile app.
Also having a feeling we could benefit from Flash Professional CC as you’ll see later in the article in ways it was not necessarily meant to be used – specially these days, having a game engine ready to run anywhere and of course being fluent in as3, the choice of using Flash/Air was obvious.
Trust me, we do diversify, but why not just use what is both familiar, fun to work with, and ‘just works’ , everytime you can? right?
Rough gameplay description:
The game is about connecting pipes so the water can flow from one building to the other, pumping fresh or dirty water, transporting it accross facilities for treatment, and finally bringing it back to homes. The player actually needs to “repair” the system. In game levels, you can see two disconnected ends of pipes, and you can throw pipe sections (straight or curved) at any pipe end with a swipe motion, just as long as the initial orietation of the pipe section in the pipe launcher had the right orientation and pipe type (I hope this means something to you … here’s a picture)
An optimized “route” is laid out for you in semi-transparency in the first levels, but you can actually connect pipe sections however you like as long as you connect the start and the end. Pipe sections can be destroyed by touching them wherever, which will make all connected pipes fall. And as you go, obstacles appear to bounce off of, and finally – robots that will mess with you. If you like a challenge, try to do the highest combo possible (a combo being connecting several sections without missing one).
Pipe sections, can bounce off of “static” pipe sections that are already connected, or obstacles, in fact bouncing off of obstacles is a gameplay mechanic at some point. Also, to make the game fun, pipe sections should feel like we’re really throwing them away, making them bounce “naturally” according to their shape, and rotate in the air. Even though they’d rotate, a counter-intuitive decision was made : no matter how the pipe section would contact another pipe – assuming it could connect to it – the rotation of the pipe when in the air would not matter to if it would connect or not. That makes the game much easier, and in the end people would understand the idea of choosing in advance how your pipe should be oriented before throwing it in the launcher.
To make everything easier to work with we decided to go with grid based levels.
So to make pipes realistically “fly off” of the launcher, bounce off obstacles, we went for a full physics engine (nape in fact).
Yet to connect pipes together, we had a grid system, and using joints was absolutely not convenient (we tried) – so the physics engine is used to detect colllision, to animate the pipe section once in the air, but as soon as the pipe collides with an available pipe section that it can connect to, a custom algorithm comes in to check if the pipe can actually connect, and kind of reverse kinematic the whole thing to place it correctly inside the grid.
So people think using physics engine is overkill really. and it is sometimes I guess, but this was an opportunity to save time , and nape is fast enough and for most collision testing with a high enough number of game objects, its best to use a physics engine, even if you only need sensors, rather than rolling your own… but you have to accept that it actually tries to simulate physics in a realistic way, and as we discovered through prototyping, realistic doesn’t mean fun, so you might end up with an hybrid system, sometimes forcing the engine into something its not necessarily suppossed to do.
Level Design, Citrus Engine style.
As I said earlier, game levels are grid based – it seemed obvious to us.
The game being created with Citrus Engine, We use the citrus camera to make the “grid” simply fit the screen as the game level starts.
And we load the game level via .swf files or embedded .swcs. With .swf files, over some time we were able to leave the level designer experiment with levels on his own with a live reloading system, he could change levels in flash professional CC, export an .swf file and just use the Citrus console to reload his level to see his changes being applied directly.
We used flash components in the .fla file, and use the same principle as ObjectMakerStarling to create game objects in the grid. To allow for an even easier workflow, we also allowed margins of errors when it came to rotation and position in the grid so that the level designer could almost just drag and drop stuff on his stage without worrying too much. When finalizing levels, this came as a nice tool where game and level designer wouldn’t need to wait around for new builds to be made and just play around as we adjusted tweens , screens and sound with other members of the team.
99% of all graphics were designed with flash – even the video intro and outro.
And the amount of details, filters, layers, meant two obvious things of course : forget about GPU mode (we shouldn’t even mention that right?) and forget about the native display list. So the Starling framework is our choice, and Citrus Engine already handles it fine with multi-resolution support. Unlike other projects where we pre-rendered vectors into several scale factors however, we wanted to keep the package as light as possible and use vector rasterizing on the fly – pretty much like what the Dynamic Texture Atlas Generator does , but we wanted to try out DMT for the chance of caching textures on disk.
So the idea is of course to tailor textures for the users screen instead of just getting a set of texture at a scale that’s closest to the required scale (or content scale factor in Starling) .
But that does mean, not using the multi-resolution support of Citrus Engine ! fortunately you can use ViewPortMode.LEGACY which turns it off, and set _assetSizes to  so that the starling stage will be at a 1:1 ratio compared to flash. – we actually figured out an hybrid way to do that to make DMT co-exist with our system in the end.
Anyway, the map is huge and had to be divided in the background, as well as the level’s intro sequences, for that specific case, we had to build a custom rasterizer as DMT was sometimes a bit frustrating with Citrus Engine on the side. We hope to have a similar system built in someday in CE, because we found that it helps a lot. The look of this game is very specific, a look that I appreciate a lot actually, maybe not minimalistic enough! Since we had vectors, why ruin it by rasterizing them in advance right?
The biggest advantage is saving package memory… but also , as it was the case in this project, if there’s a lot of changes graphically, we just had to grab the newest .swc from a shared folder and that’s it. We agreed with the designer to an instance naming convention and class names for some movieclips, so every building and numbers on the map can be modified without us having to do anything extra. What we did for the map is simply grab buildings, render the map without buildings on a texture, render buildings separately, change numbers on level numbers – when needed – and just place everything back where it should be, since we also had all relative position of all elements – which we couldn’t have with plain png files and so on.
It’s just fantastic to read registration points, transform matrices and so on, to re-create a full “scene” in Starling with just a couple of nested loops.
Of course ideally there would be a tool to do that instantly, and seperate as much as we can data and graphics to get the best flexibility possible.
A problem with ASC 2.0
There was, and still is, a big issue with ASC 2.0 . almost all ui elements had some bevel filter at some level, when built with asc 2.0 all bevel filters were completely inverted/reversed … and all dynamic text fields disappeared – which was bas since we used them at some point… The fix is to build with asc 1.0 (of course) or clone identically all filters, text fields at their right position and re-apply/replace them. We found that out to late in the project though. Even now, we have some issues with asc 2.0 and some .swc files, it’s just very hard to track and post a viable bug report in that case, since this is only a “cosmetic” issue and we’ve got more important stuff going on these days , but here is the link to the report.
In the end…
I’m a very big fan of doing everything through code. But this project made me realize once more, that the tools you already have – flash pro in this case – can be great to collaborate, and build some tools to improve your workflow as often as you can… this is a personal opinion, but you’ll definitely improve the game indirectly by making collaboration faster between members of the team, specially if everyone is open to suggestions and you have a free flow of ideas to improve on the game , or even disagree and so on… And .swf is still a great format for prototyping but also , once exported as .swc, a great format to read visual data. In fact I’d be very excited for a project that would require using the readGraphicsData() function of the flash Graphics API, I’m sure we still have a lot of cool tools to create with Flash and Actionscript.