Photoshop Exporting & Scenegraphing


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.


psd-SaveForWeb.png
 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.


psd-ScriptRun.png
 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.


psd-ScriptCode.png
 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.


psd-Blender.png
 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.


psd-ComplexLayers.png

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


psd-ExportedScene.png

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.


psd-InGame.png


Animation

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


psd-PhotoshopAnim.png
 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.


psd-MotorCode.png
 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.

Comments

Log in with itch.io to leave a comment.

Worth noting that photoshop adds a lot of bloat to their psds - it might be worth considering layered tiffs at some point if filesize ever became an issue (not that it should at such a tiny resolution!)

As a designer who don't code, I love your devlogs

(+1)

great after great, keep on share this, it's wonderful

(+3)(-1)

Reading this, I know that this is the kind of thing I should do for Atlantic ‘41, so of course I’ll never get to it and keep wasting enormous iteration time, fumbling with evil layers and dialog boxes :) You’re always inspiring regardless.

(+1)

Cool :)

I guess you are already aware of it, but we never know : https://helpx.adobe.com/photoshop/using/generate-assets-layers.html

Photoshop has some interesting features :)

(+3)

I didn't know about that and it's almost exactly what I want. When did that get added? Clever hiding it under a single-option "Generate" submenu.

It even supports svg shapes and exporting sub-layers alongside containing groups. Definitely the best way to do multi layer exporting.

I still need the positions and structural hierarchy so it's not quite enough for the Mars case but I'll put it in the toolbox for other projects. Thanks for pointing it out :)

Yes, it's well hidden and not very new...

I use it all the time, combined with Smart/Linked Objects, it's possible to do some advanced automation stuffs !

I just love so much reading your devlogs <3