Skip to content

Conversation

@Brandonn-Etheve
Copy link

Background: i was facing major perfomance issue on very large tileset (Tiled UI get frozzen for more than 5 min and prone to crash). I decided to let an AI rewrite a performance patch and there is a massive performance improvement on all of my large tileset (instant vs 5 mins).

Only tested in windows version of Tiled but i think it should work on every supported platform

Since this is patch is writen by AI someone need to try if every fonctionnality was preserved and no bug was induced, so far i only tested created and removing some animations in diffents configuration but maybe not all possible settings

At least on my side it provide a massive improvement (from unsuable to ultra fast) so i think it should be worth checking or making available in a separate download on release so people can use it when performance maters


BulkAnimationEditor: major performance pass (cache sizes, avoid indexOf, macro batching)

Summary

This PR removes several O(n²) hot paths and batches edits to avoid UI stalls when creating animations for large selections. Dialogs now open promptly and animation creation scales much better on big tilesets.

Motivation

When selecting many tiles and choosing Create Bulk Animations From Selection, Tiled would appear frozen for minutes before the configuration dialog appeared. The main causes were repeated linear searches over tileset.tiles and repeated recomputation of geometry derived from the tileset.

Key Changes

  • Replace indexOf lookups with ID math

    • getTileCoord, getSelectionExtent, and rectangle checks now compute (x, y) directly from tile.id using cached numCols.
  • Introduce a lightweight cache

    • Cache numCols, numRows, the sorted selectedTiles, and the computed extent for reuse across validations and UI updates.
  • Batch mutations with tileset.macro(...)

    • Both creation and clearing of animations run within a single macro to reduce undo steps and UI updates.
  • Remove full-tileset scans inside loops

    • Dropped tileset.tiles.filter(t => t === null) per tile. We now validate per-frame tiles as we build frames.
  • Robust frame building

    • getFrames advances by computed idStride and retrieves tiles via tileset.findTile(id) (fallback to tileset.tile(id)), aborting gracefully if a referenced tile is missing (important for image‑collection tilesets with sparse IDs).
  • Safer, faster rectangle checks

    • isSelectionRectangular uses the cached selection and expected contiguous ID pattern without extra searches.
  • UI correctness preserved

    • Direction/stride/frame/duration inputs behave as before; framesInput.maximum updates when direction/stride changes.

Performance Impact

  • Eliminates repeated O(n) indexOf calls → transforms several workflows from O(n²) to O(n) over the selection.
  • Fewer allocations and no repeated full‑array filters.
  • Single macro per operation reduces repaint/undo overhead.

Compatibility

  • Works with tileset image sheets and image‑collection tilesets.
  • Uses tileset.findTile(id) when available (Tiled ≥ 1.9.2), otherwise falls back to tileset.tile(id).
  • No changes to the user‑facing workflow or menu entries.

Risk & Edge Cases

  • If a frame ID does not exist (e.g., sparse IDs), creation aborts with a clear alert rather than silently producing partial animations.
  • Logic assumes IDs are contiguous only for image‑sheet tilesets; this is handled by findTile/tile checks.

Testing

  1. Open a large tileset (thousands of tiles).

  2. Select a large rectangular region; run Create Bulk Animations From Selection.

    • Expected: Dialog opens quickly; creating animations completes without UI freeze.
  3. Try directions Right, Down, Both with various strides and frames (including 0 = until end).

  4. Repeat on an image‑collection tileset to confirm graceful handling of missing IDs.

  5. Use Clear Animations In Selection and verify a single undo step restores all frames.

Future Work

  • Optional “Fast mode” that skips isSelectionRectangular() on very large, irregular selections.
  • Progress feedback for extremely large operations.

Notes

Version bumped to 1.3.2-p1 to indicate a performance patch.

…dexOf, macro batching

- Replace indexOf-based lookups with tile.id math
- Cache numCols/numRows, selectedTiles, extent
- Use tileset.macro() to batch writes
- Drop full tileset scans inside loops
- Build frames via findTile()/tile(), abort on missing IDs
- Keep UI behavior; update frames maximum dynamically
- Bump version to 1.3.2-p1
@Oskarsson
Copy link

This helped me a lot, blazing fast on my 4k tileset while the current released version took ages for every step. Just started using it but so far no issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants