← back to the editor · about
OTTOMANCER — CHANGELOG
=============================
(for people who use it — what changed, in plain language)
v0.64.0 — the version you are running
--------------------------------------
- **Mesh effects.** Select an image layer and the properties panel has a new
"Mesh effect" section: Twist, Bloat, Warp, Suck In and Caustics. They bend
the artwork itself rather than moving it — a vortex, a swell, a travelling
wave, a collapse to the centre, light through moving water — with sliders
for each and a readout of what the detail setting costs.
They run over the length of the animation, so press play. Twist, Bloat and
Suck In are at rest on the very first frame by design; the panel says so.
**Where they appear:** the editor, and the PNG sequence, WebP and video
exports. **Not yet in the Spine .json** — those layers export with their
artwork undeformed, the Spine badge in the toolbar says so, and the export
dialog lists it before you export rather than afterwards. The Spine half is
built and tested and is the next thing being wired up.
A layer inside a clipping folder keeps its artwork and does not take the
effect; that is listed too.
v0.64.0
--------------------------------------
- **New layers no longer land where you cannot see them.** Whatever you add —
an emitter, a folder, a path, an image, a paste, a premade effect — the
Scene list now scrolls to it and opens the folder it went into. The layer
list is only a few rows tall on most screens, so a new layer could land well
below the fold: it was there, it was selected, and nothing on screen changed
except the panel on the right. It only scrolls when the new layer is out of
view, so it will not jump around while you are looking at something else.
- **Adding something now puts it next to what you had selected.** Pasting, the
Premade Particles scenes and your saved effects used to drop the result at
the bottom of the folder instead, which on a long list could be dozens of
rows away from where you were working.
- **Double-clicking an image no longer changes an emitter behind your back.**
Double-clicking a sprite places it as its own layer — but it was also adding
that sprite to whichever emitter you had touched last, which changes what
that emitter draws. Single-clicking to give a sprite to the selected emitter
works exactly as before.
- **Ctrl+Z now really does undo one thing at a time.** Two quick clicks on the
"+" buttons used to merge into a single undo step, so one Ctrl+Z took back
both.
- Pasting layers with Ctrl+V was broken for part of yesterday and is fixed.
v0.64.0
--------------------------------------
- **Click a folder and you can now add things straight into it.** The
properties panel on the right has a new "Add to <your folder>" section
under the transform, with + Emitter, + Folder and + Path. They go inside
that folder, the folder opens so you can see them arrive, and Ctrl+Z undoes
each one.
It stays on the folder after each add, so you can put several things in
without clicking back and forth. The buttons in the left toolbar still work
exactly as before.
- **Adding a path to a closed folder no longer looks like nothing happened.**
The path went in correctly but the folder stayed shut, so you saw no new
layer anywhere while the panel jumped to it. The folder now opens, the same
way it already did for emitters and folders.
- **A path is called a path.** The properties panel used to label it
"emitter", which was wrong the moment you made one.
v0.64.0
--------------------------------------
- **Pressing Delete with keyframes selected no longer deletes the whole
layer.** If you selected keys in the timeline and pressed Delete, the layer
itself was removed. Backspace did the right thing, which made it doubly
confusing. Ctrl+Z always brought the layer back, but it should never have
happened. Delete now removes the selected keys, and still deletes the layer
when nothing is selected.
- **Keyframes on particle settings now show up on the layer's own row.** If
you animated something like Rate over Time or Start Speed, the layer showed
NO keyframes at all unless you expanded it — and the timeline header said
the layer had none. They are drawn and counted now, and you can select,
move and delete them from the layer row like any other key.
- **The timeline header counts correctly.** With "All layers" on it counts
layers that have keyframes; on a single layer it counts that layer's
animated properties. It was over-counting.
- **Clicking near the bottom edge of a button in a dialog now works.** A hint
line at the bottom of some dialogs was floating over the row above it and
swallowing clicks, so a button could look perfectly normal, be clicked, and
do nothing.
- **"Estimate" in the export window now scrolls its answer into view.** It was
written below the visible area, so the button looked like it did nothing.
- **The light theme is readable.** Several small labels — the status bar,
panel hints and the names of switched-off particle features — were too faint
against the background. The switched-off names were the worst, using a
colour picked for the dark theme. Both themes now meet the standard
contrast level everywhere.
v0.62.0
--------------------------------------
- **Spine animations are now named "play_loop", "idle_loop", "in_once" and so
on.** The ending tells you how the animation is meant to be played without
opening the file. **If you have already put an Ottomancer skeleton into a
game and your code asks for "play", it will need to ask for "play_loop"
instead** — re-exporting an old project gives it the new names. Nothing else
about the file changes, and the effect plays exactly as before.
- **Every exported skeleton now hangs off a single bone** called MASTER, so you
can move, rotate or scale the whole effect in Spine by grabbing one thing
instead of selecting everything.
- **The export instructions were naming an animation that was not in the file.**
The little report in the zip said to play "play" while the skeleton
contained "play_loop" — a Spine runtime asked for a name it does not have
shows nothing at all, with no error, so this looked like a broken effect.
Fixed, and the same mistake in the READ-ME files that ship beside the
effects is fixed too.
- **Choosing Spine 3.8 now tells you what 3.8 cannot carry.** 3.8 still works
and the file still opens — but two things only exist in 4.0 and later: the
editable colour (on 3.8 every colour is keyed on every frame, so you cannot
just retint it in Spine) and curved keys (they flatten to straight lines).
You are told before the export runs instead of finding out afterwards.
- **The ready-made effects are now "Particles".** The ✨ button that drops in
one of the 119 built-in effects said "Effects", and that group is labelled
**Premades** so it is clear these are finished things to start from.
- **The timeline header no longer says "no keys" on an animated project.** With
"All layers" on it reported no keyframes at all, however many you had.
- **Undo keeps your selection.** Pressing Ctrl+Z no longer clears which layers
were selected, including a multi-selection.
- **Editing a range across several layers no longer destroys the other end.**
Typing a new minimum into two selected layers used to overwrite both the
minimum and the maximum.
- **The colour-tag dot in the layer list is easier to hit.** It is a 7-pixel
dot with a much larger invisible target around it now.
- The changelog page itself is rendered as plain text rather than as markup, so
nothing in it can be interpreted as code.
v0.61.0
--------------------------------------
- **Every particle feature is always in the list now.** Unticking one used to
make it vanish from the panel, and the way back was a small "Add behaviour"
row at the very bottom that was easy to miss entirely — on a new project the
panel showed seven modules and hid thirteen. An unticked feature now stays
exactly where it was, collapsed to a single line, and you can open it by
**clicking its name** whether it is ticked or not. Ticking it still turns it
on and opens it.
Each one that is off also now says what it would do, in plain words —
"make them wander instead of travelling straight", "bounce them off a
floor" — so the panel tells you what is on offer instead of listing
nineteen pieces of jargon.
- **The colour and curve windows open small.** The gradient editor was opening
at about 57% of the width and 70% of the height of the screen every time,
which is most of a laptop display for one colour ramp. It now opens at
roughly the size Spine's does — under half the height, about a third of the
width. Both windows are still resizable, and the size you drag them to is
still remembered.
- **The supporters page is gone.** If you support the project on Ko-fi,
Patreon or itch.io, you are already listed there; there is no reason for a
second list here. Supporting the project is unchanged — the support page is
where it always was.
- **A description of the editor that a program can read.** New at
/schema.json: every module and every property, with its type, its default,
its unit and a one-line explanation — 19 modules and 112 properties, all of
them described. It is generated from the editor itself, so it cannot fall
out of step, and it is there so an AI assistant can find out what the tool
can do without clicking through the interface to guess. Nothing in the app
changes because of it.
- **Typing a value into Position, Rotation, Scale or Opacity now keys it at
the frame you are actually on.** This is the important one, and it was
silent. The panel read the playhead when it was *drawn*, not when you
pressed Enter — and nothing redrew it when you moved the playhead. So every
transform you typed landed one move behind.
What that looked like: put a key at frame 0, drag to frame 83, type a new
number — and instead of a second key, the frame-0 key was **overwritten**
and nothing was written at frame 83. The layer then did not animate at all,
with no error and nothing on screen to say why.
It only ever affected those transform boxes. The emitter settings and
dragging the handles in the canvas always read the playhead correctly, which
is exactly what made it so confusing: the same idea worked or did not
depending on which control you reached for.
- **The keyframe diamond now records the value the property actually has at
the playhead.** It was planting the value the panel had been showing —
measured, a key written as 111 where the real value at that frame was 122.5,
which visibly changed the motion you had just made.
- **The properties panel follows the playhead.** Move the playhead and the
numbers update to that frame. It deliberately does *not* refresh while you
are typing in one of those boxes, so a half-typed number can never be wiped
out from under you.
- **Copying layers into another project now brings their artwork.** Copy an
emitter, open a different project, paste — previously you got the layer,
the particles and the settings, and no art. Nothing failed and nothing was
said; the layer simply drew nothing. Folders, texture sheets, layers using
several sprites and multi-selections all carry their images now, and only
the images actually in use travel.
- **Cleaner Spine exports.** Three faults in the exported curves, none of
which showed up in a preview because they all happened *between* frames, so
only a game engine playing the file at its own frame rate would ever draw
them:
- a spinning particle could sweep through a pose it never held, by up to
90 degrees;
- a bar or panel that grows in steps could be drawn briefly **mirrored**;
- some curves were written in a form a game runtime cannot read back.
Exported animations are the same size as before — the whole change is one
extra keyframe across the entire library.
- **An export warning that cried wolf.** Ottomancer warns when two layers
share a name, because Spine can then mix them up. It was counting a folder
and a layer inside it — which can never be confused — so it fired on half
of every project. It now fires on the five cases that are genuinely
ambiguous.
- **Seven new effects**, all in the dark and gothic set: shadow bloom, blood
mist, rot spread, candle guttering, raven scatter, iron sparks and steam
vent burst. **Ink splat and speed lines were rebuilt** — the ink now throws
proper droplets and ligaments instead of round blobs, and the speed lines
are hard-edged strokes that taper at one end the way a drawn one does.
**Fog roll** is twice as long, because at its old length the whole bank of
fog visibly swelled and shrank once a loop, like a metronome.
v0.60.0
-------
- **A "Settled" button, so the preview shows what you actually get.** A
looping effect is delivered already running — the gif, the video and the
Spine export all start with the effect in full flow. The editor did the
opposite: it started from an empty screen and filled up, and every change
you made reset it back to empty.
That mattered more than it sounds. Across the built-in looping effects,
most showed *nothing at all* on the first frame while the delivered version
of that same frame was full. So the thing you were adjusting was not the
thing you were shipping.
The "Settled" button in the timeline bar switches the preview to the
delivered behaviour: the effect is already running when you look at it. It
is off by default because it costs a moment of extra work on every change —
on the very heaviest effects about a second — so it is there for when you
are judging the final look rather than something you pay for constantly.
Your project file is not touched either way. This only changes what the
preview shows you.
- **The colour and gradient window no longer grows until it is unusable.**
Opening a colour or gradient editor and clicking in it made the window a
little bigger every single time — a few clicks and it had swallowed the
screen. Shaping a gradient is dozens of clicks, so in practice the feature
could not be used. It was one word in one line: the editor measured itself
including its own border and then grew by that border, over and over.
- **Clicking a point in the Curves window selects it again, instead of adding
another one.** This only ever happened if your Windows display scaling is
set above 100% — 125%, 150% and 200% are all common, and at 100% it worked
perfectly, which is why it survived so long. The window drew in one set of
units and listened for the mouse in another, so every click landed slightly
off and fell through to "add a point".
- **The hex box in the colour picker showed the colour you picked.** It read
#ffffff for every colour, always — the picker itself was right, the little
white swatch beside it was right, and only the number was wrong.
- **Saving and renaming can no longer be blocked by the browser.** Save As,
renaming a layer, naming a curve or a gradient and eight other places asked
for a name through a browser pop-up. Browsers are allowed to refuse those:
Chrome offers a "stop this page creating more dialogs" tick-box, and after
that every one of them fails. Save As is not something that should be able
to die because of a tick-box. They are all ordinary windows in the app now,
with Enter to accept and Escape to cancel.
- **Keyboard shortcuts no longer reach through an open window.** With a dialog
open, Ctrl+Z and Ctrl+A were still reaching the project behind it — in one
case deleting a five-layer folder while the window in front carried on
showing its old contents. Escape sometimes needed two presses for the same
reason.
- **Undo no longer leaves the panel saying the scene is empty.** After a
single Ctrl+Z the panel under the layer list could read "nothing in the
scene yet" while the tree plainly showed your layers, with Delete still
live underneath it.
- **Curve handles on straight segments.** A segment stayed straight until you
bent it, and a straight segment had no handles — so there was nothing to
take hold of to start an ease. Every segment now has them, and each end key
shows a dashed marker for the other side of the loop, with a "Match for
loop" button that lines the two up in one click.
- **The timeline zooms out further.** It used to stop at exactly the length of
your animation; it now goes to four times that, so you can see the whole
thing with room around it.
- **Layout fixes you would have hit on a laptop.** The toolbar no longer
shifts sideways as the CHECK badge changes its wording, so Export stays
where you left it. The layer tree is no longer squeezed to a sliver on a
short window. Dragging the timeline tall and then making the window smaller
no longer leaves the stage 46 pixels high with the overlays on top of each
other. The readout under the stage no longer runs off the edge.
- **Things you can now read.** Active buttons in the toolbar were a mix of two
text colours, one of which failed every contrast guideline; they match now.
In the light theme the three panels over the stage were dark-on-dark —
including the button you press to get back out of the light theme. Status
messages are readable while a window is open, which is where the important
ones appear. Switched-off buttons now look switched off.
- **Smaller things.** The colour picker opens fully on screen instead of
hanging off the bottom, and its hue and transparency strips are no longer
thinner than a scrollbar. Two rows in the timeline that used to draw
identically now show which is which. The tabs in the Export window stop
jumping under the cursor. The Export window explains the tab you are on
rather than always leading with Spine.
v0.59.0
--------------------------------------
- **Each effect now shows a bar in the timeline saying when it plays, and you
can drag it.** Turn on "All layers" under the timeline and every emitter
gets its own bar: a solid block for as long as it is throwing particles, and
a fainter tail for as long as those particles are still on screen after it
stops.
That second part is the useful one. An emitter stops emitting long before
the picture goes away, so the tail is what tells you when a layer has
actually finished fading — which is the moment you usually want the next
thing to start on.
Drag a bar left or right to move that effect earlier or later. Say you have
a firework: a launch trail, then the burst. Drag the burst so it goes off
exactly as the trail fades, or leave a gap to build anticipation. You are
not editing the particle system to do it — nothing about the effect changes
except when it starts. It snaps to whole frames, and Ctrl+Z takes it back.
Clicking the empty part of a row still drags a selection box over keys, the
way it always did.
v0.58.0
--------------------------------------
- **A layer following a path now moves in an exported web page.** It didn't.
If you attached a layer to a path and exported the web bundle, the effect
played and that one layer sat perfectly still — no error, no warning,
nothing to notice unless you knew where it should have gone.
The small player that runs a web bundle has no idea what a path is, and it
can't be taught one. It doesn't need to be: where a layer sits on a path is
just a position over time, and position is something the player has always
animated. So the export now works out the movement itself and writes it as
ordinary keyframes, exactly as if you had animated the layer by hand.
Your saved project is untouched — the path is still a path, still editable.
Only the exported copy is flattened, in the same way images with a tint are
baked into the bundle's artwork.
v0.57.0
--------------------------------------
- **Spine exports carry about a third fewer keyframes, for the same motion.**
A particle that is simply falling traces a curve, and until now the exporter
could only describe a curve as a chain of straight lines — so it wrote a key
every few frames to keep up. Across the whole effect library that came to
two million keys, and not one of them was curved.
A Spine 4.x export now fits a real curve to each stretch of movement. Over
40 effects that took 191,849 keys down to 123,927. A falling arc that needed
61 keys now needs 2, the animation looks the same, and the export is also
faster to produce than it was before.
Checked frame by frame against the old export — 6.4 million samples, every
one inside the tolerance each effect sets — and then imported into Spine
4.0.64, edited there, and exported again with the curves intact.
**This applies to Spine 4.0, 4.1 and 4.2 only.** Spine 3.8's format shares
one curve between every property of a key and stores it as a proportion of
the value change, so it cannot describe this. 3.8 exports are unchanged. The
export window now says which versions give you the smaller file.
- **The settings panel on the right had controls nobody could read.** The
dropdown that picks how a value works — one number, a random range, or a
curve — was 26 pixels wide, while its longest option reads "Random between
two constants". About ten pixels of text were visible.
It is now a labelled button that says which mode it is in and opens a proper
menu explaining each one. Alongside that: 110 controls were under 20 pixels
tall, the keyframe diamonds on the transform rows were too faint to see
against the panel in either light or dark, and the small × that removes a
sprite was the tiniest target on the whole panel despite deleting something.
- **Six effects showed a colour they never declared.** Anything that stays put
for the whole animation — a ring, a pool of liquid, a corner bracket — was
written as though it slowly changed colour over its life. Because those
elements are built to last an hour, that change never got started: they held
their opening colour for ever, which was always the palest end. The files
now say what they actually draw, so the next person to edit one is not
misled. Nothing on screen changed.
v0.56.0
--------------------------------------
- **The effects page now shows the effects.** All 119 of them, playing, as
small looping animations. Until now that page described 119 visual effects
entirely in words — the only picture on it was the site icon.
Each one is rendered by the editor itself, using the same code that draws
the thumbnails in the Effects picker, so what you see on the page is the
effect as the editor actually draws it rather than a screenshot taken once
and left to go stale.
The whole set is 1.6 MB and loads only as you scroll, so the page still
arrives as fast as it did.
- **The gif colour fix from v0.55.0 did not cover gifs with transparency.**
Same symptom, reached by a second route: when an effect had transparent
areas, the exporter counted only the pixels it could see, and the sampling
step could line up with the picture again — a 251-colour test came out with
ONE colour in its palette. Exporting a gif with a transparent background now
picks its colours from the whole picture, the way an opaque one already did.
v0.55.0
--------------------------------------
- **GIF export could produce a blank file, and every gif was picking its
colours from a few narrow stripes.** A gif can only hold 256 colours, so the
exporter samples your frames to choose them. The sampling step could line up
with the image width — and then it read the same few columns of every row of
every frame, and judged the whole effect from those.
At worst it read **column zero alone**. For one effect that column is empty,
so a 9,395-colour animation came out as a valid 44 KB GIF of flat
background — a blank file that looks like a broken effect rather than a
broken exporter.
The blank case was the extreme, not the whole problem. **At the default
export size it was choosing from five columns out of 1080** — half a percent
of the picture. That has been true of every gif this tool has ever written.
Now it reads the whole frame. Measured on the effect that came out blank:
the same frames went from a 2-colour palette to 255.
- One delivered gif was affected and has been rebuilt. Every gif is now
checked against the colour its own frames actually carry.
v0.54.0
--------------------------------------
- **A project file could load perfectly and then never be saved again.** Two
shapes of file did it: an animation event carrying a zero or an empty text
value, and a layer glint saved with only some of its settings. Both loaded
fine. Both then failed every save, with the tool telling you it was a fault
in the tool — which it was.
The cause was the file being written one way and read back another, so the
save's own safety check saw them disagree and refused. Both directions now
match. Nothing you have made can be in that state — the editor cannot
produce either shape — but a file that opens and will never save is exactly
the kind of trouble that is impossible to work out from the outside.
- **Asset tints now travel in web bundle exports.** If you tinted an image and
exported a web bundle, the bundle shipped the ORIGINAL untinted picture and
said nothing — the effect played in the wrong colours. The bundle now
carries the artwork you were looking at.
This works the opposite way round from the Spine export on purpose: Spine
gets white art plus an editable colour, because you can recolour it there. A
web bundle is finished when it leaves, so it gets the picture as you saw it.
If you turn "Embed images" off, the tint cannot travel and the export now
tells you so rather than quietly dropping it.
v0.53.0
--------------------------------------
- **Spine export was refusing 57 of the 184 effects, and now works.** Every
effect built as a set of animations — an "in", an "idle" and an "out" over
the same layers — was blocked at the export dialog with:
EXPORT BLOCKED — the file does not match what was asked for:
animation(s) missing from the file: play
That covered every frame effect: chain, electric, fire and frost, and all
their tall and square variants.
The export itself was correct the whole time. The safety check standing in
front of it was asking the wrong question — it looked for an animation named
"play", the default, even when your project declares its own names. So it
refused a perfectly good file and told you it was a fault in the tool, which
it was.
All 184 now export. Checked one at a time, through the dialog's own
refusals, not around them.
- **This is the third time in two days that something you would hit was
invisible to us**, and all three had the same shape: the automatic checks
exercised the code the way a BUILD does, and nobody had ever driven the
thing the way a person does. The export dialog, the Spine file validator and
the web-bundle player were each checked for existing and starting up, never
for working. All three now have a check that goes through the front door.
v0.52.0
--------------------------------------
- **Web bundle exports were broken, and are now fixed.** If you exported an
effect as a web bundle — the self-playing HTML page — it showed a BLANK
canvas for any effect where a layer uses more than one image. No error
message, no warning: just black.
That is most of the library. 174 layers across the shipped effects use more
than one image, and any effect containing one of them played as nothing.
The cause was a single missing line in the player. The editor's own drawing
code checks "is this image part of a sprite sheet?" before cutting it up;
the player's copy did not, and fell over the first time it met an image that
was not. Both are now the same.
Verified by building a real bundle and opening it: before, zero pixels drawn
and the animation stopped on frame one; after, twenty frames clean and the
effect plays.
- **Why this was never caught:** everything that watched the player only asked
whether it LOADED — that it was present, that it started up, that it matched
the editor. Nothing ever asked it to play something. A player that started
perfectly and drew nothing passed every check. There is now one that opens a
real effect and counts what reaches the screen.
v0.51.0
--------------------------------------
- **Asset tint now reaches Spine — recolour a whole effect from one value.**
The editor half shipped last version; this is the half that matters. When
you tint an image, the export now sends the artwork as plain WHITE and puts
your colour on the slot itself, in Spine's setup pose, where it is a single
editable value and not a keyframe.
So in Spine you select the slot, change one colour, and the whole effect
recolours. No keys to hunt, nothing to re-export. **60,308 of 83,407 slots
across the delivered library — 72% — now carry an editable colour where
before every one of them was locked into keyframes.**
Proved by round-tripping through Spine itself: all 429 setup colours came
back identical, 429 alpha tracks, no colour keys left, and the exported
artwork measured pure white.
**Two limits, said plainly rather than left for you to find.** If you export
for Spine 3.x the colour is folded into keys as before and is NOT editable —
3.x has no separate alpha track, so this cannot be fixed. And in effects
with several animations, some slots still settle on different colours in
different animations and stay keyed; those are correct on screen but not yet
recolourable.
- **Files got slightly SMALLER**, which was not the point but is worth saying:
155.6 MB to 153.5 MB across the library. Much less than we first estimated —
the colour keys mostly still exist because your fades still need them. This
is a workflow feature, not a size one.
- **The changelog has a jump list.** This page is 106 releases long; there is
now an index of the recent ones at the top instead of scrolling for them.
v0.50.0
--------------------------------------
- **Colour an image itself, with no keyframes.** Right-click any image in the
Images list and choose **Asset tint**. The picture takes that colour
everywhere it is used, and nothing is keyed — the effect's own tint and
alpha still work on top of it exactly as before.
This is the editor half. The point of it is Spine: because the colour sits
on the artwork rather than in the animation, the export can send plain white
art plus a single slot colour, and a whole effect can then be recoloured in
Spine by changing that one value instead of editing keyed colours. The
export half is being built now; the tint is stored in your project and will
be picked up when it lands.
Your saved artwork is never altered — the tint is stored as a value beside
it, so it can be changed or cleared at any time and the original is exactly
what it was.
v0.49.0
--------------------------------------
- **You can see where you are in the timeline.** There is now a strip above
the sheet showing the WHOLE animation, with a pale block marking the part
you are looking at. Drag the block to move along, or click anywhere on the
strip to jump there — it is the scrollbar the timeline never had.
Beside it: zoom in, zoom out and Fit buttons, and a readout of how far in
you are. Zooming was previously the mouse wheel or the H key, neither of
which is visible unless somebody tells you.
Worth saying plainly, because it explains why this took so little: the
timeline always KNEW which part of the animation was on screen. It simply
never drew it. Nothing about how it navigates has changed.
- **The animation's length handle is now visible.** The bright band on the
ruler has always shown where the animation ends; the handle for dragging
that edge was five invisible pixels you found by sweeping the cursor until
it changed shape. It now has a grip you can see, and a wider catch.
v0.48.0
--------------------------------------
- **Spine loops now actually loop, and particles stop flying backwards.**
This was reported as particles "flying back to their original position and
glitching or spasming out", fixed by hand one particle at a time.
It was not a loop problem. In Spine a slot is a REUSED SEAT: when one
particle dies, that seat is handed to a different particle somewhere else on
screen — and the bone travelled in a straight line from where the first one
died to where the second one begins. Measured across 41 exported skeletons:
20,330 handovers, 3,226 of them smearing more than 4 pixels, the worst
throwing a leaf 265 pixels back up the screen. It happened on one-shots too,
not only on loops.
Every animation now also carries a first and last key on everything, with
the pair matching on a loop. Spine's own verdict: an effect declaring an 8
second loop now imports and re-exports at 8.00s, where a 3.0s effect
previously came back as 2.80s — six frames short, because a Spine animation
ends at its last key and nothing was keyed on the final frames.
**The honest cost: exported Spine files are 18.5% larger** (131.0 MB to
155.2 MB across the whole set, 657,347 extra keys). That is what full
first-and-last keying costs. If it matters more than the fix, say so — a
smaller version that only fixes the short animations is measured and ready.
- **A proper colour picker.** The old one was not ours: the Tint control was a
plain browser colour box, which hands the whole job to the operating system,
so on Windows you got its colour dialog — the grid of basic colours and the
numeric code fields. Nothing here could improve it, because none of it was
ours to change.
Now it is: a saturation and brightness square, a hue strip, an alpha strip,
a hex box and your recently used colours. It opens beside the swatch instead
of in a dialog, and nothing scrolls. Gradient stops use the same one.
- **Images can be removed from a project.** They never could — nothing in
Ottomancer had ever been able to delete one, so a mistaken import stayed for
good and travelled inside every saved copy. Right-click an image in the
Images list: it tells you which layers use it, removes it from those layers
too, and Ctrl+Z puts it all back.
- **Importing an image no longer overwrites one.** If a file you added
happened to share a name with an image already in the project, it silently
replaced that image — under every layer using it. Imports are now purely
additive; a clash arrives as "coin 2" and says so. To swap a picture on
purpose, right-click it and choose Replace image.
v0.47.0
--------------------------------------
- **Curve handles are visible again on straight segments.** A straight
segment's two handles sit exactly ON the curve line, in the same colour as
it, and were faded until you selected the key — so on the segments you most
want to bend, there was nothing to see. They now get a dark surround
whether or not the key is selected, and sit at half strength rather than a
quarter. Measured: the knob now stands 87 to 123 levels clear of what is
behind it, where before it was the same colour as the line it sat on.
- **Emitter properties no longer show handles that do nothing.** Keyed
particle settings — Start Size, Gravity, Tint and the rest — were drawing
grabbable-looking knobs on the graph. The cursor changed over them and
dragging one did nothing, because the simulation reads those values in a
straight line between keys and there is nowhere to store an ease. The fake
knobs are gone. Layer Position, Rotation, Scale and Opacity have real curves
and keep them.
Giving particle settings real easing needs a change inside the playback
engine, not the editor, and is not done.
- **Spine export, three fixes** (from the session working the exporter):
a state set's animations are no longer baked from two different
simulations; an animation that is a view of persistent content no longer
opens on a one-frame blank; and a slot filled by one animation and never
keyed by another is no longer left drawn at full opacity through it.
`chain-frame` was shipping four glints doing exactly that.
v0.46.0
--------------------------------------
- **Alt+C and Alt+V copy one property.** Point at any property — or click into
its box — and Alt+C takes just that value. Alt+V drops it on the same
property of another layer.
Copying a single property has been possible since v0.37.0 by right-clicking
it, which was the "easy" half of what was asked for. This is the fast half:
moving one number was four gestures and is now two keys.
It lands only on the property it came from — paste Start Lifetime onto Start
Speed and it refuses and says why, rather than quietly putting a number
somewhere it does not belong. With several layers selected, one Alt+V sets
them all: verified on three layers at once. Ctrl+Z takes it back.
Ctrl+C and Ctrl+V are unchanged — they still copy whole layers — and Alt was
chosen so that copying the TEXT in a box still works normally while you are
typing in it.
The right-click menu now shows the shortcut beside each item, which is where
anyone will find out it exists.
v0.45.0
--------------------------------------
- **On a phone, the editor told you to widen your window.** Ottomancer needs a
desktop — it is three columns of panels and a mouse — and on a narrow screen
it already said something. But that message was written for a desktop window
dragged too small: "widen it, or zoom out with Ctrl -". On a phone you can do
neither. There is no window edge to drag and no Ctrl key.
Measured on a 375-pixel phone: that message filled a fifth of the screen with
two instructions nobody there could follow, the layer tree took 56% of the
width, and the effect you came to look at got 14.7% of it.
A phone now gets the truth — that this is a desktop tool — and a link to the
effects gallery, which reads properly at that size. Both side panels fold
away, so the effect gets 54% of the screen instead of 14.7%.
This matters more than it sounds: every link to Ottomancer gets tapped on
phones, so for a lot of people that screen was the whole first impression.
- **Nothing changes on a desktop.** Verified at full width (three columns, no
message) and at a narrow window (properties panel folds, same wording as
before). The change applies below 700 pixels only.
v0.44.0
--------------------------------------
- **The changelog and licence pages were unreadable on a phone.** Both were
missing the one line that tells a phone to use the real screen width, so
they were laid out as if the screen were 980 pixels wide and then shrunk to
fit — the text arrived at about a third of its size.
Measured on a 375-pixel phone: the changelog reported a 981-pixel window
against the About page's 375. Fixed on both, and the publish checker now
refuses to ship any page missing it.
- These are the two pages a careful person reads BEFORE deciding to try
something — what changed lately, and what the licence lets them do.
v0.43.0
--------------------------------------
- **A line about import settings on the image tab.** If exported frames look
soft once they are in a game engine, that is almost always the engine's
import settings rather than the export — the frames themselves are sharp.
The panel now says so, and says the two settings that fix it: texture filter
set to Point (or Nearest), and compression off.
It is the single most common thing that goes wrong AFTER a correct export,
and a tool that writes frames and then says nothing about them is leaving
you to find it out from a forum.
v0.42.0
--------------------------------------
- **Estimate now tells you how big the export will actually be**, and what the
same effect costs by the other routes. Before, it told you the frame count
and stopped — so the format choice, which can cost a hundred times the file
size, was made blind.
It measures rather than guesses: it renders two real frames from partway
through your effect and averages them. Checked against a real export of the
same project — estimate 6.3 MB, actual 6.22 MB.
- It also shows the Spine bundle and web bundle sizes beside it, because those
play the effect live instead of storing every frame and are usually far
smaller. It says why, and says when frames are still the right answer — a
video edit, a store page, anyone who cannot run a runtime.
v0.41.0
--------------------------------------
- **A heavy GIF or WebP now warns you before it starts.** Those two formats
cannot write anything until every frame exists — the GIF palette is chosen by
looking at all of them — so the whole sequence sits in memory uncompressed.
A 90-frame export at the phone size (1080×1920) works out at about **712 MB**.
That is not a number anyone would guess from "export a GIF", and on a machine
without room for it the tab slows badly or stops responding. Now the export
panel says the figure before you press the button, and tells you that halving
the size quarters the memory.
- The warning stays quiet where it does not apply. PNG sequences compress each
frame as they go and WebM records as it plays, so neither holds frames this
way and neither is warned about.
v0.40.0
--------------------------------------
- **You can stop an export now.** A Cancel button appears while an export is
running, and disappears when it is not. Nothing is written, and the project
you were working on is untouched.
- **There is a clock beside the progress bar.** A bar on its own cannot tell
you whether something is slow or stuck — which is exactly the confusion the
WebP problem caused last week. Now it says how long it has been going.
- One honest note, which the button says too: the frame-by-frame exports stop
within a fraction of a second. The GIF and animated WebP encoders do their
work in one long uninterruptible push, so there Cancel takes effect at the
end of that step, which can be tens of seconds. The button says "Stopping…"
rather than pretending it already has.
- Cancelling is reported as cancelling, not as a failure. It is not an error
and it does not read like one.
v0.39.0
--------------------------------------
- **Drag a saved project onto the page and it asks what you meant.** Drop a
.ottomancer file anywhere on the editor and you get three choices:
Add to this project — keeps what you have and brings the dropped effect in
alongside it. This is how you build a big effect out of small ones: drop a
fire, drop a smoke, drop some embers, and tidy up the result.
Open it instead — replaces what is open. A snapshot of your current work
goes into Recovery first, so choosing wrong is not the end of anything.
Open in a new tab — leaves this one exactly as it is.
- Adding is undoable. One Ctrl+Z takes the whole merge back out.
- **Merging never breaks what it merges.** When two projects use the same
layer name the incoming one is renamed — and everything pointing at that
name is repointed with it. That matters most for sub-emitters, which find
their target by name: without this, merging two copies of an effect would
leave both of them driving the same sparks, and nothing would have looked
wrong in the layer list. Images are matched by content, so merging effects
built from the same library reuses the art instead of piling up copies.
- If the dropped effect is longer than your timeline, the timeline grows so
the whole thing can play. It never shrinks.
- Dropping something that is not a project now says what you *can* drop,
instead of "Those files were not images".
v0.38.0
--------------------------------------
- **The Animated WebP export could hang for ever, and now it cannot.** Choosing
Animated WebP on a large canvas — 1080x1920, the phone-shaped preset — made
the progress bar stop at 2% and stay there. No error, no file, no end. The
cause is in the browser rather than in Ottomancer: Chrome's WebP encoder
simply never answers above a certain image size, and it does not fail, it
goes quiet. Measured here: the same picture saves as a PNG in about a second
and as a WebP at 360x640 in a few milliseconds.
Ottomancer now stops waiting after a minute and tells you what happened, what
the browser was asked to do, and what to use instead — a smaller size, or the
PNG sequence or WebM. A failed export also empties its progress bar, so the
bar and the message no longer say different things.
- Every other export was checked the same way, by exporting a real project and
opening what came out: Spine bundle, PNG sequence, GIF, WebM, MP4, SVG and
the web bundle all write what they promise. The SVG export of an all-particle
project correctly says so in capitals rather than handing you an empty file.
v0.37.0
--------------------------------------
- **Copy one property from one layer to another.** Right-click any property in
the panel — Start Lifetime, a colour, a speed — and choose Copy value, then
right-click the same property on another layer and choose Paste value. It
carries the whole setting, so a range copied onto a layer holding a single
number becomes a range there too, and a gradient arrives with every stop.
- Paste only ever lands on the property it was copied from. If the clipboard
is holding something else the menu says so by name instead of offering a
paste that would put a lifetime into a speed.
- With several layers selected, the menu says how many the paste will reach —
and it reaches the ones where that module is switched on, the same rule
typing a value already follows.
- **Reset to default** is in the same menu, for putting one property back
without touching the rest of the layer.
- The menu is on **every** property, including Position, Rotation, Scale and
Opacity at the top of the panel. Copying a position onto another layer works
the same way copying a lifetime does.
- **A property your selected layers disagree about now shows EMPTY**, instead
of showing one layer's number with a dot beside it. An empty box cannot be
misread; a number can. Type into it and every selected layer takes the value,
exactly as before. Checkboxes show the half-ticked state and dropdowns show
nothing selected. A colour, a gradient, a burst list and a sprite list have
no empty state, so those still use the dot.
- **Ctrl+click in the layer list could add a layer to the selection but never
remove one.** Clicking a selected layer again left it selected, which looks
like the click was missed. Fixed. Shift+click to select a range was already
working and now has tests so it stays that way.
v0.36.0
-------
- **The gradient editor is no longer blurry.** It was being drawn at a fixed
460 by 110 and then stretched to fill the dialog — nearly three times its
real size — which is why every handle and the chequerboard behind the colours
looked soft and blocky. It now draws at your screen's actual resolution and
redraws when the window changes.
- **New handles.** Round, larger, on a stem that points at the exact position
they own, and they light up as you move over them so you can see what you
are about to grab. The selected one gets a ring, which reads on any colour —
the old outline vanished on an orange stop.
- The colour bar has rounded corners and twice the colour resolution, so a
smooth ramp no longer shows banding.
v0.35.0
--------
- **Adding an emitter no longer makes the Check badge complain.** Every new
layer arrived with loop-safe randomness switched off, and a looping layer
without it does not close its loop — which the badge correctly reported. So
the count went up by one every time you pressed + Emitter, about something
you had not done and could not have avoided. A new emitter now gets the same
setting the starter project has always had.
- **Colour can now be keyed over the timeline.** Tint has a key button, so an
effect can start warm and end cold, or flash a colour at a moment. It
multiplies whatever your gradient does rather than replacing it, so the
per-particle colour ramp is untouched and the whole system shifts together.
- **Positions and directions can be keyed too.** Every X/Y setting — shape
Position, Gravity Direction, Box Size, the speed ranges — now has a key
button. Both channels key with one click, and right-clicking that button
clears them again.
- **Auto Key now covers emitter settings, not just layer movement.** With it
on, changing Start Speed, Lifetime, Size, Tint or any other keyable setting
lands a key at the playhead. It used to apply only to moving, rotating and
scaling a layer, which its own message admitted but nothing else did.
- Ctrl+Z takes back every one of these.
**One thing that is still not possible:** keying a whole gradient. A gradient
is a list of colour stops rather than a single value, and the player that runs
your exported effects cannot blend one into another. Keying Tint is the way to
move colour through time, and it works alongside the gradient.
v0.34.0
--------
- **The properties panel marks settings that differ across your selection**,
and says how many layers an edit will reach. Select several layers and any
value they do not share carries a dot; hovering it says whose number is the
one on screen, and the header reads "editing 3 layers" so the panel never
quietly changes more than it names.
- **Right-clicking a keyframe no longer deletes it.** It opens a menu — Delete,
Cut, Copy, Reverse when several are selected, and six easings. The old
behaviour removed the key on the spot, with nothing anywhere telling you
that is what right-click did, and on a group it took the whole selection.
- **Easing is now two clicks from the keyframe itself.** Linear, Stepped,
Ease, Ease In, Ease Out and Ease In Out are in that menu. They used to live
only inside the curve editor, which is a different window and a longer trip.
The full set of twelve, with their drawn previews, is still there.
v0.33.0
--------
- **Deleting a keyframe could delete another layer's keyframe.** If two layers
had the same name — which Ottomancer allows — the timeline could not tell
their keyframes apart. Selecting one selected both, and deleting one deleted
both, silently. Keyframes are now identified by the layer itself rather than
by its name, so two layers can share a name safely.
- **Reverse (Shift+R).** Select two or more keyframes and mirror them in time,
about their own span — a rise becomes a fall, a burst played backwards is a
suck-in. The keys stay where they were as a group, so reversing a run in the
middle of an animation does not fling it to one end. Each key keeps its own
easing.
- Behind the scenes: a setting that every project has been saving since the
beginning, and that nothing ever read, is gone — the file format's published
description never mentioned it either.
v0.32.0
--------
- **Onion skin now lets you set how many ghosts and how strong.** Turning
Onion on reveals four boxes: how many frames apart the ghosts are, how many
to show before the playhead, how many after, and how solid they are. Before
the playhead is drawn cool, after is warm, and nearer frames are always
stronger. Only the spacing used to be adjustable.
- **Cut (Ctrl+X) and Select All (Ctrl+A) now work.** Copy and paste already
did; the other two thirds of the clipboard were missing. Both follow the
same rule Copy does: if you have keyframes selected they act on the
keyframes, otherwise on the layers.
Ctrl+A in the sheet means "all the keys on the rows I am already working
in", not every key in the whole project — so it cannot sweep in layers you
had forgotten were animated. Cut always copies before it deletes, and one
Ctrl+Z brings it all back.
v0.31.0
--------
- **Changing a setting now changes every layer you have selected.** Select
eight layers, set the opacity once, and all eight take it — the same for
start size, speed, lifetime, colours and every module setting. It used to
change only the one whose values were on screen, so eight layers meant
eight visits. This is how Spine, After Effects and Animate all behave.
Two things it deliberately will not do: it never writes into a module that
is switched OFF on a layer (so changing Noise across a mixed selection
leaves the layers without Noise alone), and one Ctrl+Z takes back the whole
change rather than one layer of it.
v0.30.0
--------
- **Saved curves were being stored under a broken name.** They worked, but by
accident — the setting had no name of its own, so it went into a slot called
"undefined". Anything you saved is moved to its proper place automatically
when you open this version; nothing is lost.
- **You can now save gradients, like you can save curves.** A colour ramp you
spent ten minutes shaping is one pick next time, from the same Presets list
as Fire and Smoke. It was the only one of the five libraries that could not
grow.
- **Moving something in Animate mode without Auto-key now says so.** It
changed the base pose instead of making a keyframe — the layer moved, so it
looked like it had worked, and nothing said otherwise until you played it
back. It now tells you, and tells you to press K.
v0.29.0
--------
- **"Preview export" said your art was missing when it wasn't.** Any effect
built on an animated sprite sheet — the campfire, the torches, most of the
fire and smoke — showed a wall of red "NOT FOUND, it will draw nothing"
warnings, one per frame of the sheet, and the preview drew the effect
without its flames. The export itself was always correct and complete; only
the preview was looking for the art under the wrong name. It now previews
what you will actually get.
- **The export settings now match the format you picked.** Choosing WebM no
longer offers you GIF colours; a PNG sequence no longer offers a video
bitrate. And MP4 no longer offers a Transparent tick it cannot honour — it
now says so, and points you at WebM or a PNG sequence if you need
transparency.
- **Picking a move, rotate or scale tool while the effect is playing now
tells you to pause.** The handles are hidden during playback on purpose, but
the status bar used to just say "Move tool" while nothing appeared and
dragging did nothing.
v0.28.0
--------
- **The gradient editor was unusable, and now works.** Clicking anywhere on a
gradient added a new colour stop instead of selecting the one you aimed at —
so every attempt to correct it added another, and another. You can now click
a stop to select it and drag it to move it. Adding is a double-click on the
bar, or the new **+ Add stop** button; removing is the new **Remove stop**
button, or a right-click as before.
- **The cause was worse than it looked, and it was fixed too.** The editor
canvas is drawn at one size and displayed at another, and the pointer was
being measured in the wrong one — so the editor could not tell where you had
clicked. The curve editor had the identical fault, which is why grabbing
points on a curve has been fiddly. Both now measure correctly.
- **Ctrl+Z was dead whenever a box had focus.** After typing into any field —
which is most of the time — undo silently did nothing, with no message. It
now works everywhere. Typing keys still cannot trigger shortcuts by accident.
- **Eight more things can now be undone.** Canvas width, canvas height, the
canvas preset, frame rate, background mode, background colour, and setting
or clearing the background image all skipped the undo history entirely.
- Behind the scenes: four new checks, each one watched to fail before it was
allowed to pass, so none of the above can come back unnoticed.
v0.27.0
--------
- **The Ottomancer name in the top bar now has the flame beside it, and it is
a proper link.** Middle-click it (the scroll wheel) and it opens Ottomancer
in a new tab, exactly like a link on any other website. Ctrl-click does the
same, and right-click gives you the usual "open in new tab" menu. A normal
left-click reloads the editor, and it takes a recovery snapshot first, so
nothing in progress is lost if you click it by accident.
v0.26.7
--------
- **Ottomancer would not open at all without a connection.** The saved offline
copy was being stored in a form the browser refuses to reopen, so every page
— the editor included — came up as a blank white window with no error and
nothing to click. It looked exactly like the site being down. Every page is
now saved in a form that reopens, and the offline copy genuinely works
again. If you ever saw a blank Ottomancer, this was why.
- The blank-window note in v0.26.6 below only covered half of this. The other
half is fixed here.
v0.26.6
--------
- **The site could get stuck showing an error page.** When a page was loaded
during the minute or so after an update goes out, the browser sometimes
caught the update mid-flight and got an error back — and Ottomancer then
stored that error and kept showing it, instead of throwing it away and
asking again. It now only ever remembers a page that actually loaded.
- **A blank tab on the /app.html address.** That address forwards to /app, and
the forwarding step was being stored as if it were the page. This release
stopped new ones being stored; the copies already saved were dealt with in
v0.26.7 above.
- Behind the scenes: updating the offline copy now also notices when the part
of Ottomancer that manages it has itself changed, so a fix like the two
above reaches people who already have the site saved. Both bugs have a test
that was watched to fail before it was allowed to pass.
v0.26.5
--------
- **Docking a panel no longer covers the panel underneath it.** If you docked
the Curves window to the right-hand edge — the natural thing to do with it —
it sat on top of the Properties panel and every control there stopped
responding, with nothing to tell you why. A docked panel now takes its own
room and the workspace makes space for it, on any of the four edges.
- Behind the scenes: the animated WebP frame flag fixed in v0.26.0 now has a
test of its own, so the smearing cannot come back unnoticed.
v0.26.4
--------------------------------------
- **The light theme is properly readable now.** Ten colours had no light
version at all, so they stayed dark while everything around them went light:
the "Start here" panel a new user is pointed at was dark text on a dark
block, and the Export button — the main action in the top bar — lost its
orange and became cream text on near-white, which is very close to
invisible. Measured before and after: the Export button went from 1.06 to
4.68, the panel titles from 1.22 to 11.3, the Start-here label from 1.24 to
12.2. Every colour pair in both themes is now comfortably readable, and the
build refuses to publish if a colour is ever added to one theme and not the
other.
v0.26.3
--------------------------------------
- **The editor can be used with a keyboard.** The scene tree, the colour tags,
the behaviour headers and every cell in the Effects and Sprites libraries
could only ever be clicked with a mouse — there was no way to reach any of
them by tabbing, so somebody using a keyboard could type into the effect
search box and then had nothing they could pick, and could not even select a
layer. All of them can now be tabbed to and used with Enter or Space, and
they announce themselves as buttons to a screen reader.
v0.26.2
--------------------------------------
- **Number boxes cannot be given nonsense any more.** Canvas width and height
now sit between 8 and 8192 — typing a huge number used to be accepted and
gave you a canvas the graphics card refuses to draw, and typing letters
silently collapsed it to 8 pixels. Seventeen settings that are meant to be a
fraction between 0 and 1 — Flip U, Flip V, Flip Rotation, Dampen and others —
already said so internally and nothing was reading it; they are properly
limited now.
- **A box always shows the value it actually kept.** If a number gets adjusted
to fit, the box updates to match instead of displaying what you typed while
holding something else.
v0.26.1
--------------------------------------
- **A layer put on a path stays on it after you save and reopen.** This was
the oldest known bug in the list. The layer used to freeze wherever it
happened to be, the Follow-path box read "missing path", and playback and
every export quietly stopped moving it — with nothing to tell you. The link
is now stored by the path's name, which survives being saved; and renaming a
path takes everything following it along, so the rename you make is the one
you meant.
v0.26.0
--------------------------------------
This one came out of a full audit — five separate passes over the app, the
site, the exports and the security. These are the things that were wrong.
- **Animated WebP exports were smearing.** Every particle that faded out
stayed on screen for the rest of the clip, so a long effect ended as a
build-up of everything that had ever happened. One wrong byte in the file
format told players to blend each frame over the last instead of replacing
it. Every animated WebP you export from now on is clean.
- **"New" could lose your work with no way back.** Starting a new project
reset undo, and the first edit you made afterwards overwrote the autosave —
so up to three minutes of work could exist in no copy at all, while the
button's own tooltip promised the opposite. It now takes a recovery snapshot
first, the same as Open always did. More ▾ → Recover will have it.
- **The editor now really does work offline.** The file holding all 57 sprites
was never being saved for offline use, so offline you got the editor and not
one sprite or ready-made effect. It is included now.
- **Renaming a layer can be undone**, and two layers can no longer end up with
the same name — which mattered, because effects that trigger each other find
each other by name.
- **A hostile project file can no longer put code into an exported SVG.**
Sprite sizes from a `.ottomancer` someone sends you are now treated strictly
as numbers. Nothing you have made is affected; this closes a door.
- **About and Help showed "Ottomancer v?"**, and five pages still said v0.18.3.
Every page now shows the version you are actually running.
- **The tab you pick when two panels share an edge is remembered properly.**
It used to come back correctly once and then forget.
- Corrected what the built-in help and the machine-readable reference say about
the collision floor: particles that start below it are held there, they do
not disappear.
v0.25.3
--------------------------------------
- **A panel can no longer be lost off the edge of the screen.** If you had a
floating panel near the right-hand side and then made the window smaller,
the panel stayed where it was — off the edge, with its title bar gone. You
could not click it and you could not drag it back, because the bar you drag
it by was the part that had disappeared. Panels are now pulled back into
reach whenever the window shrinks.
v0.25.2
--------------------------------------
- **A keyframe's two curve handles now stay in line with each other.** Drag
the handle on one side of a point and the one on the other side swings round
to match, keeping its own length. That is what stops a curve kinking as it
passes through a keyframe, and it is how Spine and every other animation
tool behave. Until now the two moved completely independently.
**Hold Alt** while you drag if you WANT a sharp corner at that point — the
other handle stays put. **Hold Shift** to make a handle longer or shorter
without changing the direction it points. Both are written under the graph
so you do not have to remember them.
v0.25.1
--------------------------------------
- **Sheet and Graph are buttons on the timeline again.** Switching the
timeline between the keyframe sheet and the curve graph was hidden inside
the "View" menu at the bottom right — at every window size, not just narrow
ones. The two buttons had been built to sit on the bar next to "All layers"
and "Markers", and something was quietly moving them into the menu. They are
back where they belong, so you can see which one you are looking at and
switch with one click.
v0.25.0
--------------------------------------
- **Two panels can now share an edge, as tabs.** Dock the Curves panel and
the Preview to the same side of the screen and they no longer sit on top of
each other — the title bar becomes a row of tabs and you click between them.
Before this, docking the second one simply hid the first, with nothing to
tell you where it went. Whichever tab you leave selected is the one that
comes back next time you open the editor, and dragging the edge resizes the
whole strip rather than one panel inside it.
v0.24.1
--------------------------------------
- **Delete now works while the Curves window is open.** It already worked in
the timeline below, but with the Curves window up the key was being caught
and thrown away before anything could act on it, so pressing Delete simply
did nothing. Found by using the editor rather than by reading it. Ctrl+Z
still brings the keyframes back.
v0.24.0
--------------------------------------
- **Sprites can now point at the middle of the emitter, or straight away
from it.** In the Renderer module, Alignment has two new settings: "inward"
and "outward". Say you build rain out of a circle using a streak sprite —
before, every streak sat at whatever angle it was drawn at. Now "inward"
turns them all to face the centre, and they keep facing it however they
move. "outward" does the opposite, for a burst or a sunburst.
Worth knowing: if your particles are already TRAVELLING toward the middle,
the existing "velocity" setting already aimed them there. The new settings
are for when the sprite has to face somewhere it is NOT travelling — rain
falling straight down whose streaks face a logo, or a ring of shards
orbiting with all of them facing in.
Start Rotation still works on top of all of them, so if your artwork is
drawn pointing up instead of right, correct it there once and every
Alignment setting aims properly from then on.
v0.23.1
--------------------------------------
- **Delete removes the selected keyframes.** Select one or drag a box over
several, press Delete or Backspace, and they go — and Ctrl+Z brings them
back. You could already do it by right-clicking, which is not where anybody
looks. Typing in a box is left alone.
v0.23.0
--------------------------------------
- **New keyframes now ease.** A keyframe you make starts gently, runs, and
arrives gently, instead of moving at one flat speed and stopping dead.
Constant speed is what makes animation look mechanical, and every other
tool eases by default. **Nothing you have already made changes** — this is
only what a NEW keyframe starts as, and you can still make any keyframe
straight by hand.
- **Old projects get their names tidied when you open them.** A project saved
a while ago could have a layer called "Emitter 1" while the thing inside it
was called "Sparks" — two names for one thing. Since effects that trigger
each other do so BY NAME, that could make one quietly miss. Opening such a
file now makes the two agree, keeping the name the effects actually use.
- **Ctrl+Z takes back curve edits.** Reshaping a curve changed your effect
immediately but was invisible to undo — the only way back was Cancel. It is
a normal undo step now.
- **Undo no longer collapses the layer you were working on.** Pressing Ctrl+Z
folded the layer shut in the timeline and its keyframes looked like they had
been lost. They were always there; the row had closed.
v0.22.7
--------------------------------------
- **The timeline now names both its views: Sheet and Graph.** They were one
button labelled "Graph", which never told you what turning it off gave you
— so the dope sheet was a view you had to already know about. Same rows,
same selection, same zoom; only how they are drawn changes. Graph has
draggable curve handles built in.
v0.22.6
--------------------------------------
- **Dragging a curve point straight up or down no longer moves it in time.**
Before, any sideways drift of the mouse — and there is always some — also
retimed the point, so a curve's timing crept every time you adjusted its
shape. Drag mostly up or down and the timing is held; mostly sideways and
the value is held; diagonally and you get both, as you asked for.
v0.22.5
--------------------------------------
- **Zoom the timeline to your selected keyframes.** Select some keys and press
**Shift+F**, or use **Frame keys** in the timeline's View menu. Three keys
four frames apart on a six-second effect used to be an unreadable smudge,
and the only way in was to spin the wheel and then pan by hand. **Fit time**
is in the same menu to go back to the whole effect.
v0.22.4
--------------------------------------
- **Arrow keys move selected keyframes.** Select keys in the timeline — drag
a box over them, or click one — and left/right shifts them a frame at a
time, Shift for ten. It is the quickest way to fix timing that is out by a
frame or two. With nothing selected the arrows still nudge the layer, as
before.
v0.22.3
--------------------------------------
- **Fixed an error that fired every time you shaped a curve.** Dragging one of
the little square handles in the Curves window threw an error on every
mouse movement, because two different parts of the timeline were using the
same place to remember "which handle is being dragged" — and each expected
a different thing to be in it. Nothing visibly broke, which is why it went
unnoticed; it just filled the browser's error log while you worked.
v0.22.2
--------------------------------------
- **The keyboard works on curves now.** Pick a point and the up and down
arrows nudge it; hold Shift for bigger steps. Delete removes the point
(except the first and last, which set where the move starts and ends), and
Escape lets go of it. Typing in any box is left alone.
v0.22.1
--------------------------------------
- **Fixed a hang.** The curve graph could lock the whole browser tab solid —
no error, nothing to click, only closing the tab. The time ruler along the
bottom of the graph was drawing its marks one at a time with no upper
limit, and if the view got into a wide enough state it tried to draw
millions of them, sixty times a second. It now works out the spacing from
what is on screen, and refuses any view that does not make sense.
- **Panels resize from any edge.** Before, only the little corner grip
worked, and it disappeared entirely once a panel was docked — so a panel
docked down the side could not be made wider, which is the one resize you
actually want. Grab any edge now; a docked panel resizes by the edge facing
your work.
v0.22.0
--------------------------------------
- **The Curves panel is editable at last.** There were two of them: a
"Curves…" window you could edit but not dock, and a **Curves** panel from
the top bar that docks to the edges of the workspace but was a picture you
could only look at. That panel now has everything the window has — click a
point to select it, drag it, drag its square handles to shape the ease.
- **The curve graph has a proper time axis.** Wheel to zoom around the
pointer, shift+wheel or middle-drag to pan, double-click or **Fit** to see
the whole effect again, and **−** / **+** buttons if you would rather not
use the wheel. The tick marks get finer as you zoom in.
- **A readout above the graph shows the selected key, with its time and value
in boxes you can type into.** Dragging is the quick way; typing is the way
that cannot miss by a pixel.
- **Panels and windows roll up** to just their title bar, so you can park one
without closing it and losing your place.
v0.21.2
--------------------------------------
- **The Curve editor works properly now** — the one behind the "Curve" button
on Size, Start Size and the rest. Four things were wrong with it:
**Clicking a point added a new point instead of selecting it.** If your
click missed the point by a few pixels — and the points were small — you
got a new one where you were aiming. So every attempt to grab a point made
the curve messier. Clicking on or near a point now always selects it. You
can still add one by clicking in clear space.
**Nothing you did applied until you pressed OK.** Drag a curve, look at
your effect, see no change. It updates live now, as you drag, and Cancel
puts it back exactly as it was.
**The graph was tiny and would not grow.** It now fills its window, and the
window resizes.
**Nothing showed a point could be grabbed.** The cursor now changes over a
point and over a handle.
v0.21.1
--------------------------------------
- **The curve window is a real window now.** It used to be a popup that
dimmed everything and took every click, so you could look at a curve OR
work, never both. It now floats: the timeline, the viewport and the panels
all stay live while it is open, so you can scrub and watch the curve at the
same time. Press Curves again, or Escape, to close it.
- **The points and handles are much easier to hit**, and the cursor now
changes when you are over one — a hand over a point, a pointer over a
handle. They were small enough to miss on a large screen, and nothing told
you they could be grabbed.
- **Window edges are easier to grab too**, and they light up under the
pointer.
v0.21.0
--------------------------------------
- **Applying an animation now shows its keyframes.** They were always being
created, but the layer stayed folded shut in the timeline, so you got one
summary row and no properties — which looks exactly like nothing happened.
Anything that makes a keyframe now opens the layer that got it.
- **The curve window has a playhead.** A vertical line that moves with the
transport, just like the one in the timeline, so the shape of a curve is
tied to the moment you are looking at.
- **Curve handles show you which key you are working on.** They sit faint
until you click a point; that point's handles then go full colour on a
dotted arm, and the one you are dragging fills in. Click a handle to grab
it directly.
- **Every window resizes from any edge, moves, and snaps.** Not just the
bottom-right corner. Drag any edge or corner, drag the title bar to move
it, and it snaps to the screen edges and to the panels behind it, with a
line showing where it will land. Each window remembers its own size and
place. The curve graph now fills its window too — before, a taller window
just gave you more grey.
v0.20.3
--------------------------------------
- **Spine cost estimates were counting layers you had switched off.** Both of
them. So an export looked more expensive than it actually was, and the
numbers you use to decide what to ship were high. Fixed — a disabled layer
now costs nothing, which is what it does.
- Behind the scenes, two new checks run before anything is published: one
that catches a setting written to a name that does not exist (which used to
do nothing at all, quietly), and one that re-measures how the engine
actually behaves against what the guides claim. The first found the bug
above the moment it was switched on.
v0.20.2
--------------------------------------
- **The curve editor has handles now.** Every keyframe already carried an
ease — it was in the file, in the playback and in the Spine export — and
there was no way to reach it. Open **Curves** and each segment now shows
two square handles on top of the round points: drag a round one to change
the value, a square one to shape how the value gets there. A hold key has
no ease, so it shows none.
- **Canvas size says which box is which.** It was two bare numbers stacked
on top of each other. They are now marked W and H.
- **A fix for anyone writing a project file by hand or by script.** The
format guide described a layer's keyframes with the wrong shape, and a file
written to it loaded with every keyframe blank — no error, the layer
present, the animation simply gone. The guide is corrected, and the reader
now accepts both shapes and refuses a keyframe it cannot read instead of
loading a broken one.
v0.20.1
--------------------------------------
- **Onion skin now has its dials.** It could always show ghost frames before
and after the playhead, tinted cool for the past and warm for the future —
but only the spacing could be changed. How many ghosts to show behind, how
many ahead, and how strong they are now sit beside it in the View menu.
- **A first visit says where to start.** One line above the ready-made
effects, once, and it goes away as soon as you pick one. If you arrive on a
link that already opens an effect, you still get it.
- **The editor can be used with a screen reader.** Most of the boxes in the
properties panel had no name a screen reader could read — the label was on
screen but not joined to the field, so it announced them as blank. All of
them are named now, and the status line at the bottom is read out, so
"Added Festival Fireworks" or "Could not save, storage is full" is heard
rather than only shown. A canvas editor will never be fully navigable this
way, but nothing should be silent.
v0.20.0
--------------------------------------
- **The looping effects now actually loop.** Almost none of them did. An
effect set to loop was drawing different random numbers every time round,
so the last frame never matched the frame before the first — in a game that
reads as a small pop, once per cycle. Measured across the whole library:
4 of the 94 looping effects closed cleanly before, 92 do now. Eleven of them
also needed their rate, their cycle length or their particle limit adjusted
so the numbers divide.
If you liked the old endless variation for a live background, turn
**Loop-safe random** off in Main — it is a switch, not a rule.
- **A new "Check" button in the top bar**, next to the Spine one. It looks for
the faults that do not look like faults: a loop that will not close, an
emitter quietly hitting its particle limit so half the burst is never born,
a sub-emitter pointing at a name that no longer exists, particles born at
zero size. Where the repair is arithmetic it offers to do it — **Fix this** —
and where it is a matter of taste it tells you what to change and leaves it
alone.
- **The properties panel only shows what the emitter is using.** There are 19
modules and a typical emitter uses six, so the panel used to spend thirteen
headers saying nothing is happening here. The rest now sit under **Add
behaviour**, grouped by what they do — "how they move", "how they change as
they age" — rather than by their engine names. Searching still looks through
all nineteen.
- **A link that opens an effect.** `ottomancer.com/?fx=Fire+Tornado` starts the
editor with that effect already loaded. Any name from the effects list works.
- Undo now updates the Spine and Check readouts. They could previously sit on a
verdict about a project you had just undone.
- **The site was telling people there are 118 effects.** There are 119, and one
button said 117. Fixed everywhere, and the deploy now counts the library and
refuses to publish if any of that copy disagrees with it.
- **Every setting now explains itself.** Hover any field name and it tells you
what it does in plain words — all 112 of them, where before only a quarter
had any explanation. The ones with a trap in them say so: pulling inward
needs a negative number, a collision floor is solid underneath, and a
sub-emitter stops working if you rename what it points at.
- **The first layer is called what it says it is.** A new project's layer read
"Emitter 1" in the list while the effect inside it was called "Sparks" — and
"Sparks" was the name that actually did the work.
- **"Start here."** The ready-made shelf in the bottom-left is where you
actually begin, and it used to look like the quietest thing on screen. It is
now a proper block that says what it is for. It has not moved.
- **Effects with an opening burst no longer lose it.** If a burst was set to
go off in the first fraction of a second, it could quietly stop firing after
a few loops and never come back — Volcano Eruption lost its opening blast
that way. Every looping effect in the library now repeats exactly, forever,
with no drift at all.
- **The Check button takes you to the problem.** Every emitter it names is
now a link — click it and that layer is selected, ready to fix. Naming a
layer was only half an answer in a scene with nine of them.
- **You can now tell the panels apart.** The greys the editor was built from
were so close together that the whole app read as one flat sheet — the
darkest and lightest surfaces were within a whisker of each other, and
neighbouring ones were closer still. They have been spread out. Same dark
tool, same colours, but the panels, the bars and the stage are now visibly
different surfaces instead of one.
- **Small grey labels are readable.** They were below the contrast a person
needs to read comfortably; they are not any more.
- **Ottomancer now looks the same for everyone.** It used to ask for Segoe UI
and Consolas, which only exist on Windows — so anyone on a Mac or Linux was
quietly getting different fonts, and a different-looking app. It now brings
its own (IBM Plex Sans and IBM Plex Mono, 59 KB once, then cached and
available offline). If they ever fail to load the editor still reads
correctly in whatever the machine has.
- **More room to work.** Property rows, module headers, the layer list and
every input got a little taller and a little wider inside. It reads calmer
and is easier to hit; the cost is about three fewer property rows on screen
at once.
- **The Spine and Check readouts look like readouts now**, not like two more
buttons. They are pills in plain colours — green when everything is fine,
sand when something is worth a look, red when something is wrong.
- **Corners agree with each other.** There were eleven different rounded
corners on screen; now there are three, and each one means something:
controls, panels, and the two status pills.
- **The smallest text in the editor got bigger.** Some labels were 8 and 9
pixels tall; nothing is under 10 now. Along with it, the editor's colours
and sizes are on a proper system rather than being chosen a rule at a time —
invisible today, but it is what lets the interface actually improve.
- **The effect you start with now loops properly too.** The starter project
was built by hand rather than from the effects library, so the loop fix
missed it — which meant the new Check button greeted you with a problem
about the project Ottomancer had just made for you. Fixed, and checked on
every publish from now on.
- **Keyboard focus is visible.** Tabbing through the editor used to leave you
guessing which button you were on, because buttons drew no focus at all.
They now show an amber ring. Clicking with the mouse still shows nothing,
which is how it should be.
- The Check button no longer warns about things that are fine. Projects store
numbers to five decimal places, and three of its rules were stricter than
that — so a correct effect could come back from a save looking broken. All
three now allow for it, and every real fault is still caught.
v0.19.18 — earlier
------------------
- **The Project panel now shows how big your project is**, and how much of
that is images. A project keeps its own artwork inside it, so one imported
sheet can turn a 20 KB file into a 5 MB one — worth being able to see
rather than discover later.
- Your projects stay **one plain file that carries its own art**. It opens
anywhere, nothing goes missing, and a script or a text editor can read it.
v0.19.17 — earlier
------------------
The SETUP preview is live now — move something and it follows.
- **Move an emitter, drag a folder, change anything, and the playing preview
updates as you do it**, the way Spine does. It was being fed nothing about
where things are, so moving an object changed the stage and left the preview
showing the old arrangement.
- Everything else was always live — rate, size, colour, lifetime — because the
simulation reads those as it runs. It was only ever the positions that were
missing.
- **Adding or deleting an emitter shows up too**, instead of the preview
quietly carrying on with the old list.
- The stage stays exactly where you left it while the preview plays. The two
run on separate clocks on purpose, so nothing you watch can move your
playhead or key anything.
v0.19.16 — earlier
------------------
A proper layout pass — the tools, the modes, and where everything lives.
- **The move / rotate / scale buttons were drawn on top of the transform
panel.** They were both pinned to the same corner, so the panel's title read
as "sform" and its X and Y labels sat behind the icons. The tools now have
their own column and the panel sits beside them, readable.
- **SETUP and ANIMATE moved onto the stage**, centred at the top, where the
thing they change actually is. They were sitting in the menu bar next to New
and Open, which made them look like ordinary buttons.
- **SETUP now splits the screen.** The timeline goes away — it is no use while
you are posing — and the stage divides: your work on the left, the effect
playing on the right, almost as large. The earlier version put the preview
along the bottom where the timeline had been, which was not the same thing.
- **The preview never stops, and never touches your keys.** It runs its own
clock and loops forever, so you can change something and watch what it did
without the playhead moving and without keying anything by accident.
- **"Spine: safe" is always on the top bar now**, instead of hidden inside the
More menu. It tells you whether your project can be exported at all, which
is not something to go looking for.
- **The left column is organised the way other software does it.** Buttons
that add to the scene sit under the scene. Adding an image sits with the
images, as **+ Add** on the Images list. The ready-made shelf — Effects,
Sprites, Animations — moved to the bottom, because picking one is something
you do once at the start.
- **Two duplicate buttons removed.** "Add Images" and "Library" in the top bar
opened the same dialogs as the buttons in the panels below them.
v0.19.15 — earlier
------------------
The Export window now tells you what each emitter costs, before you export.
- **A "Spine cost" line, and a breakdown per emitter.** It says roughly how
many slots your effect will use in Spine, which emitter is responsible for
them, and what share each one is — sorted by the expensive one first.
- **It names the reason.** If trails are what is multiplying an emitter, it
says so: *"trails are 7 samples, so each particle costs 8x"*. If Max
Particles is the only thing holding one down, it says that too.
- **It updates as you change things**, so you can see the number move rather
than exporting to find out.
- **It warns when Spine will struggle.** Spine's editor gets slow long before
the file gets big, so the number that matters for Spine is slots, not
megabytes.
The figure is deliberately on the high side — it is checked against real
exports and always comes out at or above what the file actually contains, so
it is safe to plan against.
v0.19.14 — earlier
------------------
Every export that can have a transparent background now does.
- **SVG was ignoring the Transparent tick.** You could tick the box, export,
and still get a solid rectangle behind everything. It now does what the box
says.
- **The web bundle was always dark.** Drop it into a page or an iframe and it
brought a black rectangle with it. With Transparent ticked, the page is now
see-through, so the effect sits on whatever is behind it.
- **Transparent GIFs were losing almost the whole effect.** A GIF can only do
"fully there" or "fully gone" — no in-between — and a glow is almost entirely
in-between, so nearly all of it was being thrown away. Measured on one frame:
2,902 visible pixels became 49.
Now the visible part is blended onto a colour first and only the truly empty
area is left transparent, which is how GIF exporters have always done it.
**93% of what you can see survives**, instead of 2%. The export tells you the
number each time.
- **WebM keeps transparency, and the note now says so.** It used to advise
turning Transparent off for video, which sent you away from the one video
format here that keeps it.
Where each format stands, all measured on real exported files:
PNG sequence full soft transparency
Animated WebP full soft transparency — same as the PNG, pixel for pixel
Spine full soft transparency
WebM keeps transparency
SVG no background
Web bundle see-through page
Animated GIF hard-edged only, keeps 93% of what you see
MP4 cannot — the format has no transparency at all, and says so
v0.19.13 — earlier
------------------
Safety net: nothing broken gets out quietly.
- **An export is now checked by reading it back**, the same way saving already
was. Ottomancer opens the file it just made, plays it, and confirms every
image it asks for is actually in the zip. If something is missing it
**refuses to save the file and tells you which image**, instead of handing
you a zip that imports into Spine with pieces missing.
- **It knows where the export is going.** Sending it to a game runtime and
sending it to the Spine editor need different files, so a problem that would
break one and not the other is reported accordingly — no false alarms.
- **If anything goes wrong while you are working, a bar now appears with a
"Save my work now" button.** It writes your project straight to your
Downloads folder. Before this, any error covered the whole screen with
"Ottomancer could not start" — which was untrue an hour into a session, and
gave you no way to rescue what you had done.
- **An image that fails to save is now reported.** It used to be skipped in
silence, which is how an export ends up quietly missing a piece.
- Under the hood: the feedback board now has an automatic check that nothing
anyone posts can ever run as code, and the markers that prove this is the
original Ottomancer are all verified on every build.
v0.19.12 — earlier
------------------
Every looping effect now closes exactly — including the ones we used to warn you about.
- **Swirling, drifting noise no longer breaks a loop.** Fire Tornado had 628
flames landing in the wrong place at the wrap. It now has none. The noise
pattern repeats with the loop instead of drifting on forever, so a flame
coming round again follows exactly the path the last one did.
- **Two warnings in the Export window are gone, because they are no longer
true.** One told you to turn Noise Scroll Speed down to zero. The other told
you to shorten a particle lifetime that outlived the loop. Both would have
cost you the look of your effect to fix something that no longer happens.
- **Measured across the whole library**: every looping effect closes at zero
pixels — Fire Tornado over 386 particles on screen at the seam, Falling Snow
over 214, Portal Vortex 130, Magic Aura 91. It still closes with the noise
scroll pushed to three times what any effect uses, and with a lifetime twice
the length of the loop.
Nothing about how your effects look has changed. The noise only repeats once
the loop comes round, which is what asking for a loop means.
v0.19.11 — earlier
------------------
See what your export will actually do, before you export it.
- **A "Preview export" button in the Export window** (on the Spine tab). It
bakes the file and then PLAYS it — not the effect running in the editor, but
the finished JSON, read back the same way a game engine reads it. If it
plays here, the file is sound.
- **It tells you what the file needs.** Every image it references, at the size
it expects — and says plainly if one of them is missing, which is the thing
that leaves you with an invisible effect in your game.
- **It tells you what the file costs.** Frames, duration, bones, slots, keys,
JSON size, and whether it loops. Then it measures the drawing as it plays:
average and worst frame time against the budget your frame rate allows, and
how many frames went over.
- **Play, pause and scrub** through it, and anything the preview cannot draw
is listed rather than quietly skipped.
This was asked for on the feedback board: "i need a way to see if a json i
will export, how it will play in a basic html game, what info it has...like
assets, frame rate, frame drop, etc. so i know the export will work before i
add it to an existing project."
v0.19.10 — earlier
------------------
Falling Snow loops properly now — and so does everything else.
- **A looping effect no longer hitches at the wrap.** Falling Snow had a
flake jumping most of the width of the screen every time the loop came
round. It is gone: all 214 snowflakes on screen at the seam now land in
exactly the same place at the end as they do at the start.
- The cause was a rounding error, not the snow. An effect that loops restarts
its random numbers each time round, so every cycle looks the same — but the
restart was landing one frame late, and after a while it started landing on
time instead. That one frame is two snowflakes, which was enough to pair
every flake with the wrong twin on the far side of the loop.
- **This affected any looping effect**, not just snow. Snow was simply the
only one whose flakes live longer than the loop, so it was the only one
where you could see it happen. The same fix is in the web player, so
exported web builds loop cleanly too.
v0.19.9 — earlier
-----------------
Curve handles on every point.
- **Every point on a curve now has its two handles showing** — one reaching
back, one reaching forward — instead of only the point you had clicked.
Grab either one and drag it to bend the curve into that point or out of it.
- **Grabbing a handle picks up its own point.** You no longer have to select
a point first and then find its handles; just take hold of the handle you
want. The point you are working on is drawn brighter than the rest, so you
can still tell them apart at a glance.
- The first point has no backward handle and the last has no forward one,
because there is no curve on that side of them to shape.
v0.19.8 — earlier
-----------------
A Windows menu, and panels you can put where you want them.
- **Windows ▾ in the top bar**, where every other program keeps it. It lists
the panels: **Curves** and **Preview**, with a tick beside the ones that
are open.
- **Drag a panel by its title bar and drop it where you like.** Near an edge
it snaps and fills it — left, right or bottom — and an outline shows you
where it will land before you let go. Drop it anywhere else and it floats.
Drag the corner to resize. Where you put them is remembered.
- **They follow the selection and keep playing.** Curves shows the selected
layer's animation live; Preview shows the effect running, framed the way an
export will frame it, not the way the stage happens to be panned.
- **SETUP mode puts the preview where the timeline was.** The timeline only
appears in ANIMATE now, the way Spine does it — a dope sheet is no use
while you are posing, and it is the tallest thing on screen. The stage grows
from 414 to 631 pixels tall in the swap.
If you had the preview open somewhere else, that is left exactly as it was
and put back when you return to ANIMATE. Only a preview that SETUP opened
gets closed again.
v0.19.7 — earlier
-----------------
Spine exports now say what every slot is doing on the first frame.
- **Every slot is switched on or off explicitly at frame 0.** Before, a slot
whose particle appears later said nothing at all until then — and what a
slot shows when it says nothing is somebody else's software's decision. On
one firework, **158 slots were still holding artwork from the end of the
loop at the start of it**, and 2507 of 2783 slots were silent on frame 0.
That is the "bits of the end playing at the beginning" problem, and the
"stars frozen on screen during other animations" one. Both come from the
same silence. It costs about one key per slot — under 2% of the file.
- **A scrolling noise field cannot close a loop, and the export now says so.**
Measured rather than guessed: one effect goes from 366 slots jumping at the
loop point to zero when Noise > Scroll Speed is set to 0, and loop-safe
randomness makes no difference to it whatsoever. The warning names the
emitters and tells you the choice — set the scroll to zero for an exact
loop, or keep it and accept a few pixels of pop.
v0.19.6 — earlier
-----------------
Tools you can press.
- **Move, Rotate and Scale are buttons now**, in a rail on the left of the
stage, one of them always lit so it is never a guess which is active. Or
press W, E, R — the same keys Spine, Unity and Maya use.
The handles were always there. Nothing on screen said they were tools, so
"we need translate and rotate tools" got reported twice by someone looking
straight at them. That is a UI failure, not a missing feature.
- **The stage shows only the tool you chose.** Move draws arrows out of the
pivot, rotate draws the ring, scale draws its handle — instead of all five
grab targets stacked around one small object, where reaching for the X
arrow got you the rotate ring.
- **A selected layer is always marked**, whichever tool is up: the pivot
square, and a faint dashed circle when the tool draws nothing near it.
- **SETUP and ANIMATE moved to the centre of the top bar.** They decide what
half the app does, and they were sitting in the run of ordinary buttons
with nothing marking them as different in kind.
- **Fixed: the Local / Parent / World buttons stopped lighting up when
clicked.** They had been broken for two releases — the space really did
change, only the highlight did not follow, so the panel showed one thing
and did another.
v0.19.5 — earlier
-----------------
Eight defects from an outside bug report, and a new firework.
- **FIXED, and the worst of them: a burst on the very first frame never
reached a Spine export.** The file came out valid, complete-looking, and
missing that whole part of the effect — no error, no warning. The editor
showed it firing perfectly, because only the export warms the simulation up
first, and the warm-up swallowed it. Anyone hitting this had to move their
burst a frame or two later and never know why.
- **The export now refuses rather than quietly losing an emitter.** If
something emits in the editor and puts nothing in the file, the export stops
and says which emitter. That is the general net: it does not need to know
why, so the next cause of this gets caught too.
- **"export blocked: [object Object]"** — every blocked export said exactly
that, and nothing else. The one sentence written to explain the refusal was
the one thing thrown away. Blocked exports now say what is wrong, all of
them, not just the first.
- **An empty first frame no longer refuses the export.** A shell that opens a
frame or two in legitimately has nothing on frame 0; that used to be a hard
block with no way forward. It is a note now, saying it opens blank and which
box to untick.
- **The setup-pose control says what it does.** It fills the slots holding a
particle on frame 0 — not all of them, deliberately, because filling the
rest would leave particles frozen on screen in other animations. It is
called "Show frame 0 in Spine's setup pose" now and reports "74 of 400" so
the number makes sense.
- **The size estimate was nine times under on effects with trails.** Every
trail sample is its own slot in a Spine export, and the estimate counted one
per particle. It counts them properly now and is deliberately generous —
real exports come in at or under it.
- **Projects saved by older builds open again.** Files ending `.ottopia` were
not selectable in the Open dialog even though they load perfectly.
- A library sprite with no image data is refused instead of silently
producing an emitter that draws nothing.
- **New effect — Festival Fireworks** (Scenes). A peony shell that opens
straight into gold star-streaks with drooping tips and lingering embers.
Contributed as a finished, measured recipe. Duplicate the folder for a
second shell and change its colour and position. It opens on the very first
frame, which is only possible because of the fix at the top of this list.
v0.19.4 — earlier
-----------------
The effects library shows you the effects.
- **Every effect now has a picture.** 118 of them, previously offered as a
name and a sentence in a tool whose whole subject is how things look. Each
thumbnail is the real recipe, simulated and drawn by the real renderer — the
same road the effect takes when you click it — so what you see is what you
get, not an illustration of it.
- **It picks the moment worth showing.** Not the first frame (a slow build has
not started), not the last (a burst is over), and not the busiest either: an
effect that grows its particles peaks its count when everything is still too
small to see. It measures how much is actually on the frame and shows you
that moment.
- **Only what you are looking at is drawn**, one at a time, and kept for the
rest of the session — so scrolling back is instant and opening the library
never makes you wait for 118 simulations.
- 111 of the 118 produce a picture. Seven are too thin or too sparse to read
at this size and keep the name and description they always had.
v0.19.3 — earlier
-----------------
The editor opens in roughly half the download it used to need.
- **569 KB down to 322 KB.** The built-in sprite art was 45% of everything a
visitor downloaded, and none of it is needed to open the editor. It now
lives in its own file, fetched the moment the editor is on screen and
before you could ask for it.
- **Nothing about using it changes.** Every sprite's name, size and category
is still in the page, so the library lists instantly. If you open the sprite
library or add a ready-made effect in the first half-second, it waits for
the art rather than showing you empty boxes, and says so if it is taking a
moment.
- Your own projects are untouched: art you have added lives in your project
file exactly as before. The starter sprites are drawn by the editor itself,
so it opens with something on screen whatever the network is doing.
- Offline still works — the new file is cached with everything else on your
first visit.
v0.19.2 — earlier
-----------------
See what your effect actually costs to draw.
- **Overdraw view.** One button in the View menu, and the stage shows how many
times each pixel gets painted: dark where nothing overlaps, bright where a
lot does. That number is what decides whether an effect runs on a phone, and
until now nothing in any editor would tell you — two effects that look
identical can cost four times as much, and you find out on the device.
In Unity and Unreal artists get this by hand: switch the blend mode to Add,
set the particle colour to a dim grey, put a black card behind the effect,
read the brightness, then undo all of it. This is that, built in, with the
reading done for you.
- **The reading, in the corner:** average overdraw, the worst spot, and how
much of the frame is covered at all. Average is the one that matters — a few
hot pixels are cheap, a whole screen painted three times over is not.
- **A particle budget you pick by device.** Phone (300), Tablet or Switch
(600), Desktop (1500), or no opinion. The counter turns amber when the peak
goes past it. The budget already existed in the file format and nothing ever
set it, so it could never actually fire.
- **It cannot change anything.** The view measures by running the real
renderer against a counting surface, so what it reports is what you see —
but it touches no part of your project, the simulation, or any export.
Checked by baking a Spine export with the view on and off and comparing.
- It costs about 4ms a frame on a heavy scene. Getting there took three
rewrites: the first was 80ms, and the cause was not what it looked like.
v0.19.1 — earlier
-----------------
Stretch or squash the timing of a whole action.
- **Select some keys and a bracket appears across the top of the sheet**, with
a grab at each end. Pull one and the selection stretches or squashes in
time; the other end stays put. The spacing inside keeps its proportions, so
"make this whole thing thirty percent slower" is one drag instead of moving
every key by hand and hoping the rhythm survived.
Dragging a key still slides the selection about as it always did. This is
the other half of timing work: the length of an action rather than where it
sits.
- Keys land on frames while you drag, like everything else in the timeline.
Hold Alt for the exact time.
- **It will not let you destroy the action you are editing.** Squash it as far
as you like and it stops at one frame between keys instead of merging them
into each other; pull it left past the start of the timeline and it stops at
zero instead of piling every early key onto the same moment. Both of those
lost keys in testing before the limits went in, which is why they are there.
v0.19.0 — earlier
-----------------
Copy and paste keyframes — the thing Spine users reach for most.
- **Select keys, Ctrl+C, move the playhead, Ctrl+V.** The spacing between them
comes with them, so a whole action lands intact wherever you put it. There
are "Copy keys" and "Paste keys" buttons in the View menu too, because a
shortcut nothing mentions is a shortcut most people never find.
- **Paste onto a different layer.** Select one layer before pasting and the
keys land on that layer instead, creating the property track if it does not
have one. Build a bounce once and give it to everything.
- **Paste mirrored** with Ctrl+Shift+V, or shift-click the Paste keys button.
Every value is negated, so a move to the right becomes a move to the left
and a turn one way becomes a turn the other. Meant for position and
rotation; it will do nothing sensible to Opacity, which is why it is a
separate command rather than the default.
- **Fixed on the way: Ctrl+C copied the LAYER even when you had just
box-selected a run of keyframes.** The obvious gesture did something
confidently wrong. Keys win when keys are selected; layers when they are
not; and the clipboard remembers which kind it holds, so paste never has to
guess from where you last clicked.
- Easing comes with the keys. Copy a run with an ease-out on it and the
ease-out is there when you paste.
v0.18.9 — earlier
-----------------
Housekeeping you will not see, except for one line on this page that was wrong.
- **This page used to say the developer notes live in "VERIFY.md".** No such
file exists, and as far as the history goes it never did. Anyone who went
looking found nothing. Fixed, and there is now a check that fails the
publish if any document names a file that is not there.
- **The project got a front door.** Nine developer documents and nothing
saying where to start. There is now a README, a single RULES file holding
every invariant in one place instead of scattered through comments, and a
guide for AI assistants picking the project up cold. None of this changes
the editor; all of it makes the next change safer.
- **A licence file now sits with the source**, carrying the same nine clauses
published here. If the two ever drift apart, the publish stops.
v0.18.8 — earlier
-----------------
A cleaning and safety pass. Almost nothing here changes what you see, which is
the point of it — this is the release that makes the next ten safer.
- **The publish button now runs a safety audit before it uploads anything.**
It refuses to publish if a file about to go live contains a password, a key
or a personal email address; if a developer-only file has strayed into the
website folder; if the marker that identifies this code as ours has gone
missing; if the security headers have weakened; if a link points somewhere
unexpected; or — the one with teeth — if any licensed artwork has ended up
in a shipped file. Every one of those rules existed already, written down
somewhere. Now they stop a publish instead of being remembered.
- **Dead code removed.** Three definitions nobody used: a table of value types
that nothing consulted, a function whose only caller had been deleted, and a
list of align modes that sat unread while the buttons passed their own text.
That last one is now actually read, so a typo in an align button says so
instead of quietly doing nothing.
- **Nothing was slow.** Measured before changing anything: drawing the
viewport is 9% of a frame's budget and everything else — visibility keys,
path following, the transform bar — is under a fifth of one percent, and all
of it scales linearly to a thousand layers. No optimization was needed, so
none was invented.
- The download is 569 KB compressed, and 45% of that is the built-in sprite
art. Loading it on demand instead would cut the first visit nearly in half.
That is a real change to how the app loads, so it is written up properly and
scheduled rather than rushed in at the end of a long day.
v0.18.7 — earlier
-----------------
I built a whole effect by hand and it broke in four places. All four are fixed.
The effect: a rocket that climbs a path with a flame trail, sparks and smoke on
it, hands over at 1.15s to an explosion with a shell burst, glitter and a shock
ring, using every one of the nineteen modules. Nothing below was visible in the
parts. All of it showed up the moment they were assembled.
- **FIXED, and the worst of them: one-shot emitters were silently missing from
a looping Spine export.** A looping bake warms up for four cycles before it
records anything, so an emitter set to fire once fired during the warm-up and
was finished long before recording started. On this firework the entire
explosion — three emitters, 1271 bones' worth — was absent from the .json,
while the warning list talked about trail slots. One-shots now restart at the
top of the recorded loop, and the export says so.
- **FIXED: hiding a layer now stops its emitters.** A Visible key hid the
drawing but the emitter kept running, so an explosion keyed on at 1.15s had
already fired at 0s, unseen, and was over before it appeared. Hiding a folder
stops everything inside it, and switching one on starts it from its own
beginning — so a burst fires when it appears, which is the point.
- **FIXED: a Visible key could empty the whole Spine export.** 1521 bones and
1512 slots became 9 and 0, with no error, because a branch that happened to
be hidden on the last frame was dropped from the bake. Bakes are a replay of
the project now: every layer is on throughout, whatever the playhead is
doing when you press Export, and the export panel says exactly that.
- **FIXED: renaming a path silently unhooked everything following it.** Paths
were referenced by name, so "Path 1" → "Launch Arc" left every layer on it
frozen where it stood, with no error and a Follow-path box gone blank. Two
paths sharing a name was worse — the layer jumped to the wrong one. They are
referenced by identity now, so a rename is just a rename. Projects saved
before this go on working. Deleting a path shows "⚠ missing path" on the
layers that were using it instead of quietly showing nothing.
- **Search in the Effects library.** 118 effects behind nine tabs, and no way
to find one you had heard of except reading every card. Type and it searches
all of them, by name and by description, telling you which category each
result came from.
- **Buttons that were cut off.** "Effects list" was losing 18 pixels of itself
and Help 7, both squeezed into a 24-pixel square meant for one-character
buttons. Help is "?" now, next to the "i". The hint on the Scene panel —
"drag to reorder · drop onto a folder to nest", the one line that teaches
that layers nest — was getting 28 pixels and ellipsising to a single letter;
it wraps to its own line now.
v0.18.6 — earlier
-----------------
The curve editor, the way Spine does it: shapes you can see, one click away.
- **Presets are pictures now.** Twelve tiles, each drawing its own curve, so
you pick a shape instead of guessing what "Back In" means. Every tile is
drawn by the same function that plays the animation, so a tile cannot show
you one thing and apply another.
- **The one you are using lights up.** Open a curve and the tile matching it
is highlighted. Before, all of them looked the same whatever the segment was
actually set to — the panel could tell you where you could go, never where
you were.
- **Three new shapes.** Slow Out (a long, soft landing), Strong In (almost
nothing, then a rush) and Elastic Out (overshoots a long way and springs
back), joining Ease, Back and Bounce.
- **Type the numbers.** Four boxes under the presets hold the bezier values,
for a curve copied from somewhere else or a value the mouse cannot land on.
Greyed out on Linear and Stepped, which have no handles to type.
- **One curve, many keys.** Select a stretch of keys in the timeline, pick a
shape, and it lands on all of them. The button says how many. A twelve-key
bounce used to mean opening this window eleven times.
- **A "Curve…" button in the View menu.** Reaching the editor used to mean
double-clicking the gap BETWEEN two keys, on the right row, in a sheet where
that gap can be four pixels wide. Everything the editor could do was already
there and most of it was unreachable in practice.
- **Fixed: the editor leaked two handlers every time you opened it.** Nothing
ever removed them, so a session with fifty curve edits carried a hundred
dead listeners running on every mouse move. The knobs, the graph handles and
the numbers all still work; there is just less rubbish behind them.
v0.18.5 — earlier
-----------------
Spine's transform bar, over the stage, with Local / Parent / World.
- **A transform bar on the viewport.** Translate, Rotate and Scale in a compact
strip in the top-left corner of the stage, showing whichever layer is
selected. Type into it and the layer moves. Drag a handle and the numbers
follow. It is a second way in to the same values the properties panel has
always had, so Auto Key, undo, the dope sheet and the curve editor all
behave exactly as they did.
Fold it away by clicking its title, or turn it off entirely in the View menu.
- **Local / Parent / World.** These pick which axes the X and Y arrows run
along:
Local — the layer's own axes. A layer rotated 40° travels the way it
faces.
Parent — its parent's axes. This is the space the numbers are stored in,
so dragging X changes the stored X and nothing else.
World — the stage's axes, flat across and up. The numbers become
absolute stage values: where the layer really is, whatever every
parent above it is doing to it.
- **A real bug this uncovered.** The X and Y arrows were DRAWN along the
layer's own axes but the drag was constrained in its parent's space. On any
rotated layer the arrow pointed one way and the layer went another. Both now
come from the same place, so the layer travels along the arrow you grabbed —
in every space.
- **Shear is shown greyed out, on purpose.** Spine has it; Ottomancer's
transform is position, rotation and two scales, with no shear component to
write to. A box that quietly swallowed what you typed would be worse than a
box that says why it is off.
v0.18.4 — earlier
-----------------
You can key a layer on and off, and it was asked for on the feedback board.
- **Visible is now an animatable property.** Select any layer — an emitter, an
image, a folder — and the transform panel has a Visible row next to Position
and Scale. Key it 1 to show, 0 to hide. It switches, it does not fade: a
layer is either there on a frame or it is not.
That means one project can hold several passes of an effect and turn each on
at its own moment, instead of a separate project per pass. Hiding a folder
hides everything under it.
From the board: "id love if i could key switches of assets or particles in
the hierarchy." Thank you — that is exactly the kind of thing worth asking
for.
- **The dope sheet calls rows what the panel calls them.** Rows read "Visible"
and "Progress" now, not the internal names.
- Honest limit, stated in the export panel where it matters: PNG sequence, GIF,
WebP, MP4 and the sprite sheet all carry visibility keys, because they render
frames. The Spine export does not — the layer bakes as if it were visible
throughout. Fix planned; until then the warning tells you before you export,
not after.
v0.18.3 — earlier
-----------------
The graph view has real curve handles now.
- **Bezier handles on the timeline graph.** Switch the timeline to graph view
(View menu), select a key, and the segments either side of it show their two
control points joined by dashed lines — the same way Spine draws them. Drag
one and the easing changes under your hand.
The curve dialog got handles two releases ago; the GRAPH did not, and the
graph is where you actually work. That was the gap.
- **Double-click adds and removes keys.** In graph view, double-click empty
track to drop a key exactly where you clicked, or double-click a key to
remove it. The diamond view keeps what it always did — double-click to type
an exact value, or double-click between two keys for the easing editor.
- Handles only appear on segments touching a selected key. Every segment at
once is an unreadable thicket on a busy sheet.
v0.18.2 — earlier
-----------------
A campfire built the way a fire actually is: four layers, not one.
- **New scene: Campfire.** Lit ground breathing underneath, a body of flame on
the sixteen-frame sheet so every particle burns rather than drifts, embers
leaving the top with trails, and smoke drawn over the lot. Four emitters at
four speeds, in that draw order.
- It is there as the standard, not just as another effect. A single emitter
cannot be a fire, and most of the fire entries in this library still are
one. This is what the rest are being measured against.
v0.18.1 — earlier
-----------------
The animated fire sheet is redrawn, with sixteen real frames.
- **"Flame Sheet 4x4" rebuilt.** The old one animated, but every pixel in it
was at full brightness — a flat silhouette flipping between poses. It was
the smallest sheet in the library by a wide margin, which is what a flat
silhouette costs.
The new one has the shading fire actually has: a white-hot core low down,
a bright inner flame inside the outer one, orange body, deep red at the tip
where it thins out. Three travelling waves at different speeds make tongues
that rise and lick across the sixteen frames.
- **It loops properly.** Every wobble is built from the frame number, so frame
sixteen flows back into frame one. Measured: the wrap is a SMALLER step than
an ordinary frame-to-frame one, so there is no pop once per cycle.
- Flipbook Fire, Blue Flame and Flamethrower all use it.
v0.18.0 — earlier
-----------------
Eleven more effects, aimed at the things casual games actually need.
- **117 effects now, up from 106.** The new ones are the beats a game asks for
over and over and the library had no answer to:
Damage Spark the jolt when something takes a hit
Landing Puff dust lifting where something lands
Freeze Crack ice locking on, shards settling where they stop
Splash Ring something hitting water
Poison Bubbles fat sickly bubbles rising and bursting
Electric Shock current flickering around a point
Heal Burst green motes lifting off
Wind Gust a gust crossing frame with leaves in it
Coin Pop coins bursting up and falling back
Star Rating Pop one star landing with a flash
Combo Flash a hard radial flash for a crit
- They are built on the sprites fixed in the last two releases, which is why
they were worth doing now rather than earlier: a spark effect made of
two-pixel dots is a spark effect nobody wants.
- The effects page lists all 117: ottomancer.com/effects
v0.17.5 — earlier
-----------------
Sparks look like sparks, and the site finally lists what is in the box.
- **"Hard Spark" redrawn.** It was a two-pixel rectangle — a dot pretending to
be a spark. It is now a streak with a white-hot head and a tail that fades
out behind it, which is what a spark in flight actually looks like and what
the effects that align particles to their direction of travel need. It is
the most-used sprite in the library after the flame, so Sparkler, Forge
Sparks, Celebration Burst, Rank Up Beam, Fireworks Show and Summoning Circle
all change with it.
- **"Splash Shard" redrawn** from a symmetrical diamond into a bent sliver.
- **A new page listing every effect**: ottomancer.com/effects — all 106 by
name, in their nine categories, with what each one does, and the 57 sprites
underneath. It is generated from the library itself, so it cannot drift from
what the editor actually contains. There is a link to it in the top bar.
v0.17.4 — earlier
-----------------
The fire sprites are redrawn. They look like fire now.
- **"Flame Body" and "Cartoon Flame" have been redrawn from scratch.** The old
ones were smooth, symmetrical teardrops — widest at the very bottom, soft
all the way round. That is a gradient blob, not a flame, and stacking a
hundred of them gave a fire that read as orange fog.
The new ones are shaped the way fire actually is: pinched at the root,
widest low down, tapering to a wisp that leans, with a white-hot core near
the base and edges bitten away so the outline is ragged rather than round.
- **Every fire effect improves at once** — Torch Flame, Flamethrower, Ghost
Fire, Lava Spurts, Cartoon Fire, Fire Tornado, Backdraft Roll, Dragon
Breath and the Volcano scene all use those two sprites.
- **Your existing projects improve too.** The sprites kept their names, so
anything you have already made picks up the new artwork with nothing to
re-do and nothing to re-link.
v0.17.3 — earlier
-----------------
A security pass, and a quiet mark of where this came from.
- **Checked, not assumed.** Every place the app writes HTML was traced: there
is exactly one, and it draws an icon from a fixed set, never anything typed
by anyone. The feedback board escapes every field it shows. There is no
eval, no new Function, no document.write and no injected frame anywhere in
the build. The server side caps the size of a post before reading it, checks
the type of every field, trims whitespace and cuts each to a maximum length.
- **Nothing here is "unhackable"** and it would be dishonest to say so. What is
true: the pages carry a strict content policy with a hash for every script,
the editor uploads nothing, and the one page that does send anything says so
on itself.
- The build carries a small origin mark. It does nothing, it holds no personal
information, and it exists so a copy of this code can be traced back here if
it ever appears under someone else's name.
v0.17.2 — earlier
-----------------
A dead copy of a function removed, and a guard so it cannot happen again.
- Nothing you can see changed. `isAncestor` existed TWICE with two different
meanings, and the second silently replaced the first for every caller. The
one that ran is the one that stops a layer being dropped inside itself; the
dead copy would not have. Reordering the file would have turned that into
scene corruption with no error anywhere. The dead copy is gone.
- The build now refuses to publish if any two top-level functions share a
name. A comment in the code claimed a tool already did this. There was no
such tool.
v0.17.1 — earlier
-----------------
Shape a path where it lives, and the handles work when paused.
- **Drag a path's points in the viewport.** Select the path and its points
appear — green at the start, red at the end. Drag one to reshape the path.
**Alt-click a point removes it; Alt-click the line adds one there** — the
same two gestures the curve editor uses. It never drops below two points,
because one point is not a path.
- **Fixed: the move/rotate/scale handles were visible but dead while paused.**
v0.16.2 made them draw whenever playback is paused, but the click handler
still asked "is this SETUP mode?" before starting a drag — so outside SETUP
you could see them, hover them, and nothing happened when you pulled. They
drag now wherever they are drawn.
v0.17.0 — earlier
-----------------
Paths: put a layer on a line and animate it along.
- **+ Path** adds a path to the scene — a dashed line with a green start and a
red end. It draws nothing and exports nothing by itself; it is there to be
followed.
- **Put a layer on it.** Select the layer, set "Follow path" in the properties
panel, and a **Progress** row appears: 0 is the start of the path, 1 is the
end. Key Progress and the layer travels — a rocket arcing, a coin flying to
a counter, a leaf crossing the screen.
- Progress is an ordinary keyable property, so the timeline, the dope sheet
and the curve editor with its new tangent handles all work on a path move
with nothing new to learn. Ease it out of the start and into the end exactly
as you would ease anything else.
- Movement is by **distance, not by point**: a path with one short leg and one
long one is crossed at a steady speed rather than dawdling on the short one.
- It comes out the other end as real animation. A layer following an arc
exports to Spine as ordinary position keys, so any runtime plays it with no
special support — and the same is true of GIF, MP4, WebM and the rest.
v0.16.5 — earlier
-----------------
Curves can be shaped by hand.
- **Tangent handles.** Select a key in any curve editor and two blue handles
appear. Drag one to pull the curve through that key — a slow start, a hard
snap, a long settle. Both sides move together so the curve stays smooth;
**hold Shift to bend one side only**, which is how an ease-in differs from
the ease-out beside it.
- **Hand-shaped keys keep their shape.** Tangents used to be recalculated
every time anything moved, so any shape you pulled was wiped the moment you
nudged a key. Keys you have shaped are marked with a small dot and are left
alone; everything else still auto-smooths as before.
- Adding a key (click empty space) and removing one (right-click) worked
already and are unchanged.
v0.16.4 — earlier
-----------------
A Spine import now arrives with the hierarchy you built, not one flat heap.
- **The exported bone tree mirrors your scene.** A firework used to land in
Spine as 2,724 bones hanging directly off root, with nothing to say which
belonged to the lift-off and which to the burst. It now arrives as the tree
you made:
root
Fireworks Show
Red
Comet Red -> its particles
Burst Red -> its particles
Glitter Red -> its particles
Every folder and every emitter becomes a named parent. Volcano Eruption,
Summoning Circle and the rest all changed the same way.
- The cause was world-space emitters. Their particles hold absolute positions,
so they cannot hang off a bone that moves — they were parented to root
instead, which is correct arithmetic and an unusable tree. The new parents
are STATIC bones with no transform and no keys, so they are identity: the
animation is byte-for-byte what it was, only organised.
- Six new checks keep it that way, including one that fails if an organiser
bone ever gains a transform or a keyframe.
v0.16.3 — earlier
-----------------
Drag a sprite onto the canvas, and Help stops hiding in a menu.
- **Drag an image from the list straight onto the canvas** and it is placed
where you drop it. The canvas lights up while you drag over it. Clicking
still gives the sprite to the selected emitter and double-clicking still
drops it in the middle, so nothing you already do has changed. Dragging was
the obvious thing to try and it used to do nothing at all.
- **The ? Help button is on the toolbar now**, not inside the More menu. It
opens 37 keyboard shortcuts and a short guide to how the app works — the
one thing that explains everything else, and it was behind a menu called
"More". F1 opens it too.
- **Ready-made things and empty things are now in separate boxes** under the
scene. "Effects", "Sprites" and "Animations" hand you finished content;
"+ Emitter", "+ Folder" and "+ Images" make new empty ones. They were mixed
together under a single heading, which made a 106-effect library look like
just another button.
v0.16.2 — earlier
-----------------
The move / rotate / scale handles were always there. Now you can see them.
- **Transform handles show whenever playback is paused.** Select a layer and
press Space: a square in the middle to drag it anywhere, an X and a Y arrow
to slide along one axis, a small square to scale, and the ring around it all
to rotate. Turn Auto Key on and posing sets a keyframe as you go.
None of this is new — it has been in the app the whole time. It only ever
drew in SETUP mode, and the app opens in ANIMATE, so unless you happened to
press a mode button you never saw a single handle and there was nothing to
suggest one existed. It still stays hidden while the effect is playing,
where it would just be clutter over moving particles.
- The SETUP and ANIMATE buttons now say what they actually give you.
v0.16.1 — earlier
-----------------
Exported loops actually loop.
- **A baked Spine loop now closes.** If you exported a looping effect and
found particles cutting short or snapping back at the wrap, that was real
and it is fixed. Two things were wrong, and both had to go:
Loop-safe Randomness was off by default, so the simulation never repeated
at all — measured, the particles one cycle later matched the start in 0
cases out of 36. An export set to Loop now switches it on for itself while
baking, warms four cycles, and says so. Your project is left as it was.
Spine slots were also handed to a new particle as soon as the old one died,
so a particle arriving one cycle later found its slot taken by a stranger —
and Spine then interpolated between the two across the loop point. That is
the snap. A looping bake now keeps each particle's slot for the whole
animation.
Measured on four effects: every slot that is on screen at both ends now
holds exactly the same value at both ends. Portal Vortex was jumping by
1261 pixels; it is now zero. There is a test so it stays that way.
- A looping bake uses more slots than before (Fireflies 55 to 64) and the
.json is usually SMALLER, because a loop only has to cover one cycle.
v0.16.0 — earlier
-----------------
Thirty more effects, and the timeline now tells you where a loop closes.
- **106 ready-made effects, up from 76.** Thirty new ones across every
category: Fire Tornado, Dragon Breath, Forge Sparks, Geyser, Ocean
Spray, Bubble Column, Black Hole, Time Rewind, Soul Ascend, Necrotic
Miasma, Falling Star Wish, Aurora Veil, Cherry Blossom Drift,
Hyperspace Jump, Frost Nova, Glass Shatter, Ground Slam Dust, Slash
Arc, Anime Impact Flash, Incense Curl, Smoke Rings, Locomotive Chuff,
Backdraft Roll, Ripple Rings, Anger Steam, Dizzy Stars, Coin Magnet,
Rank Up Beam — plus two multi-emitter scenes, **Volcano Eruption** and
**Summoning Circle**.
- **A pin for where the effect repeats.** The ruler already marked each
emitter's own cycle. With more than one emitter that is not the same
thing: emitters of 1s and 1.5s only line up again at 3s, and 3s is the
number you need to cut a PNG sequence or a Spine clip that loops. The
new teal dashed pin marks it, and says the period in seconds and
frames. It stays away entirely if any enabled emitter plays once and
stops, because then the effect never does come back round.
- **The export dialog says when the first frame will be empty.** On a
one-shot render nothing has been emitted at time zero, so frame one is
blank. That was always true and never mentioned.
Under the bonnet, and only worth knowing if something looks wrong: the
export container writers (GIF, zip, animated WebP, MP4) now have their own
tests, and every one of the eight export formats was run end to end and
checked byte by byte. Four of the new effects were built with an inverted
force direction — a "black hole" that was really a fountain — and were
caught by measuring what they produced rather than trusting the settings.
v0.15.1 — earlier
-----------------
Security hardening, an honest privacy note, and one more button.
- **Reset a module.** Next to the copy arrow on each module header there
is now a ↺. It puts that one module back exactly as a new emitter
would have it — and removes its keyframes with it, because defaults
with old keys still driving them is not "back to how it started", it
is a third state that never existed. It asks first, and tells you how
many keyed properties it is about to remove.
- **Three security headers added**: HSTS (so the first request of a
session cannot happen in the clear on a hostile network),
Permissions-Policy (this tool needs no camera, microphone, location or
payment access, so all of it is now denied outright), and
Cross-Origin-Opener-Policy.
- **The feedback board can never be cached by the offline worker.** It
was not being cached, but only because nothing had happened to put it
there — and the lookup ignored query strings, which is how one
visitor eventually gets served another visitor's response. It is now
excluded explicitly.
- **The privacy claim now says what actually happens.** The licence said
the software transmits nothing anywhere — true of the editor, and not
true of the feedback board, which is a public page you can post to.
Section 7 now spells out exactly what a post sends, what the server
keeps to stop one person flooding the board (a one-way salted hash of
your address, never shown, never reversible), and that posting is
optional. The feedback page says the same thing in a line.
v0.15 — earlier
---------------
Three things for the person using it, and one for anyone who wants to
script it.
- **Send one module to another emitter.** Hover any module header in the
Properties panel and a small → appears. It copies just that module
— Velocity, or Colour over Lifetime, or whichever — to another emitter,
or to all of them at once. Duplicating a whole emitter was the only
way to reuse anything before, which is no help when the two emitters
differ in every other respect.
It copies the keyframes in that module too. Copying the numbers alone
would leave the target's old keys driving your new values: the panel
would show what you sent and the animation would do something else,
with nothing to tell you. Anything the target had keyed in that module
is replaced, not merged.
- **Importing a flipbook sheet now shows you the slice.** Bring in a
square sheet and you get a preview with the grid drawn over it, and a
button for each division that actually fits — 2×2, 4×4,
8×8. Pick the one that lands between the drawings instead of
across them, press the button, and Texture Sheet Animation is switched
on and set up for you, with the sheet moved to the front of the sprite
list where the tile grid applies.
Before this you got a sentence in the status bar naming the candidate
grids, then went looking for the module and typed the numbers in
yourself, and found out whether you were right by pressing play.
Importing an ordinary sprite is unchanged — no dialog appears.
- **A filter for the Properties panel.** There are 112 rows across
nineteen modules. Type in the box next to "Properties" and only the
matching ones stay: it looks at each property's name, its unit and its
description, as well as the module it lives in, so "speed" finds Start
Speed and Stretch by Speed, and "flip" finds all three flips wherever
they live. Modules with nothing matching disappear rather than sitting
there empty. Clearing the box puts the panel back exactly as it was,
including which modules you had collapsed.
- **Ottomancer from the command line, and a written-down file format.**
`node export.mjs project.ottomancer --info` summarises a project;
`--validate` checks it bakes to a sound Spine skeleton; `--spine`
writes that skeleton, for 3.8, 4.0, 4.1 or 4.2. `FORMAT.md` documents
the `.ottomancer` JSON — every module, the four value types, how
keyframes are stored, and the rules a reader should follow.
Why bother: the project file is open JSON, so a script can generate
twenty variations of an effect, retint a whole scene, or check exports
in a build without the editor being involved. The command loads the
engine out of the shipped page rather than reimplementing it, so it
cannot disagree with what you see on screen.
Honest limit: `--spine` writes the skeleton only. The atlas and its
page image need pixels packed into a sheet, which needs the browser.
Use Export > Spine for those.
v0.14.3 — earlier
-----------------
Three things, none of them requested by anybody: a lock on the front
door, a test that runs itself, and an apology to anyone using Spine 4.
- **Only the scripts in this build can run.** The site now sends a
policy listing the exact fingerprint of every piece of code it
contains. Anything else — a script injected into the file, appended to
it, or slipped in by a compromised tool — is refused by the browser
before it executes. This project has actually shipped a build with an
injected script in it once: it uploaded cleanly and left the editor
dead. That specific thing cannot happen quietly again. The
fingerprints are regenerated on every build, because a stale one would
mean a blank page.
Also blocked by the same policy: loading code from another website,
and sending your data to one.
- **The editor is now tested by a command, not by hand.** `tests\engine.mjs`
runs the real particle simulation and checks 28 things: emitter scale,
Flip U and V and their independence, all three alignment modes, that
rotation still works under one and is suppressed under another, curve
tangents, save-and-reload including projects saved before these
features existed, and all 76 shipped effects building, emitting and
staying numerically sane. Publishing runs it and refuses to upload if
anything fails.
- **Spine 4 users were being sent the long way round.** The export has
been able to write 3.8, 4.0, 4.1 and 4.2 for a while — it changes the
format, not just the label — but the /spine page still said you had to
import with 3.8 and described a detour through an old install. That
page now says what the software actually does. The genuine caveat is
stated plainly instead: the output is verified against the format on
every build, but nobody has yet opened it in a running Spine editor.
- Offline mode was missing three files it should have been keeping,
including the one that makes the Back link work. Generated from the
file list now, so it cannot fall behind again.
v0.14.2 — earlier
-----------------
Findings from an audit of the whole thing, not from the to-do list.
- The feedback board could look four hours out of date. Post a bug
report, reload, and it might not be there — and neither would anyone
else's. The board is cached for half a minute so that heavy traffic
cannot exhaust the database, which is right, but Cloudflare was
writing its own four-hour figure into the instruction sent to your
browser. The half-minute cache stays; your browser is now told, every
time, not to keep a copy.
- The sitemap named a namespace that does not exist — sitemap.org
instead of sitemaps.org. Nothing on the site showed it, and it is the
file a search engine is handed first.
- The /api/ responses were missing two security headers that every page
on the site already had, because the file that sets them only applies
to pages.
- A dialog whose cleanup step failed used to fail in complete silence,
which left window listeners attached and showed up later as a control
that responded twice. It still cannot trap you in a dialog, but it now
says what happened.
Also checked and found correct, so nobody has to wonder again: the
advertised counts (75 effects, 57 sprites, nine categories) are exact;
every page, asset and internal link resolves; the database is empty of
test rows; the rate limit, the honeypot and the input validation all
behave; and an exported web bundle now carries the corrected player.
v0.14.1 — earlier
-----------------
New: Alignment "birth", and an explanation of the one next to it.
- Renderer > Alignment has a third option. "birth" points the sprite the
way the particle launched, once, and then lets it rotate normally from
there. That is what debris wants: it leaves the blast pointing outward
and then tumbles. "velocity" re-aims it every single frame, which is
what a streak or a raindrop wants.
- The existing "velocity" option had a trap worth naming: because it
re-aims every frame, it overwrites rotation entirely, so setting an
angular velocity alongside it silently does nothing. It still behaves
exactly as it always did — but the control now says so, and "birth" is
the option for people who wanted both.
v0.14 — earlier
---------------
New: Flip U and Flip V.
- Two new controls in the Main module, under Flip Rotation. Each is the
fraction of particles to mirror: Flip U left-to-right, Flip V
top-to-bottom, decided independently per particle.
This is the cheapest variety there is. One asymmetric sprite — a leaf,
a shard, a splash, a scrap of debris — becomes two or four without
drawing anything new, and a spray of them stops looking like the same
stamp repeated.
- Works everywhere the particle does: the viewport, PNG sequences, MP4,
WebM, GIF, WebP, the Spine export, and an exported web bundle. Checked
in each rather than assumed, because a mirror that appears in the
editor and not in your engine is worse than no mirror at all.
- Nothing you have already made changes. Both default to 0, and the
feature deliberately does not draw from the per-particle random
sequence — doing so would have reshuffled every existing effect while
changing nothing about what any of them does.
v0.13.3 — earlier
-----------------
Exported web bundles now match the editor.
- A web bundle played a scaled world-space emitter at the wrong
particle size. The fix that made emitter scale affect particle size
went into the editor in v0.12.3; the little runtime that ships inside
an exported bundle never got it. So the same project drew one picture
in the editor and another in the bundle you handed someone: particles
spread out and moving correctly, each one the wrong size. Scale 2 drew
them at 1, scale 0.5 drew them at 1.
Only world simulation space was affected, and only at a scale other
than 1 — which is everything unless you changed it.
- Checked the rest of that runtime the same way rather than waiting to
trip over the next one: of the 125 functions it shares with the
editor, this was the only one that had fallen behind. The pre-flight
check now compares all 125 before any release, so a bundle that would
not match the editor cannot be published again.
v0.13.2 — earlier
-----------------
Autosave stops re-copying your images.
- A project's pictures used to be written into every autosave and every
recovery snapshot. On a 2048x2048 sheet of the kind that does not
compress, that is 21.35 MB written each time — and 99.9% of it was the
one image. The settings, meaning every emitter, curve, gradient, key
and animation you have made, come to 22.6 KB.
Images are now stored once, on their own, and rewritten only when you
actually add or remove one. An autosave went from about 75
milliseconds of frozen editor to under half a millisecond; the
snapshot went from 21.35 MB to 12 KB.
- Which means the recovery history works on real projects. Its 3.5 MB
allowance used to be swallowed by duplicate copies of the same
picture, so a project with one large sheet in it kept no recovery
points at all. It now keeps the last twelve.
- Your .ottomancer files are unchanged and still carry their own art —
a project file that needed this browser's storage to open would not
be a file you could send anyone. Projects saved by older versions
still open exactly as before, and an autosave left by an older version
is still restored with its images.
v0.13.1 — earlier
-----------------
Buttons that looked normal and did nothing. Every one of these was a
control you could see, point at, click, and get no response from — which
is the most annoying kind of bug there is, because it looks like you did
it wrong. Checked at 800x600, 911x512, 1024x768, 1093x614, 1280x720,
1366x768 and 1920x1080, which covers the common laptop sizes and the
browser zoom levels people actually use: zero unreachable controls left.
- The "View" menu on the timeline was almost empty and is now full.
Onion skin and its frame count, the graph reading, Curves…, Guides
and A/B were all supposed to live in it. They were being built a
moment after the menu was assembled, so the menu quietly took the one
button that existed yet and left the other six crowding the timeline
bar — which is why that bar was nearly three times wider than the
space it had.
- The "More" and "View" menus open properly. Their entries could not
be clicked at all below 1200px wide: the menus drop below their
button, and the bar had been told to scroll sideways, which silently
clips anything hanging outside it. Both bars wrap to a second row
instead, as they were originally written to.
- The "View" menu now opens upward when it is near the bottom of the
window, instead of running its last entry off the bottom edge.
- Controls at the bottom of the properties panel are clickable again.
The floating "Buy me a coffee" pill was pinned to the bottom-right
corner on top of everything else, and the editor fills the whole
window — so it sat over whichever controls happened to be there. It
is gone; the support button on the top bar was always the more
visible of the two anyway.
- The support button no longer falls off the right-hand edge on a narrow
window. Below 1200px the two right-hand labels shorten to
"Support" and "Bugs" — the full wording is still in the tooltip.
- Below 950px, where the properties panel folds away to make room, the
editor now says so and tells you how to get it back. There has been a
line of styling waiting to show that message since the narrow layout
was written; the message itself had never been added.
- The timeline bar fits its controls on two rows rather than three on a
narrow window, which gives the dope sheet back 30 of its 210 pixels.
v0.13 — earlier the same day
----------------------------
Everything below from 0.12.1 to 0.12.3 shipped on the same day and was
never released separately, so it is all collected here as 0.13. The
detailed entries are kept because they say what actually changed.
It earns a version of its own rather than another patch number for one
reason: **effects that use a scaled emitter in world simulation space
now draw differently**, because their particles finally scale with the
emitter. That is a change you can see in work you already saved, and a
version number that claimed nothing had changed would be lying to you.
Alongside that, three ways of losing work were closed:
- a dragged loop region made a project impossible to save at all;
- autosave could stop and never say so;
- and the recovery snapshot re-serialised the whole project on every
edit once storage filled, which is what made large projects freeze.
Also new: a "Bugs & ideas" button on the top bar, a warning that appears
if autosave ever stops, and the editor tab finally has an icon.
v0.12.3 — fixes
---------------
- Scaling an emitter now scales its particles too when the emitter is
set to world simulation space. It already worked in local space, so
the same emitter at the same scale drew two different pictures
depending on that dropdown: in world space the particles spread out
and moved faster but each one stayed its original size.
If you have a saved project with a world-space emitter scaled to
anything other than 1, it will look different — larger or smaller,
and correct. Projects at scale 1, which is everything unless you
changed it, are untouched.
v0.12.2 — fixes
---------------
- Dragging the loop region no longer makes a project impossible to save.
Opening a file overwrote the loop region with the full animation
length, so a project whose loop had been dragged never read back as
itself — and the save check, correctly, refused to write a file that
would not reload. Two bugs in one: the loop region is now kept as you
set it and survives saving and reopening.
- The "More" menu on the top bar sat to the right of the support
button and got pushed off the edge, showing as a stray fragment of its
own label. It now sits with the buttons it holds.
- A "Bugs & ideas" link now sits on the top bar next to the
support button. A clear bug report is worth more than a coffee, and it
was two clicks further away than the donate button.
v0.12.1 — fixes
---------------
- MP4 export works again at 1080p and above. It had been asking the
browser for an H.264 level that cannot encode anything larger than
720p, so a normal 1920x1080 export was refused and reported as
"H.264 not available" on machines that encode H.264 perfectly well.
The exporter now picks a profile that fits the size you asked for.
- Texture sheet animation no longer slices sprites that are not
sheets. The tile grid was being applied to every sprite in an
emitter, so an ordinary sprite sharing an emitter with a flipbook
was drawn at a sixteenth of itself. The grid now describes the
first sprite only. This also affected the Spine export and the
exported web player, and is fixed in all of them.
(Visible in the shipped Flamethrower effect, whose Heat Puff was
being quartered.)
v0.12 — first public release
----------------------------
A little history: this software was originally developed under the name
"Ottopia Particles" before becoming Ottomancer for its public debut.
The editor:
- professional dope-sheet timeline: dope sheet, frame ruler over the key lane,
transport cluster, loop region you can drag, animation variants with
their own menu, and a curve editor in its own window.
- Properties panel rows now wrap instead of pushing buttons out of
reach; every label stays inside its button; small controls got
proper click sizes.
- flat professional dark look: flat panels, orange accent, matching light
theme.
The library:
- 118 ready-made effects in nine categories — including animated
flipbook effects (Toon Explosion, Flipbook Fire, Electric Zap),
seamless loop overlays for games (Win Rays, Pulse Glow, Shine
Sweep, Big Win, Idle Shimmer), Matrix Code Rain, a Comet, Cartoon
Fire, and many variants.
- 57 built-in sprites, with animated 4x4 sheets drawn frame by frame.
- Every effect is an ordinary emitter after you apply it — recolor,
resize, pull apart, make it yours.
Around the app:
- Exports, all verified from disk by the test pipeline: Spine-compatible
JSON + atlas + PNG (engine-ready), PNG sequence, WebM and MP4 video,
animated WebP and GIF, SVG (transforms; warns rather than writing an
empty file), and a compact web bundle with its own player.
- A website version: same editor, nothing installed, works offline
after the first visit, installable as an app.
- A license in plain language: free for everyone, everything you make
is yours to sell; just don't sell or repackage the tool itself.
- Version number in the title bar, so reports can say which build.
Known rough edges:
- This is a one-person, free-time project. Things will be imperfect;
reports are welcome and read. Thank you for your patience.