mapeditor/tiled
Flexible level editor
Mixed signals — read the receipts
worst of 4 axesnon-standard license (Other)
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 2d ago
- ✓24+ active contributors
- ✓Other licensed
Show 4 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 50% of recent commits
- ⚠Non-standard license (Other) — review terms
What would change the summary?
- →Use as dependency Concerns → Mixed if: clarify license terms
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/mapeditor/tiled)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/mapeditor/tiled on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: mapeditor/tiled
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/mapeditor/tiled shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Mixed signals — read the receipts
- Last commit 2d ago
- 24+ active contributors
- Other licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 50% of recent commits
- ⚠ Non-standard license (Other) — review terms
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live mapeditor/tiled
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/mapeditor/tiled.
What it runs against: a local clone of mapeditor/tiled — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in mapeditor/tiled | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 32 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of mapeditor/tiled. If you don't
# have one yet, run these first:
#
# git clone https://github.com/mapeditor/tiled.git
# cd tiled
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of mapeditor/tiled and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "mapeditor/tiled(\\.git)?\\b" \\
&& ok "origin remote is mapeditor/tiled" \\
|| miss "origin remote is not mapeditor/tiled (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "README.md" \\
&& ok "README.md" \\
|| miss "missing critical file: README.md"
test -f "CONTRIBUTING.md" \\
&& ok "CONTRIBUTING.md" \\
|| miss "missing critical file: CONTRIBUTING.md"
test -f ".github/copilot-instructions.md" \\
&& ok ".github/copilot-instructions.md" \\
|| miss "missing critical file: .github/copilot-instructions.md"
test -f "Doxyfile" \\
&& ok "Doxyfile" \\
|| miss "missing critical file: Doxyfile"
test -f ".readthedocs.yaml" \\
&& ok ".readthedocs.yaml" \\
|| miss "missing critical file: .readthedocs.yaml"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 32 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~2d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/mapeditor/tiled"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Tiled is a general-purpose tile map editor written in C++ with Qt, enabling developers to create 2D tile-based game maps (for RPGs, platformers, etc.) in the TMX format with support for unlimited layers, custom properties, multiple tilesets, and flexible tile sizes. It exports to TMX (Tiled Map eXchange) format, a widely-adopted standard for tile map data. Monolithic desktop application structured around a Qt-based UI core: src/ contains the main editor (C++ with QML UI components), src/plugins/ holds file format handlers and extensions (Python plugin support), dist/ manages platform-specific packaging (WiX installers for Windows, macOS bundle fixes, AppImage for Linux), and docs/ contains Sphinx-based documentation. TMX file I/O is central, with tight coupling between the map model and the editing UI.
👥Who it's for
Game developers building 2D tile-based games (especially indie developers using engines like Godot, LibGDX, or custom engines) who need a visual level editor to design maps without writing code. Also used by level designers and artists collaborating with programmers.
🌱Maturity & risk
Highly mature and production-ready. The project has multi-platform CI/CD via GitHub Actions (Ubuntu, macOS, Windows via AppVeyor), official distributions via GitHub Releases and itch.io, broad Linux package support (Flatpak, snap, distro repos), and code signing infrastructure (SignPath). Active development with regular releases and maintainer-signed macOS builds indicating long-term commitment.
Standard open source risks apply.
Active areas of work
Active ongoing maintenance visible via GitHub Actions workflows (packages.yml, ubuntu.yml, macos-latest.yml, codeql-analysis.yml). Recent work includes dependency management (dependabot.yml), documentation builds via ReadTheDocs, translation management via Weblate (hosted.weblate.org/engage/tiled), and code quality scanning (CodeQL). The project maintains signed release infrastructure and continues cross-platform support.
🚀Get running
git clone https://github.com/mapeditor/tiled.git
cd tiled
# Ubuntu/Debian
sudo apt install qtbase5-dev libqt5svg5 qttools5-dev-tools zlib1g-dev qtdeclarative5-dev qbs
# Then build with Qbs:
qbs build
Daily commands:
After building with Qbs, run the editor executable (typically in the build output directory, e.g., release-install/bin/tiled on Linux/macOS or release-install/bin/tiled.exe on Windows). No server or special initialization needed—it's a standalone desktop app.
🗺️Map of the codebase
README.md— Core project description and purpose; essential to understand what Tiled does and its design philosophy as a flexible tile map editor.CONTRIBUTING.md— Contributor guidelines and development workflow; mandatory reading for any contributor to align with project standards..github/copilot-instructions.md— AI assistant guidelines specific to this codebase; helps understand project-specific conventions and expectations.Doxyfile— Documentation generation configuration; defines how the C++/Qt codebase is documented and analyzed..readthedocs.yaml— Documentation build configuration; critical for understanding how user-facing docs are generated and deployed..github/workflows/packages.yml— Primary CI/CD pipeline for cross-platform builds; shows the build matrix and distribution strategy..github/dependabot.yml— Dependency management automation; reveals critical external dependencies and update strategy.
🧩Components & responsibilities
- Map Editor UI (Qt (QWidget/QML), OpenGL rendering) — Main editor window, canvas rendering, tool palette, property inspector, layer/object panels
- Failure mode: Inability to edit/save maps; corrupted layer/object state
- TMX Format Handler (Qt XML, custom C++ serializers) — Serialization/deserialization of .tmx (XML), .tsx (tileset), and related map formats
- Failure mode: Map data loss; incompatible format versions; missing tileset references
- Tileset Manager (Qt Image/Pixmap, custom data structures) — In-memory tileset caching, tile property assignment, animation frame management
- Failure mode: Incorrect tile rendering; memory exhaustion on large tilesets
- Build & Distribution Pipeline (QBS, GitHub Actions, platform-specific installers (WiX, AppImage)) — Automated compilation, testing, and packaging for Windows/macOS/Linux
- Failure mode: Failed releases; broken installers; incorrect dependencies in distribution
- Documentation System (Sphinx, MyST, RTD hosting, Transifex i18n) — User manual, API reference (Doxygen), tutorials, and localized translations
- Failure mode: Out-of-date docs; broken tutorials; missing translations affecting user adoption
🔀Data flow
User (File System)→TMX Parser— Map file (.tmx) loaded from disk into memoryTMX Parser→Map Data Model— Parsed XML converted to internal layer/object/tileset graphMap Data Model→Tile Map Renderer— Layers and tiles indexed for viewport renderingUser (Input)→Command/Undo Engine— Editor actions (paint, draw, delete) queued as reversible commandsCommand/Undo Engine→Map Data Model— Executed commands mutate layers/objects; undo reverts mutationsMap Data Model→TMX Serializer— Dirty map state saved back to .tmx file on user save action
🛠️How to make changes
Add a new language/localization
- Create translation file in docs/locale with appropriate language code (e.g., docs/locale/ja/LC_MESSAGES/manual.po for Japanese) (
docs/locale/de/LC_MESSAGES/manual.po) - Update .tx/config to register the new language with Transifex (the translation platform) (
.tx/config) - Run dist/update-translations.sh to sync translations across the build system (
dist/update-translations.sh)
Add a new documentation page
- Create a new .rst file in the docs/ directory following Sphinx/MyST conventions (
docs/index.rst) - Add the file reference to the toctree in docs/index.rst (
docs/index.rst) - Rebuild documentation using docs/Makefile or .readthedocs.yaml will auto-build on push (
docs/Makefile)
Add a new platform build target
- Create a new workflow file in .github/workflows/ (e.g., windows-latest.yml) (
.github/workflows/ubuntu.yml) - Reference appropriate build scripts from dist/ (e.g., dist/linux/AppRun for Linux) (
dist/linux/AppRun) - Update dist/distribute.qbs to include the new platform in the distribution matrix (
dist/distribute.qbs)
Configure dependency updates
- Define package ecosystem and version constraints in .github/dependabot.yml (e.g., pip, npm, cargo) (
.github/dependabot.yml) - Set schedule frequency and assign reviewers for automated dependency PRs (
.github/dependabot.yml)
🔧Why these technologies
- Qt/QBS (Qt Build System) — Cross-platform GUI framework and build system enabling single-codebase compilation for Windows, macOS, and Linux with native look-and-feel.
- Sphinx + MyST Parser + RTD Theme — Industry-standard Python documentation framework supporting multiple output formats, internationalization (i18n), and hosted deployment via Read the Docs.
- GitHub Actions + Dependabot — Native CI/CD and dependency management within GitHub ecosystem; enables automated testing, building, and security updates across platforms.
- Multi-license (GPL/BSD/Apache) — Maximizes adoption across different commercial/open-source projects by providing license flexibility without forking.
⚖️Trade-offs already made
-
Single-codebase Qt application vs. platform-specific implementations
- Why: Reduces maintenance burden and ensures feature parity across Windows, macOS, Linux.
- Consequence: Requires careful abstraction of platform-specific APIs; potential performance trade-offs vs. native-only apps.
-
Multi-license model (GPL + BSD + Apache)
- Why: Enables both open-source and proprietary integrations.
- Consequence: Increased legal/licensing complexity; contributors must understand license implications.
-
Sphinx for documentation instead of in-code wiki
- Why: Separates documentation from source code; allows professional hosting and translation management.
- Consequence: Documentation drift risk if not kept in sync with code changes.
🚫Non-goals (don't propose these)
- Real-time collaborative editing (single-user editor model)
- Built-in game engine integration (exports to formats consumed by third-party engines)
- Cross-platform mobile app (desktop-only application)
- Database-backed map storage (file-based format: TMX)
🪤Traps & gotchas
Qt version lock: Code requires Qt ≥5.12; upgrading Qt is non-trivial due to API changes and QML compatibility. Qbs build tool: Not as widely known as CMake; if Qbs breaks, fallback to CMake/QMake (which exist but lag behind). Platform-specific code: macOS code signing, Windows installer generation (WiX), and AppImage creation have separate workflows—changes to packaging easily break on one platform. Python plugin: Requires Python development headers; optional but complicates dependency matrix. XSLT in build: src/plugins/ uses XSLT for format conversion—requires libxml2/libxslt, non-obvious dependency for C++ developers. Translation system: Uses Weblate for i18n; new strings need Weblate integration, not just code changes. No Docker/container setup documented: Developers must manually install Qt and Qbs—no docker-compose up shortcut.
🏗️Architecture
💡Concepts to learn
- Tile-based map rendering — The entire domain Tiled addresses—understanding how tile grids, layers, and offsets compose into a full game world is foundational to reading the map model code
- TMX (Tiled Map eXchange) format — The core export format and data interchange standard; reading src/libtiled/mapformat.cpp requires understanding TMX XML structure and semantics
- Qt Model/View pattern (Qt MVC) — Tiled uses Qt's Model/View architecture extensively for layers, tilesets, and object properties; understanding QAbstractItemModel is essential for UI modifications
- QML and Qt Quick UI composition — Modern Tiled UI components use QML for dialogs and property panels; understanding QML binding and signals is needed for UI-level changes
- Plugin architecture via Qt plugins (QPluginLoader) — Tiled's extensibility relies on dynamic loading of plugins (e.g., CSV/JSON format handlers); understanding Qt's plugin interface is needed to add new formats
- Sparse vs. dense tile storage — Large maps with empty regions need efficient memory representation; Tiled likely uses sparse tile encoding or layer compression—understanding the trade-offs impacts performance optimization
🔗Related repos
bjorn/tiled-qt— Historical predecessor/fork—context for understanding Qt migration decisions and early architecturemapeditor/tiled-java— Official Java-based map editor alternative in the same ecosystem; useful for comparing API design and architecture across language implementationsgodotengine/godot— Major consumer of Tiled—Godot has a built-in TMX importer; understanding Godot's map import layer helps inform Tiled's export format decisionslibgdx/libgdx— Another primary consumer of Tiled maps; libGDX's TiledMap class and loaders are reference implementations for TMX parsing outside of Tiled itselfthorbjornl/qbs— Qbs is maintained separately; understanding its docs and limitations is critical for debugging build issues specific to Tiled's Qbs configuration
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add Windows-specific CI workflow validation for installer packaging
The repo has dist/win/ with WiX installer configurations (.wxs files) and installer.qbs, but no dedicated GitHub Actions workflow validates Windows installer builds. Current workflows cover ubuntu.yml and macos-latest.yml, but Windows packaging is only in appveyor.yml (legacy). Adding a modern GitHub Actions workflow for Windows builds would catch installer regressions early and modernize the CI/CD pipeline.
- [ ] Create .github/workflows/windows-latest.yml following the pattern of existing ubuntu.yml and macos-latest.yml
- [ ] Configure Qt build environment for Windows MSVC/MinGW toolchain
- [ ] Add validation steps for WiX installer generation (dist/win/installer.wxs)
- [ ] Test the .qbs build system on Windows (dist/archive.qbs, dist/distribute.qbs)
- [ ] Add status badge to README.md alongside existing CI badges
Document translation workflow and maintainer guide in CONTRIBUTING.md
The repo has Transifex integration (.tx/config), translation directories (docs/locale/bg, docs/locale/de), and dist/update-translations.sh script, but CONTRIBUTING.md lacks specific guidance on adding translations or managing locale updates. New contributors wanting to help with translations have no documented process.
- [ ] Expand CONTRIBUTING.md with a 'Translations' section referencing .tx/config and Transifex setup
- [ ] Document the dist/update-translations.sh script's purpose and how to run it
- [ ] Explain the docs/locale/ directory structure and .po file workflow
- [ ] Link to Transifex project and explain how contributors can add new languages
- [ ] Document the Python dependencies (sphinx, docutils, myst-parser) needed for translation builds
Add CodeQL GitHub Action configuration for C++ and Python security scanning
The repo has .github/workflows/codeql-analysis.yml referenced but likely not fully configured for Tiled's mixed C++/Qt and Python stack (documentation, build scripts). Given the project's size and security-sensitive nature (level editor that loads arbitrary files), modern CodeQL analysis for C++ memory safety and Python injection vulnerabilities would catch regressions. The workflow file exists but may need language matrix expansion.
- [ ] Verify .github/workflows/codeql-analysis.yml and expand language matrix to include C++ (cpp) and Python
- [ ] Configure build command to properly invoke qbs or CMake for C++ compilation
- [ ] Add Python dependency scanning for docs/conf.py and dist/ scripts
- [ ] Test on a feature branch to validate CodeQL alerts don't overwhelm maintainers
- [ ] Document any CodeQL suppressions needed for legitimate Qt patterns in .codeqlignore or analysis settings
🌿Good first issues
- Add unit tests for libtiled Map class (src/libtiled/map.cpp). Currently there's no dedicated test file for core data structure operations (addLayer, addTileset, setProperty). Start by creating
tests/libtiled/maptest.cppwith basic CRUD tests.: Core functionality is under-tested; visible from sparsetests/directory. Low-risk change with high impact on stability. - Document the property system in docs/. Map/Layer/Tile/Object all support arbitrary key-value properties via
setProperty(), but there's no developer guide explaining how to access or persist custom properties. Add a section to docs/ with code examples.: File structure shows docs/ exists with Sphinx config but no property system docs; this is a common question for plugin authors. - Simplify the Windows build in dist/win/. Currently uses WiX (Windows Installer XML) which is XML-heavy and platform-specific. Investigate NSIS or MSI tooling that integrates better with Qt/Qbs, and document the migration path.: dist/win/ has multiple .wxs files (installer.wxs, Custom_InstallDir.wxs, Custom_InstallDirDlg.wxs)—this is complex; a simpler cross-platform approach would reduce maintenance burden.
⭐Top contributors
Click to expand
Top contributors
- @bjorn — 50 commits
- @dependabot[bot] — 8 commits
- @kunal649 — 6 commits
- @exoego — 5 commits
- @SIDDHAARTHAA — 4 commits
📝Recent commits
Click to expand
Recent commits
f511930— Bump timheuer/base64-to-file from 1 to 2 (#4516) (dependabot[bot])77fc9a2— Made indexes in the TilesetModel without tiles invalid (#4512) (bjorn)e48776a— fix(ci): replace third-party action with native brew bump-cask-pr command (#4478) (PoonamMehan)725993a— Added whitespace trimming for custom property names (#4486) (Praagya26)7144155— Fix point object bounding box in multi-object selections (#4401) (MollahHamza)c247b17— Fixed runtime language switching in many editor widgets and models (#4411) (SIDDHAARTHAA)5fac4aa— Fixed Tile Animation Editor update after tileset image reload (#4508) (bjorn)1fb0747— docs: Add pixi-tiledmap support details to documentation (#4499) (riebel)fef53ef— Fix locale-aware parsing of numbers in expression-capable spin boxes (#4507) (bjorn)d3b20fd— Merge pull request #4506 from mapeditor/fix-properties-updates-disabled (bjorn)
🔒Security observations
The Tiled Map Editor repository demonstrates a reasonably secure posture with modern CI/CD practices (GitHub Actions), multiple license compliance, and no obvious hardcoded secrets detected. However, security concerns include permissive dependency version ranges that could mask vulnerabilities, absence of a documented security policy, and deprecated CI configuration files. The lack of specific dependency pinning could lead to supply chain risks if a compromised minor version is released. For a production tool used by many developers, implementing stricter dependency management, adding a security.md policy, and establishing regular security audits would strengthen the security posture. No critical injection vulnerabilities or infrastructure misconfigurations are apparent from the file structure analysis.
- Medium · Permissive Sphinx Dependency Version Range —
Package dependencies - Sphinx >= 8, < 9. The Sphinx dependency is pinned to >= 8, < 9, which allows any minor and patch version within that range. This could include versions with unpatched security vulnerabilities if not actively monitored. Sphinx is a critical documentation build tool. Fix: Consider using more specific version pinning (e.g., Sphinx >= 8.0.2, < 8.1) and establish a process for regular dependency updates and security monitoring. - Medium · Broad docutils Version Range —
Package dependencies - docutils >= 0.20, < 0.22. docutils is pinned to >= 0.20, < 0.22, allowing wide version variation. docutils is fundamental for documentation processing and could contain vulnerabilities. The range spans potentially multiple minor versions. Fix: Tighten version constraints to specific patch versions after testing and implement automated security scanning for transitive dependencies. - Low · Missing Security Policy Documentation —
Repository root. No SECURITY.md or security policy file is evident in the file structure. This makes it unclear how security vulnerabilities should be reported, potentially delaying disclosure of critical issues. Fix: Create a SECURITY.md file following GitHub's security policy guidelines (https://docs.github.com/en/code-security/getting-started/adding-a-security-policy-to-your-repository). - Low · Public RSA Key in Distribution Files —
dist/dsa_pub.pem. The file dist/dsa_pub.pem contains a public DSA key committed to the repository. While public keys are intentionally public, storing them in the repo could be used for signature verification. Ensure this is the correct public key and no private keys are accidentally committed. Fix: Verify this is indeed a public key only. Implement pre-commit hooks to prevent accidental commits of private keys (e.g., using git-secrets or similar tools). - Low · Deprecated Travis CI Configuration —
.travis.yml. The .travis.yml file is present but Travis CI has been acquired and deprecated in favor of GitHub Actions. This configuration is likely not active and could cause confusion about the actual CI/CD pipeline. Fix: Remove .travis.yml and consolidate all CI/CD configuration to the GitHub Actions workflows in .github/workflows/. Document the active CI/CD pipeline. - Low · Multiple License Files —
LICENSE.APACHE, LICENSE.BSD, LICENSE.GPL, .LICENSE-HEADER. The repository contains multiple license files (LICENSE.APACHE, LICENSE.BSD, LICENSE.GPL) with a header template (.LICENSE-HEADER). While this is valid for multi-licensed projects, it should be clearly documented which license applies to which components. Fix: Add a LICENSING.md file that clearly explains which license applies to which parts of the codebase to avoid confusion and ensure proper compliance.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.