Troubleshooting
Most surprises are a setting doing exactly what it says. This page is ordered by what you would actually see, not by which part of the program is responsible.
The result looks quilted, or pillowy
Every region between lines bulges up on its own, so the character reads as padded panels rather than one solid form.
Turn up Follow overall form in the inspector, under Surface. That is precisely what it is for: it makes the regions agree about the overall shape of the subject and carry their detail on top of it, rather than each rounding independently.
If it is already on and the effect persists, the likely cause is too much detected line work chopping the surface into small cells. Check in Normal view: if you can see creases where the artwork has only shading, lower Max colourfulness so those colored marks stop counting as line work, or paint over them with Remove stroke R.
A limb blends into the body behind it
Light above an arm also lights the stomach below it, and the arm has no sense of being a separate thing.
Fill the arm with In front D. Where two parts overlap, the shared edge is indistinguishable from a fold in one continuous surface, so without being told, the tool folds the surface behind. This is the single most valuable hint on character art with overlapping limbs.
If the limb is also domed rather than tubular, add a Tube axis A stroke down its length.
A hard edge looks rounded
A blade, a plank, a cut-off panel has a rolled lip it should not have.
Paint Cut outline C along the outline itself. Painted inside the shape it does nothing, and the application will tell you so after the stroke.
Texture detail becomes a field of little bumps
Scales, cross-hatching, stippling — each mark gets its own ridge.
Every one of those marks is being detected as line work, which is technically correct and not what you want. Two options, and they combine:
- Remove stroke R over the textured region, to stop the marks creasing the surface.
- Then, if the region needs some surface variation, fill it with Trust methods T and give a detail method a small weight.
An eye or a rivet reads flat
You erased the strokes around it, and now it catches no light at all — which is correct, because nothing left in the picture says it is round.
Fill it with Convex area O. The shape's edge becomes the rim of a dome rather than a fold, and it will catch a highlight as the light moves. Use Concave area I for the opposite: a crater, a dent, a socket.
A well or a barrel lights like a bowl
The hole lights on the side nearest the light, as a bowl or a dome would, or its near edge catches light as if the hole had a floor just below the rim.
Fill the mouth with Opening W. The inside then lights as the far wall of a shaft: shaded on the side nearest the light, lit on the far side, and the same all the way down. Paint the rim as a Flat face P and put a Tube axis A stroke down the outside wall. If the inside tips too much or too little toward you, adjust Camera pitch in the solver settings.
The shadow under my character became a lump
The sprite was exported with its contact shadow baked in — a soft dark pool at the feet, fully opaque like everything else. The outline runs around it, and the outline is what the whole method solves from, so the shadow is read as more character and inflated into a shape sitting on the floor.
Fill it with Not the object X. The area stops being shape and exports flat, so it lights like ground. Your sprite's own transparency is untouched and the artwork still shows the shadow.
Paint it over the shadow rather than generously around it: this is the one hint that removes artwork from the solve, so a loose stroke costs you the bottom of the boots.
My pixel art comes out mushy, and it looked fine in Aseprite
Check the size in the status bar against the size you drew at. Pixel art is very often exported enlarged — 4x for a store page, 8x for a portfolio, and frequently by a factor that is not a whole number.
Every setting here is measured in drawn pixels. Stroke width, blur radius, relief radius, the smallest feature the form pass will keep: at an 8x enlargement all of them are being measured against a ruler eight times too long, so armour plating reads as noise and the blur that should span an outline spans an eighth of one.
The application says so when it notices, naming the size it thinks you drew at, and offers a Work at W×H button that recovers that grid from the file. That is the same as opening the original. Scale the finished normal map up afterwards with nearest-neighbour. The result is not slightly better, it is a different class of result.
A wall or a roof comes out rounded
Buildings, crates, cliff faces: anything whose surface is genuinely flat but turned away from the camera. The silhouette cannot settle it, because a wall and a gentle bulge can have the same outline, so the solver rounds it off.
Fill the face with Flat face P. You do not state which way it points — the direction comes from the edges you already drew. One fill can cover a whole building and still come out as separate walls and a roof, because the lines between the faces are not part of any of them.
Two things to check when the answer looks wrong. If every face is turned too far or too little, it is Camera pitch in the solver settings rather than the faces. If two faces that should be separate came out as one averaged plane, there is a gap in the line work between them — fill it in with Add stroke B.
The result is nearly flat, or nonsense
Check the status bar. If Outline reads zero, or Coverage is close to 100%, your sprite has no transparency around it — so there is no silhouette, and the silhouette is what everything is solved from. Trim the sprite or paint the background out.
The application warns about this on load, and it is the single most common cause of a result that looks like nothing.
A fold I can plainly see has no effect
The detection did not find that line. Usual causes, in order:
- The line is too close in colour to what it sits on. Lower Stroke darkness.
- The line is drawn in a saturated colour and is being excluded as shading. Raise Max colourfulness.
- Contrast radius is too small for the line's width. A soft or broad stroke compared against a surround inside itself reads as a series of beads rather than a continuous line. Check what was measured — it is named above the control.
Or just paint it: Add stroke B over the line.
Painted shading is being read as a fold
Lower Max colourfulness, which is the control that separates near-neutral ink from coloured shadow. Or paint over it with Remove stroke E, which is faster if it is confined to one area.
I painted a hint and nothing happened
Five hints have a precondition and the application tells you when it is unmet, immediately after the stroke:
- "this cut touches no outline pixels" — Cut outline must be painted on the outline.
- "the axis never reaches the outline — raise the reach" — raise Tube axis reach to at least about half the limb's width.
- "this region covers the whole shape" — In front needs a part behind it. Fill only the nearer part.
- "this region covers the whole shape, so nothing is in front of it" — Behind needs a part in front of it. Fill only the farther part.
- "no detail method has any weight" — Trust methods scopes detail methods, and every method is at zero. Give one a weight.
No message and no change usually means the hint agreed with what the tool had already concluded.
Every bump reads as a dent in my engine
The green channel convention. Either the wrong target was exported, or your engine is also applying a flip at import.
The flip is already baked into the file, so leave Flip Green Channel — or Godot's Invert Y — off. Export a calibration target once and this stops being a question.
The picture fades and a spinner shows while I work
A solve is taking a while, which on a large sprite with expensive settings is normal. Keep working: each change you make replaces the one being solved, and the picture catches up with the newest. If it is in the way, Turn off live updates on the banner, or View ▸ Live updates, makes changes wait until you press Solve.
To make solves cheaper: turn Follow overall form off, set any detail method weights to zero, or work at a smaller sprite size while dialling settings in. See Performance and hardware.
The picture went soft while I dragged a light
On a large sprite that is zoomed out, the editor may draft at a lower resolution so the pointer stays attached to the picture. Zoom in: dragging a light then shades the visible pane, and the preview stays sharp. Releasing the pointer always recomputes the full frame. See Performance and hardware.
Importing replaced the sprite I already had
That is the default. Replace the open sprite is on, and any layer marked Artwork (base) or Artwork (new layer) rebuilds the scene from those rows.
To pull hints onto a sprite you already have: Skip every artwork row, uncheck the box, and Import. The checkbox only appears when the open sprite is the same size as the document. See Taking the artwork too.
The Replace checkbox will not turn off
A layer is marked Artwork (base) or Artwork (new layer). Those rows already replace the open scene, so the box stays on and locked. Set those rows back to Skip if you meant the flattened document, or Skip them and uncheck the box for hints only.
My tiles show lines at every seam in a tilemap
The sheet is being solved as one picture, so tiles are smoothed into whatever was packed beside them and flat fill that ends on a tile line is lit as an edge. Turn on Tile grid in the Solver tab with your cell size. Then paint Outline edge G along the tops of platforms, which the grid otherwise reads as carrying on. Do not leave space between tiles to fix it: that makes every edge an outline. See Tile sheets and tilemaps.
If a bright stripe is left at one tile line, look for Outline edge paint that crossed into the tile from the one beside it, such as the rounded end of a stroke along a roof, landing in the corner of the tile below the eave. Paint from one tile in the corner of the next looks like a short stroke along that tile's edge. Erase it. Strokes made with the grid on stay in their own tile, so this comes from paint made before the grid was on, or imported with the image.
If the line is in the colour too, it is the texture filtering across into the next cell, not the normal map.
The status bar says Tiles
A tile grid is on. It is the CPU by choice, and nothing is wrong. See Performance and hardware.
The status bar says CPU
Your graphics card could not be used. The inspector's Solve detail section says why, and that is the actionable part — usually a webview or browser without a working graphics backend, or a driver declining the request.
If it said GPU a moment ago and now says CPU, the card dropped out during a solve. The picture on screen is the finished result, computed on the CPU. The next solve tries the card again. After a second failure the rest of the session stays on the CPU; reload to try again. See When the editor falls back to the CPU.
The output is the same either way; only the speed differs.
Frames in an animation disagree with each other
One frame reads differently from its neighbours, and it shows as flicker in motion.
- Fix the detection radius across the batch. In the editor, set Contrast radius by hand rather than leaving it
measured. On the command line, pass
--radius <n>instead of letting it measure per sprite. - Check for a hint painted on one frame and not the next. The dots on the frame strip show which frames have hints.
The files I dropped became frames, not layers
A drop cannot say whether a set of PNGs is one subject over time or several subjects in one picture, so it always means animation frames. File ▸ Import ▸ Sprites as layers… is the command that says the other thing. See Layers and scenes.
A character I put on its own layer has a rim around it
Each layer is solved from its own silhouette. Split a character into head, body and arms and you have manufactured three seams to fix, because the neck and the shoulder now have rims where they meet the body.
In front D and Behind U are the tools for parts of one object that overlap. Together they give one sprite three depths, a far arm, the body and a near arm, without any layers. Layers are for separate objects that happen to share a picture.
I closed the program and it offered my work back
That is the recovery prompt, and it is meant to appear after a crash, a closed tab, or a machine that restarted with unsaved work still in it. Recover it opens the copy. Discard it deletes it. Your own project file was never written to.
If you discard it, the copy is gone — there is only one. If you did not want the offer, discarding is the right answer; closing the dialog does the same. See Recovering work after a crash.
The height map of two sprites cannot be compared
Each height map is scaled to that sprite's own range. A pebble's white is not a cliff's white. That is a consequence of there being no world unit in a 2D sprite, not a setting. For a parallax effect it is usually what you want; for anything comparing two sprites, it is a trap. See Exporting.
Reload from source is greyed out
Either the sprite did not arrive from a layered document, or the file was opened by a route that cannot be repeated — a drag and drop, or a browser without the File System Access API. Re-import through File ▸ Import and reload becomes available.
The file box opened twice, or saving went to my downloads folder
Some browsers offer the file dialogs and then refuse to let a page use them: a policy set by an IT department, a hardened or locked-down profile, or a "file editing" permission switched off in site settings. The editor finds this out the only way it can, by trying — so the very first file command puts up its own box and then the browser's plain one. It says which browser message it got, in the status bar, and uses the plain box from then on.
That answer is remembered between sessions, so it happens once rather than once per startup. Everything still works, with two differences: saving lands in your downloads folder instead of a folder you choose, and Reload from source is unavailable. Opening several files — frames or layers — uses the same plain box, so those commands keep working too.
If you allow file editing for this site afterwards, choose View ▸ Reset interface to defaults to make the editor try the dialogs again — otherwise it will go on believing what it was told. The desktop build is not affected either way.
The window went blank
The editor caught an error while drawing the window. It shows the error instead of an empty page. Copy it before reloading; the packaged Steam build has no console attached.
On the desktop build, the same text is also a file you can send. Help ▸ About names the folder and can copy its path. On Windows that folder is:
%LOCALAPPDATA%\com.goathollowgames.totallynormalmapper\logs
On Linux it is:
~/.local/share/com.goathollowgames.totallynormalmapper/logs
Send last-crash.txt — it is always the newest report. Older reports sit beside it as crash-*.txt. Email them to
support with what you were doing; a project file or the sprite still helps.
On the web build there is no log folder. Copy the text from the crash screen, or from Help ▸ About after you reload.
Two things this cannot catch, because they never reach the editor:
- The window vanished, with no crash screen and no new file. The process died — often an out-of-memory kill on a very large import. Say what you opened and how big it was.
- The host itself failed before any of the editor's code ran. Same situation: no file, describe the moment.
Reload may offer unsaved work. Recover it if that copy is from before the window went blank. If recovering blanks the window again, discard that copy and open the last file you saved. See Recovering work after a crash.
The crash file is the reason the work stopped. The recovery copy is the work. They are not the same thing, and sending one does not replace the other.
On Linux, it says WebKitGTK is missing
The Linux version draws its window with WebKitGTK 4.1, which comes from your distribution rather than from Steam. When it is not installed, the editor says so before it starts. Install it, then start the editor again from Steam:
| Distribution | Command |
|---|---|
| Ubuntu, Linux Mint, Debian | sudo apt install libwebkit2gtk-4.1-0 |
| Fedora | sudo dnf install webkit2gtk4.1 |
| Arch | sudo pacman -S webkit2gtk-4.1 |
WebKitGTK 4.0 is a separate package and does not count, even though many systems have it.
If the message says WebKitGTK is installed and Steam is hiding it, Steam started the editor inside one of its runtime containers. In Steam, open the editor's Properties, then Compatibility, tick Force the use of a specific Steam Play compatibility tool, choose Legacy runtime 1.0, and start it again.
On Steam Deck, it says to use Proton
On a Steam Deck the editor runs as its Windows version, through Proton. SteamOS does not include WebKitGTK 4.1 and does not let you install it in a way that lasts. In Steam, open the editor's Properties, then Compatibility, tick Force the use of a specific Steam Play compatibility tool, and choose Proton Hotfix or the newest Proton.
Still stuck
Email support. A sprite that reproduces the problem, or the project file, gets a much faster answer than a
description — and File ▸ Export hint layers… is a good way to show exactly what the solver was given. If the window went
blank, attach last-crash.txt as well; see The window went blank.
