Table of Contents
Non-Java Modding Techniques
Remixed Dungeon provides extensive modding capabilities without requiring Java programming knowledge. This guide covers all the non-Java modding techniques you can use to create modifications.
Resource Override Modding
The simplest type of modding involves replacing game resources directly.
Sprite Replacement
- Locate original sprites in the assets directory
- Create new sprites with the same dimensions and format
- Place them in the same directory structure in your mod folder
Example directory structure:
MyMod/ ├── sprites/ │ ├── items/ │ │ ├── weapon/ │ │ │ ├── sword.png (your custom sword sprite) │ │ │ └── dagger.png (your custom dagger sprite) │ │ └── armor/ │ │ └── armor.png (your custom armor sprite) │ └── mobs/ │ └── rat.png (your custom rat sprite) └── version.json
Sound and Music Replacement
- Replace sound effects by placing new files in
sounds/directory - Replace background music by placing new files in
music/directory - Keep the same filenames to ensure the game loads your replacements
Text and Localization
- Modify game text by creating
res/values/strings.jsonwith string overrides - Add new languages by creating
res/values-[lang-code]/strings.json - Format:
{"original_key": "your_new_text"}
JSON-Based Modding
JSON files control most game content and mechanics in Remixed Dungeon.
Item Modding
Create custom items by defining them in JSON files:
{
"class": "com.watabou.pixeldungeon.items.weapon.melee.Sword",
"name:en": "Flaming Sword",
"name:ru": "Пылающий меч",
"desc:en": "This sword is engulfed in magical flames that burn enemies.",
"desc:ru": "Этот меч окутан магическим пламенем, которое сжигает врагов.",
"damageMin": 8,
"damageMax": 15,
"imageIndex": 5,
"AC": "ATTACK",
"script": "items/flaming_sword.lua",
"onHit": "onHit"
}
Mob Modding
Create or modify creatures:
{
"class": "com.watabou.pixeldungeon.actors.mobs.Rat",
"name:en": "Fire Rat",
"HP": 20,
"damageMin": 5,
"damageMax": 10,
"defenseSkill": 5,
"exp": 3,
"loot": "gold",
"lootChance": 0.5,
"properties": ["hostile", "small"],
"onDeath": "fire_explosion",
"imageIndex": 3
}
Level Modding
Design custom levels using JSON:
{
"name": "Custom Level",
"width": 32,
"height": 32,
"map": [
"################################",
"#..............................#",
"#..............................#",
"################################"
],
"mobs": [
{
"class": "com.watabou.pixeldungeon.actors.mobs.Rat",
"x": 10,
"y": 10
}
],
"items": [
{
"class": "com.watabou.pixeldungeon.items.Gold",
"x": 15,
"y": 15,
"quantity": 50
}
]
}
Dungeon Structure
Modify how levels connect by editing levelsDesc/Dungeon.json:
{
"connections": [
{"from": 1, "to": 2},
{"from": 2, "to": 3}
],
"branches": [
{"level": 3, "branch": "sewers"}
]
}
Lua Scripting
Lua scripts provide dynamic behavior without Java coding.
Basic Lua Structure
local RPD = require "scripts/lib/commonClasses" local item = require "scripts/lib/item" local M = {} return item.init{ desc = function() return { image = 0, imageFile = "items.png", name = "Custom Item Name", info = "Custom Item Description", stackable = false, upgradable = true, isFlies = false, defaultAction = "Custom Action Name" } end, -- Function that can be called from JSON execute = function(self, item, hero, action) if action == "Custom Action Name" then -- Add fire damage RPD.affectBuff(hero, RPD.Buffs.Burning, 3) -- Apply burn for 3 turns RPD.glog("The item burns you!") end end }
Correct Lua Functions
target:damage(amount, source)- Deal damage to a target (e.g., victim:damage(10, caster))target:heal(amount, source)- Heal a target (e.g., target:heal(5, caster))RPD.affectBuff(target, buffClass, duration)- Apply a buff/debuff to a targetRPD.permanentBuff(target, buffClass)- Apply a permanent buff to a targetRPD.removeBuff(target, buffClass)- Remove a buff from a targetRPD.glog(message)- Display a message in game logRPD.spawnMob(className, cell, mobDesc)- Create a new mob at a cell locationRPD.item(itemClass, quantity)- Create an itemRPD.GameAction- Check if currently in game (not in menu)RPD.GameLoop.currentTurn- Current turn countRPD.Dungeon.level()- Current level objectRPD.Dungeon.hero- Player characterRPD.Dungeon.level():mobs()- All mobs on current levelRPD.Dungeon.level():cell(x, y)- Cell at coordinateRPD.Dungeon.level():distance(pos1, pos2)- Distance between positionsRPD.Terrain.WALL,RPD.Terrain.EMPTY, etc. - Terrain constantsRPD.Blobs.Fire,RPD.Blobs.Water, etc. - Environmental effectsmath.random()- Generate random number (use instead of G.chance())
Item Scripts
local RPD = require "scripts/lib/commonClasses" local item = require "scripts/lib/item" return item.init{ desc = function() return { image = 1, imageFile = "items.png", name = "Explosive Item", info = "An explosive item that damages enemies.", stackable = false, upgradable = false, isFlies = true, defaultAction = "EXPLODE" } end, actions = function() return {RPD.Actions.EXPLODE} end, -- Called when item is used execute = function(self, item, hero, action) if action == RPD.Actions.EXPLODE then local level = RPD.Dungeon.level() local cell = hero:getPos() -- Damage all creatures in radius local mobs = level:mobs() for i = 0, mobs:size()-1 do local mob = mobs:get(i) if level:distance(mob:getPos(), cell) <= 2 then mob:damage(10, hero) -- Damage mob, source is hero RPD.glog("Explosion damages " .. mob:name() .. "!") end end -- Also damage the hero slightly hero:damage(5, item) -- Source is item itself RPD.glog("The explosion hurts you too!") end end }
Mob Scripts
local RPD = require "scripts/lib/commonClasses" local mob = require "scripts/lib/mob" return mob.init{ spawn = function(self, level) -- Called when the mob is created RPD.glog("A healing mob appears!") end, act = function(self) -- Called each turn when mob is active local hero = RPD.Dungeon.hero local distance = RPD.Dungeon.level():distance(self:getPos(), hero:getPos()) if distance <= 2 then -- Heal the mob self:heal(5, self) -- Heal 5 HP, source is mob itself RPD.glog("The healing mob glows softly!") end -- Spend time for this turn self:spend(1) end, -- Called when mob is attacked onAttackProc = function(self, enemy, damage) -- Chance to counter-attack if math.random() < 0.3 then -- 30% chance enemy:damage(5, self) -- Damage attacker, source is this mob end return damage end, die = function(self, cause) -- Handle death RPD.glog("The healing mob fades away.") end }
Buff Scripts
local RPD = require "scripts/lib/commonClasses" local buff = require "scripts/lib/buff" return buff.init{ desc = function() return { icon = 10, name = "Custom Buff Name", info = "Custom buff description with %d turns remaining." } end, attach = function(self, target) -- Called when buff is applied RPD.glog("You feel different...") return true end, act = function(self) -- Called each turn while buff is active if math.random() < 0.1 then -- 10% chance per turn self.target:heal(1, self.target) -- Heal 1 HP occasionally, source is target itself end -- Continue for another turn return true end, detach = function(self) -- Called when buff is removed RPD.glog("The effect fades...") end }
Tiled Level Editor
Create complex custom levels using the Tiled map editor:
Getting Tiled
- Download Tiled from https://www.mapeditor.org/
- Use the custom Tiled extension provided with Remixed Dungeon
Level Structure
- Create a new tilemap with the correct dimensions
- Use the original tilesets as a base or create new ones
- Place special objects for spawns, items, and exits
- Export as JSON format for use in the game
Object Types
mob_spawn- Places a mob at the locationitem_spawn- Places an item at the locationexit- Level exit pointentrance- Level entrance pointfeature- Special level features
Configuration Files
version.json
{
"version": 1,
"name": "My Mod",
"author": "Your Name",
"description": "A brief description of your mod",
"requiredCoreVersion": "32.0",
"dependencies": ["required_mod_name"]
}
Bestiary Configuration
Control what mobs appear where:
{
"level_1": [
{"class": "com.watabou.pixeldungeon.actors.mobs.Rat", "weight": 10},
{"class": "com.watabou.pixeldungeon.actors.mobs.Gnoll", "weight": 5}
],
"level_5": [
{"class": "com.watabou.pixeldungeon.actors.mobs.Swarm", "weight": 8},
{"class": "com.watabou.pixeldungeon.actors.mobs.Eye", "weight": 3}
]
}
Tips for Successful Non-Java Modding
Planning Your Mod
- Start with simple resource swaps before moving to complex JSON configurations
- Look at existing game files as examples for your own
- Test frequently to avoid accumulating errors
- Keep backups of working configurations
File Organization
- Follow the same directory structure as the original game
- Use clear, descriptive names for your files
- Group related content in subdirectories
- Document complex mods with a README file
Testing and Debugging
- Enable your mod in-game and start a new game to test
- Check the game's log files for errors if something doesn't work
- Test on multiple save files to ensure compatibility
- Use simple test cases before implementing complex features
Community Resources
- Share your work on the Remixed Dungeon Discord server
- Look at other mod authors' work for inspiration and techniques
- Collaborate with other modders for complex projects
- Report bugs or request features through the official channels
With these techniques, you can create extensive modifications to Remixed Dungeon without writing a single line of Java code!
