itch.io is community of indie game creators and players

Devlogs

Photoshop Exporting & Scenegraphing

Mars After Midnight
A downloadable game

Mentioned briefly in the Typography post, one of my aims for this project is to streamline the process of editing something -- images in Photoshop, vectors in Illustrator, sound effects in Bitwig, etc -- and then getting that thing into the game.

Adobe Illustrator makes this easy enough: just work in SVG and I can parse that from a python script. Bitwig also has a simple region bounce feature to dump a wav file in a directory that the build tools can then pick up.


But Photoshop

Adobe has multiple ways to get asset-friendly PNGs out of Photoshop but unsurprisingly each of these ways is peppered with small annoyances.



 Save for Web. Cutting edge in 2006


If all I wanted was a flattened PNG of the entire PSD then I'd be grudgingly satisfied. Being selective about which layers/groups to export, and how, is an important part of making Photoshop useful to me for creating game assets. It bugs me every time I need to retype a target filename, select the export folder, show/hide the right layers, or any other slightly complex thing related to getting images out of the app and into the game.


Script It

My usual move in these cases is to write a custom script, and fortunately Photoshop has an embedded Javascript environment for this kind of thing.



 Oooh, timesink!


It's too bad that writing and debugging these scripts is a frustrating chore. Decoding a decades-old proprietary API and using it effectively can get tiresome. Functions that don't work how you expect, workarounds for seemingly-random variations, mucking with document state and potentially wiping out your file on errors. And all in Javascript running within Photoshop, where you'll never know something's wrong until it happens.

I made a stab at a comprehensive in-app export script a few years ago and got something marginally useful put together. Maintaining and expanding the script ended up being too much trouble though and I eventually abandoned it.



 Export script


Before describing where I ended up for this project, I should explain what I'm really using Photoshop for, and why the built-in export options weren't enough.


Scene Graphing Made Hard

The game uses many composited 2D scenes. Nothing fancy, just a hierarchy of images placed here and there, hidden or visible, dynamic or static, etc.

For a long time I've been casually searching for a well-featured 2D scene editing tool, preferably one that supported animation too. I guess my casual searching skills suck because last year I stopped looking and wrote a toolset in Blender to do it.



 Scene constructed and animated in Blender


This toolset enabled creating a hierarchy of image/sprite nodes, animating them, and then easily exporting the result to a game-friendly asset for playback. Being very open and extensible means that Blender is a great environment to build something like this.

I was pretty happy with this solution for simple scenes, but anything having more than a few nodes fell into the same pit that all the other scene editing tools I know of have with Photoshop integration: lots of files/groups/layers to export before they were ready to be added as nodes.

When I started exploring ways to just get PSDs directly into the build pipeline for Mars I realized that a functional scene construction/editing tool was right in front of me all along.


But Photoshop Again

Photoshop's groups and layers are basically a 2D scene graph.



If I could just get this structure directly out of Photoshop and into the game, I wouldn't need Blender or any other scene-related tool at all. Animation would have to be handled separately but let's skip that for now.

The key to making this happen is psd-tools, a fantastic python library that can open and inspect PSD files. It gives access to all the layers, their properties and, combined with PIL, the ability to composite groups/layers/shapes however I want.

Using psd-tools and PIL, I wrote a build script to convert each PSD file into a folder containing:

  1. A _def.json file defining the structure
  2. A bunch of PNGs for the layers



The script ignores layer visibility, since I use this too often for editing convenience. Instead, a simple layer naming convention describes how to ignore, combine, or otherwise specially process each layer.

  • #name Ignore layer/group
  • name+ Flatten group and export as single image
  • name$ Write layer shape points instead of image

So now I work recklessly in Photoshop with all the layers, groups, patterns, effects, shapes, type, and other usual features. Hit Command-S to save the whole PSD, then build&run the game to see any changes.

Besides the energy saved dealing with manually exporting all the time, the organizational benefit of having 1 scene = 1 PSD simplifies everything from assets to code.


On the Game Side

For the game's part, it loads the JSON directly into a hierarchy of nodes with positions, properties, and optionally attached images. All that constitutes a scene that can be addressed and animated or whatnot.




Animation

Photoshop does support some rudimentary animation features. I've never gotten along well with them though and that hasn't changed for Mars.



 Animation in Photoshop, mingling a little too tightly with the construction


Instead, I've done the expected and written an animation definition language that can address the scene or any other game variables directly.



 Custom animation definition language


I might post more details about this animation system later but first I think I need to start talking about the actual gameplay for this dumb game. Next time.

Read comments (8)