00-Evan/shattered-pixel-dungeon
Shattered Pixel Dungeon is an open-source traditional roguelike dungeon crawler with randomized levels and enemies, and hundreds of items to collect and use. It's based on the source code of Pixel Dungeon, by Watabou.
Solo project — review before adopting
weakest axiscopyleft license (GPL-3.0) — review compatibility; single-maintainer (no co-maintainers visible)…
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 7w ago
- ✓GPL-3.0 licensed
- ✓Tests present
Show all 6 evidence items →Show less
- ⚠Solo or near-solo (1 contributor active in recent commits)
- ⚠GPL-3.0 is copyleft — check downstream compatibility
- ⚠No CI workflows detected
What would change the summary?
- →Use as dependency Concerns → Mixed if: relicense under MIT/Apache-2.0 (rare for established libs)
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/00-evan/shattered-pixel-dungeon)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/00-evan/shattered-pixel-dungeon on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: 00-Evan/shattered-pixel-dungeon
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/00-Evan/shattered-pixel-dungeon 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 — Solo project — review before adopting
- Last commit 7w ago
- GPL-3.0 licensed
- Tests present
- ⚠ Solo or near-solo (1 contributor active in recent commits)
- ⚠ GPL-3.0 is copyleft — check downstream compatibility
- ⚠ No CI workflows detected
<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 00-Evan/shattered-pixel-dungeon
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/00-Evan/shattered-pixel-dungeon.
What it runs against: a local clone of 00-Evan/shattered-pixel-dungeon — 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 00-Evan/shattered-pixel-dungeon | Confirms the artifact applies here, not a fork |
| 2 | License is still GPL-3.0 | 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 ≤ 76 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of 00-Evan/shattered-pixel-dungeon. If you don't
# have one yet, run these first:
#
# git clone https://github.com/00-Evan/shattered-pixel-dungeon.git
# cd shattered-pixel-dungeon
#
# 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 00-Evan/shattered-pixel-dungeon and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "00-Evan/shattered-pixel-dungeon(\\.git)?\\b" \\
&& ok "origin remote is 00-Evan/shattered-pixel-dungeon" \\
|| miss "origin remote is not 00-Evan/shattered-pixel-dungeon (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
&& ok "license is GPL-3.0" \\
|| miss "license drift — was GPL-3.0 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 "SPD-classes/src/main/java/com/watabou/noosa/Game.java" \\
&& ok "SPD-classes/src/main/java/com/watabou/noosa/Game.java" \\
|| miss "missing critical file: SPD-classes/src/main/java/com/watabou/noosa/Game.java"
test -f "SPD-classes/src/main/java/com/watabou/noosa/Scene.java" \\
&& ok "SPD-classes/src/main/java/com/watabou/noosa/Scene.java" \\
|| miss "missing critical file: SPD-classes/src/main/java/com/watabou/noosa/Scene.java"
test -f "SPD-classes/src/main/java/com/watabou/noosa/Group.java" \\
&& ok "SPD-classes/src/main/java/com/watabou/noosa/Group.java" \\
|| miss "missing critical file: SPD-classes/src/main/java/com/watabou/noosa/Group.java"
test -f "SPD-classes/src/main/java/com/watabou/glwrap/Program.java" \\
&& ok "SPD-classes/src/main/java/com/watabou/glwrap/Program.java" \\
|| miss "missing critical file: SPD-classes/src/main/java/com/watabou/glwrap/Program.java"
test -f "SPD-classes/src/main/java/com/watabou/utils/Bundle.java" \\
&& ok "SPD-classes/src/main/java/com/watabou/utils/Bundle.java" \\
|| miss "missing critical file: SPD-classes/src/main/java/com/watabou/utils/Bundle.java"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 76 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~46d)"
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/00-Evan/shattered-pixel-dungeon"
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
Shattered Pixel Dungeon is an open-source Java-based roguelike dungeon crawler that generates randomized levels, enemies, and loot using procedural generation. It runs cross-platform (Android, iOS, Desktop) via LibGDX and provides hundreds of collectible items, character progression, and permadeath gameplay mechanics. The core engine sits in SPD-classes/ with rendering via custom OpenGL wrappers in com.watabou.glwrap and scene management through com.watabou.noosa. Monorepo structure: SPD-classes/ is the core library containing the Noosa game engine (com.watabou.noosa.* for scene/rendering), LibGDX wrappers, and OpenGL abstractions. Platform-specific entry points (Android, iOS, Desktop) import this library and add native platform code. Graphics pipeline: TextureCache.java → SmartTexture.java → Script.java shaders; input flows through InputHandler.java → GameAction.java → scene event dispatch.
👥Who it's for
Indie game developers learning roguelike architecture and procedural generation; mobile/desktop game players seeking a classic dungeon crawler; modders and port maintainers who fork the codebase to create variants (as the README explicitly invites). The project is read-only for contributions but open for study and redistribution.
🌱Maturity & risk
This is production-ready and actively maintained: the game has official releases on Google Play, App Store, Steam, and GOG with multi-year update history. However, the repo explicitly does not accept pull requests and serves primarily as reference code. The codebase is mature (~7MB of Java) but forward progress depends entirely on the single maintainer (00-Evan).
Single-maintainer risk is substantial—all active development flows through one person. Dependencies are minimal but outdated (org.json:json version 20170516 is from 2017 and is deliberately pinned to avoid Android crashes). No visible test suite in the file list and no CI configuration shown, raising quality assurance concerns for a game requiring careful balance tuning. The no-PR policy means community bug fixes cannot be merged upstream.
Active areas of work
Unable to determine from file list alone, but the project maintains regular releases and the README directs users to the official blog (ShatteredPixel.com) and Transifex translation project for active work. The codebase structure suggests ongoing content additions (new items, enemies, levels) rather than engine rewrites.
🚀Get running
Clone and build for desktop: git clone https://github.com/00-Evan/shattered-pixel-dungeon.git && cd shattered-pixel-dungeon && ./gradlew desktop:run (uses Gradle from the shell scripts). Consult /docs/getting-started-desktop.md for full setup. For Android: ./gradlew android:assembleDebug after Android SDK setup per /docs/getting-started-android.md.
Daily commands:
Desktop: ./gradlew desktop:run. Android emulator: ./gradlew android:installDebug && adb shell am start -n com.shatteredpixel.shatteredpixeldungeon/.com.watabou.glwrap.Game. See /docs/getting-started-*.md per platform.
🗺️Map of the codebase
SPD-classes/src/main/java/com/watabou/noosa/Game.java— Core game engine entry point and main loop; all contributors must understand the architecture for rendering, input, and scene managementSPD-classes/src/main/java/com/watabou/noosa/Scene.java— Base scene abstraction for all game states (dungeon, menus, etc.); required to implement new screens or gameplay statesSPD-classes/src/main/java/com/watabou/noosa/Group.java— Scene graph container for visual objects; fundamental to understanding UI and game object hierarchiesSPD-classes/src/main/java/com/watabou/glwrap/Program.java— OpenGL shader program abstraction; critical for rendering pipeline and visual effectsSPD-classes/src/main/java/com/watabou/utils/Bundle.java— Serialization framework for game state and item persistence; essential for save/load mechanicsSPD-classes/src/main/java/com/watabou/utils/Random.java— Seeded random number generator for deterministic dungeon generation and enemy spawningSPD-classes/build.gradle— LibGDX and core dependency declarations; defines baseline runtime environment for all platforms
🛠️How to make changes
Add a New Game Screen (Menu, Shop, Inventory)
- Create a new class extending Scene in your game-specific module (
SPD-classes/src/main/java/com/watabou/noosa/Scene.java) - Override create() to build the UI using Group and Component (buttons, text, etc.) (
SPD-classes/src/main/java/com/watabou/noosa/ui/Component.java) - Implement onKeyDown() or PointerArea callbacks for input handling (
SPD-classes/src/main/java/com/watabou/input/InputHandler.java) - Call Game.instance().switchScene(yourNewScene) to activate the screen (
SPD-classes/src/main/java/com/watabou/noosa/Game.java)
Add a New Serializable Game Entity (Item, Mob, Trap)
- Implement the Bundlable interface with storeInBundle() and restoreFromBundle() methods (
SPD-classes/src/main/java/com/watabou/utils/Bundlable.java) - Use Bundle.put() and Bundle.get() to persist fields as key-value pairs (
SPD-classes/src/main/java/com/watabou/utils/Bundle.java) - Register the class in the persistence layer for automatic save/load cycles (
SPD-classes/src/main/java/com/watabou/utils/FileUtils.java)
Add Visual Effects or Animations
- Create a new Visual subclass or use Emitter for particle effects (
SPD-classes/src/main/java/com/watabou/noosa/Visual.java) - Use Tweener subclasses (PosTweener, AlphaTweener, ScaleTweener) for smooth transitions (
SPD-classes/src/main/java/com/watabou/noosa/tweeners/Tweener.java) - Add the visual to the current scene's Group via scene.add() (
SPD-classes/src/main/java/com/watabou/noosa/Group.java) - Call Tweener.start() to animate over time in the game loop (
SPD-classes/src/main/java/com/watabou/noosa/Game.java)
Implement Procedural Dungeon Generation
- Use Random.seed() to deterministically initialize the RNG for reproducible dungeons (
SPD-classes/src/main/java/com/watabou/utils/Random.java) - Use PathFinder for connectivity and NPC placement within generated rooms (
SPD-classes/src/main/java/com/watabou/utils/PathFinder.java) - Use Point/Rect for grid-based room and corridor layout logic (
SPD-classes/src/main/java/com/watabou/utils/Point.java) - Render the dungeon as a Tilemap with camera control (
SPD-classes/src/main/java/com/watabou/noosa/Tilemap.java)
🔧Why these technologies
- LibGDX (gdx) — Cross-platform abstraction for rendering, audio, and input; enables single codebase for Android, iOS, Desktop, and Web
- OpenGL (glwrap, glscripts) — Hardware-accelerated 2D/3D graphics rendering with shader support; essential for performant dungeon visualization and effects
- GDX — undefined
🪤Traps & gotchas
Version pin quirk: org.json:json is deliberately pinned to 20170516 (5 years old) to prevent crashes on old Android versions—do not auto-upgrade. No tests: no visible test framework in the file structure; changes require manual playtesting. Platform fragmentation: same Java codebase compiled for Android, iOS, and Desktop via different build paths; a change to com.watabou.input can have wildly different behavior per platform depending on native event routing. Shader compilation: custom GLSL shaders in com.watabou.glscripts fail silently on some mobile GPU drivers; errors appear only at runtime. Asset loading: TextureCache is a global singleton—texture modifications during gameplay can leak memory if not properly disposed.
🏗️Architecture
💡Concepts to learn
- Texture Atlas Batching — SPD packs hundreds of sprite frames into atlases (managed by
TextureCache.javaandTextureFilm.java) to reduce GPU draw calls on mobile—essential for 60fps on constrained devices - Scene Graph — The
Scene→Group→Gizmohierarchy (com.watabou.noosa) implements a scene graph for efficient rendering and event propagation across UI and game layers - Procedural Dungeon Generation — Core roguelike mechanic: levels are generated algorithmically rather than hand-authored, providing infinite replayability; SPD's generation logic determines enemy placement, item distribution, and map layout
- OpenGL Shader Abstraction — Custom
Program.javaandShader.javawrappers around OpenGL ES 2.0 shaders enable platform-independent custom effects (lighting, color filters) without direct GL calls in game code - Input Event Abstraction — The
InputHandler→GameActionabstraction decouples gameplay logic from platform-specific input; same code works with touch, mouse, and controller without conditionals - Roguelike Permadeath & Save Systems — Unlike regular games, roguelikes design around permanent failure and procedural variety; SPD's dungeon generation combined with permadeath creates the core loop that prevents save-scumming
- Cross-Platform JVM Compilation — SPD compiles the same Java codebase for Android (Gradle), iOS (RoboVM/xmlvm), and Desktop (LWJGL) via Gradle; understanding platform-specific entry points is critical for engine modifications
🔗Related repos
watabou/PixelDungeon— The original Pixel Dungeon source code that Shattered Pixel Dungeon is forked from; shows the ancestor design00-Evan/pixel-dungeon-gradle— Earlier Gradle-based port of Pixel Dungeon by the same maintainer; direct predecessor to Shattered Pixel Dungeon's build systemlibgdx/libgdx— The underlying cross-platform game framework (Java/OpenGL) that Shattered Pixel Dungeon depends on; understanding LibGDX rendering is essential for graphics work herelibgdx/gdx-controllers— Gamepad/controller input abstraction used by Shattered Pixel Dungeon; relevant for extending input handling beyond keyboard/mouseadonthese/OpenRogue— Another Java-based roguelike using similar procedural generation patterns; useful reference for alternative dungeon generation algorithms
🪄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 unit tests for com.watabou.utils.BArray utility class
The BArray.java class in SPD-classes/src/main/java/com/watabou/utils/ appears to be a core utility for array operations, but there are no visible test files in the repository structure. Adding comprehensive unit tests would improve code reliability and make it easier for contributors to understand the expected behavior of this frequently-used utility. This is especially important for a roguelike with randomized levels that likely depends heavily on array manipulations.
- [ ] Create SPD-classes/src/test/java/com/watabou/utils/BArrayTest.java
- [ ] Add test cases covering initialization, insertion, deletion, and edge cases
- [ ] Verify tests run with gradle test and integrate into build pipeline
- [ ] Document expected behavior in test class javadoc comments
Add GitHub Actions workflow for multi-platform compilation verification
The README indicates the project compiles for Android, iOS, and Desktop platforms, but there's no visible CI workflow in the file structure to verify builds don't break across these targets. Adding a GitHub Actions workflow that runs gradle build for the SPD-classes module on push/PR would catch cross-platform regressions early and reduce friction for new contributors unfamiliar with the build process.
- [ ] Create .github/workflows/build.yml to run './gradlew build' on SPD-classes
- [ ] Configure matrix strategy to test on ubuntu-latest, macos-latest, and windows-latest
- [ ] Add step to validate that both Android and Desktop variant builds succeed
- [ ] Document build requirements and troubleshooting in CONTRIBUTING.md
Add input mapping documentation and validation for KeyBindings.java
The SPD-classes/src/main/java/com/watabou/input/KeyBindings.java file controls game input across mobile and desktop platforms, but there's no documented specification of supported key bindings or a validation mechanism. Adding structured documentation and a test class that validates key binding configurations would help contributors understand the input system and prevent invalid configurations from being accidentally committed.
- [ ] Create SPD-classes/src/main/java/com/watabou/input/KeyBindingsSpec.md documenting all valid GameAction enum values and their platform mappings
- [ ] Add validation method to KeyBindings.java that checks for conflicting bindings or unsupported actions
- [ ] Create SPD-classes/src/test/java/com/watabou/input/KeyBindingsTest.java with tests for binding conflicts and platform-specific requirements
- [ ] Reference spec in javadoc comments for KeyBindings class
🌿Good first issues
- Add unit tests for
com.watabou.gltextures.TextureCache.javato verify sprite atlas lookups and memory eviction—currently untested logic for a performance-critical component. - Document the custom input mapping layer (
com.watabou.input.*) with a guide explaining howGameActionenum values wire to platform-specific key/controller inputs, since cross-platform input handling is non-obvious. - Create example shader snippets in
/docsshowing how to write custom GLSL forcom.watabou.glscripts.Script.javasubclasses, since the shader system is powerful but undocumented.
📝Recent commits
Click to expand
Recent commits
7b8b845— v3.3.8: updated version for amended v3.3.8 release (00-Evan)09c1e2c— v3.3.8: updated declared languages in Android module (00-Evan)09eea4b— v3.3.8: fixed errors with full R8 usage (00-Evan)cb9ba85— v3.3.8: improved code and fixed crashes with new blob terrain flags logic (00-Evan)00a540a— v3.3.8: updated translations, version, and changelog for v3.3.8 release! (00-Evan)b692329— v3.3.8: fixed necromancers finishing summons if tiles become impassable (00-Evan)fde2353— v3.3.8: improved logic for blobs and terrain changes on tile flags (00-Evan)3f7543f— v3.3.8: enabled R8 full mode (00-Evan)5a3d0fb— v3.3.8: updated AGP, gradle, and target/compile SDK (00-Evan)b030dc9— v3.3.8: fixed a bad reference in MissileWeapon that could rarely crash (00-Evan)
🔒Security observations
Shattered Pixel Dungeon has moderate security concerns centered on outdated dependencies, particularly the 6+ year old org.json library. While the codebase appears to be primarily game logic without typical web vulnerabilities (SQLi, XSS), the reliance on older libraries and lack of visible security scanning infrastructure creates risk. The project's note about using an outdated JSON library for Android compatibility suggests a conscious trade-off, but this should be actively monitored. No critical infrastructure or credential issues are evident from the available file structure. Primary recommendations: update dependencies where possible, implement automated security scanning in the build process, and conduct a security audit of input handling code.
- High · Outdated JSON Library with Known Vulnerabilities —
SPD-classes/build.gradle - org.json:json:20170516. The project uses org.json:json:20170516, which was released in May 2017 and contains multiple known security vulnerabilities. This is an extremely outdated version (over 6 years old at time of analysis). The dependency comment acknowledges this is intentional for Android compatibility, but this creates significant risk. Fix: Update to the latest stable version of org.json that maintains Android compatibility. If Android 5.0 compatibility is required, consider upgrading the minimum API level or using a security patch. At minimum, document and monitor for CVEs affecting this specific version. - High · Outdated LibGDX Dependency —
SPD-classes/build.gradle - com.badlogicgames.gdx:* dependencies. The project uses LibGDX (gdx and gdx-controllers) via variable references ($gdxVersion). Without visibility into the actual version used, there is risk of using outdated versions with known vulnerabilities. LibGDX is a core graphics framework handling user input and rendering. Fix: Verify and document the specific $gdxVersion being used. Ensure it is a recent stable version with security patches applied. Implement dependency vulnerability scanning in CI/CD pipeline. - Medium · Potential Input Handling Vulnerabilities —
SPD-classes/src/main/java/com/watabou/noosa/TextInput.java and SPD-classes/src/main/java/com/watabou/input/*. The project includes TextInput.java and multiple input handling classes (KeyBindings.java, PointerEvent.java, etc.) without visible sanitization or validation logic in the file structure. Game engines processing user input can be vulnerable to buffer overflows or injection attacks if input is not properly validated. Fix: Review input handling code to ensure all user input is validated and sanitized. Implement length limits, character whitelisting, and bounds checking. Pay special attention to keyboard and controller input processing. - Medium · Freetype Font Rendering Library Exposure —
SPD-classes/build.gradle - com.badlogicgames.gdx:gdx-freetype:$gdxVersion. The project includes gdx-freetype for font rendering. Font parsing libraries have historically been targets for exploitation. External font files could potentially be used to trigger buffer overflows or other memory safety issues. Fix: Keep gdx-freetype updated to the latest stable version. Validate font files before loading them. Consider restricting font loading to trusted sources only. Monitor for font parsing vulnerabilities in Freetype. - Medium · No Visible Security Configuration or Static Analysis —
SPD-classes/build.gradle. There is no evidence of security-related Gradle plugins, OWASP dependency checks, or static analysis tools (like SpotBugs, FindSecBugs) configured in the build process. This lack of automated security scanning increases the risk of introducing vulnerabilities. Fix: Add security scanning plugins to the Gradle build: OWASP Dependency-Check, SpotBugs with FindSecBugs plugin, and Checkstyle. Enable dependency vulnerability scanning and fail builds on detected issues above a threshold. - Low · Missing or Limited Security Headers in Documentation —
README.md and repository root. The README and visible configuration files do not document security practices, vulnerability disclosure policy, or security update procedures. This is common for game projects but represents a gap in security governance. Fix: Add a SECURITY.md file documenting vulnerability disclosure process. Include security considerations in README. Consider adding CONTRIBUTING.md with security guidelines for contributors.
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.