Files and presets

Two file formats, because they answer two different needs and one format handles both badly. A project is the work you did on a sprite, or on a scene of them. A preset is a look, meant to be applied to many.

Projects — .tnmap

File ▸ Save project (Ctrl+S) and File ▸ Open project… (Ctrl+O).

Save writes back to the file the project was opened from or last saved to, without asking. The first save of a new project asks where to put it, and after that Ctrl+S is silent. File ▸ Save project as… (Ctrl+Shift+S) always asks, and the project then belongs to the new file. The title bar shows which file you are working in, with an asterisk when there is something unsaved.

Double-click a project in your file manager and it opens in the editor, with the editor's icon on the file. If the editor is already open, the project opens there, asking first if there is something unsaved, and the window comes to the front. The editor registers the file type for your user account the first time it starts from Steam, and again if Steam moves it to another library folder; nothing needs installing. On Linux that is a desktop entry and a file type under ~/.local/share, which file managers that follow the freedesktop specifications read. New in 1.8.0.

With something unsaved, the editor asks before letting go of it: before File ▸ New project, before a file you open replaces the open work, and before the window closes. Each offers to save first. New in 1.7.0 for opening and closing; until then only New asked.

A project contains:

  • The artwork, embedded rather than referenced.
  • Every painted hint layer.
  • All solver settings, including the export target.
  • The light rig.
  • Every frame, if you have a batch open. See Frames and animation.
  • Every layer — its artwork, its hints, its own settings, its position and whether it is visible — plus the canvas size they are arranged on. See Layers and scenes.

A project saved from a single sprite writes none of the layer or canvas fields, so it stays the same file it always was. Projects from earlier versions open unchanged and become one-layer scenes.

The artwork is embedded on purpose. A project that referenced its artwork by path would be smaller and would break constantly — moved folders, renamed exports, a copy sent to a colleague, artwork since repainted so the hints no longer line up with it. Painted hints cost your time and are meaningless against different pixels, so a project reopens intact or it is not a project.

It is JSON, so it opens in a text editor and can be read. That is how anyone works out what a file claims when a program says it cannot load it.

The first save asks where to put the file. After that, Save project Ctrl+S writes straight back to it and says so in the status bar, and the window title carries the file's name with an asterisk while there is unsaved work. Save project as… Ctrl+Shift+S always asks. If the browser withdraws permission to write — which it may, on a folder it granted access to earlier — the save falls back to asking again rather than failing.

Recovering work after a crash

If the application closes with unsaved work in it — a crash, a closed tab, a machine that restarted overnight — the next start offers the work back: "This program closed with unsaved changes to knight.png, about 20 minutes ago." Recover it opens that copy: the artwork, every hint layer, the settings, the lights, and the whole scene if there was one. Discard it deletes it.

Your own file is never written to. This is not autosave, and the difference is the whole design rather than a technical detail. Saving is a decision — the file you named, at the moment you chose, with the work in the state you meant to keep — and a program that quietly overwrote that file every thirty seconds would have taken the decision away and offered nothing back. There is no undo for it. Ten minutes spent trying something you wanted to abandon would instead be committed.

So the copy goes into the browser's own storage and answers exactly one question at startup: did this program die with work in it? If it did not, the copy is thrown away unseen.

Some particulars, because a safety net you do not understand is one you cannot rely on:

  • It is written after about three seconds of inactivity, not on a timer, so it is captured between actions rather than in the middle of a stroke.
  • There is one copy, not a history. The question has one answer, and a list of ten timestamped states would be a worse undo stack offered at the worst moment.
  • Saving clears it. So does discarding it. Either one is the same statement: there is no unsaved work to keep.
  • A copy older than a week is not offered. That is a browser closed and forgotten about rather than a crash, and month-old work turning up unasked reads as the program having kept something it should not have.
  • If the browser refuses storage — private mode, storage disabled — you get no offer and nothing else changes. The net is not worth failing to start over.

Undo is a separate thing and does not survive a restart. See Keyboard shortcuts.

Crash reports

If the window went blank, the desktop build writes a text file of the error so you can send it. That is separate from the recovery copy above: one is why it stopped, the other is the work.

Help ▸ About shows the folder. Send last-crash.txt from it. A process that dies before the editor can catch the error leaves no file. The details, including that limit, are under The window went blank.

Settings presets — .tnpreset

Edit ▸ Save settings preset… and Edit ▸ Load settings preset…

A preset holds only the settings — no artwork, no hints, no lights. That is what makes it reusable: a look dialled in on one character can reach the other two hundred, go into version control, and be handed to the batch tool, without dragging a copy of a sprite along.

Loading one applies the settings over whatever sprite is currently open.

Presets do not carry hints, because hints address particular pixels and would be meaningless on another sprite. They do not carry lights, for the same reason — a light's position is in sprite pixels.

The one setting that gets special treatment is Contrast radius. A preset saved with it left at measure per sprite will keep measuring per sprite when loaded, rather than freezing whatever the original sprite happened to measure.

Presets and the batch tool are the same thing

A preset is exactly the configuration the batch tool takes, which is the point:

tnmap sprites/ --preset knight.tnpreset

tnmap.exe is in the Steam install folder, beside the editor. Batch and the command line covers the flags and the Steam requirement.

Flags given on the command line override the preset, and the echoed command line shows the merged result, so it doubles as a receipt of what actually ran. See Batch and the command line.

Edit ▸ Copy batch command does the same job from the other direction: it puts a complete command line on your clipboard with your current settings written out as flags. There is a submenu for the shell you are pasting into — Bash, Zsh, Fish, PowerShell or Cmd — because quoting, path separators and line continuations differ between them and a command that needs editing before it runs is not much of a convenience.

Exporting hint layers

File ▸ Export hint layers… writes one grey PNG per painted layer into a folder you pick, named <sprite>.hint-<layer>.png — where <layer> is the layer's internal key, so a knight's flat faces come out as knight.hint-facet.png and its added strokes as knight.hint-inkAdd.png. A Direction layer is the exception: it comes out as a normal map with alpha, in color, since it is not a mask.

Worth having for two things the application cannot do on its own:

  • Seeing exactly what the solver was given. A hint is a mask, and looking at it settles arguments that a preview cannot.
  • Handing the work over — to a colleague, or to version control — without a project file.

Reading them back in is not built. If that would be useful to you, it is worth asking for.

What a browser can and cannot do

The desktop build always gets a proper save dialog with a folder to choose and an overwrite prompt.

Run in a browser, that depends on the File System Access API: available in Chromium-based browsers, absent elsewhere. Without it, files are downloaded instead — which goes wherever downloads go and silently renames the second copy project (1).tnmap. The application tells you which happened rather than reporting a download as though it were a save.