Table of Contents

Non-Java Modding Quick Reference

This quick reference guide covers the most common modding tasks you can accomplish without Java coding in Remixed Dungeon.

Common File Locations

For Mods

Important Files

Resource Overrides

Replace a Sprite

1. Find original sprite in game assets

2. Create your new sprite in the same format/dimensions

3. Place in matching directory in your mod:

YourMod/
└── sprites/
    └── items/
        └── weapon.png (replaces original weapon sprites)

Configure Custom Sprite Animations

Sprites can be configured using JSON files in spritesDesc/ directory. For example, SpiderElite sprite configuration:

{
  "texture": "spiders.png",
  "width": 16,
  "height": 16,
  "shadow": 0.1,
  "idle": { "fps": 5, "looped": true, "frames": [0, 0, 0, 0, 0, 0, 1, 1] },
  "run": { "fps": 15, "looped": true, "frames": [2, 3, 4, 5] },
  "attack": { "fps": 15, "looped": false, "frames": [6, 7, 8, 6] },
  "die": { "fps": 10, "looped": false, "frames": [9, 10, 11] }
}

Replace Sound

YourMod/
└── sounds/
    └── your_sound.wav (use same filename as original)

Replace Music

YourMod/
└── music/
    └── your_track.ogg (use same filename as original)

JSON Configuration Changes

Change Item Stats

Create items/weapon/short_sword.json in your mod:

{
  "class": "com.watabou.pixeldungeon.items.weapon.melee.ShortSword",
  "damageMin": 6,  // Increased from default
  "damageMax": 12, // Increased from default
  "name:en": "Enhanced Short Sword"
}

Change Mob Stats

Create actors/mobs/rat.json in your mod:

{
  "class": "com.watabou.pixeldungeon.actors.mobs.Rat",
  "HP": 20,        // Increased from default
  "damageMin": 8,  // Increased from default
  "exp": 4         // Increased from default
}

Create Custom Mobs with JSON Configuration

Mobs can be configured using JSON files in mobsDesc/ directory. For example, SpiderElite configuration:

{
   "class"         :"com.nyrds.pixeldungeon.mobs.common.MultiKindMob",
   "HP"            :[15, 17, 19],
   "exp"           :[3, 4],
   "maxLvl"        :10,
   "dmgMin"        :[5, 6, 7],
   "dmgMax"        :[10, 12, 15],
   "name"          :"SpiderElite_Name",
   "name_objective":"SpiderElite_Name_Objective",
   "description"   :"SpiderElite_Desc",
   "gender"        :"SpiderElite_Gender",
   "spriteDesc"    :"spritesDesc/SpiderElite.json",
   "scriptFile"    :"scripts/mobs/SpiderElite"
}

Add New Text

Create res/values/strings.json in your mod:

{
  "CustomMessage": "This is my custom message!",
  "NewItemName": "Legendary Sword of Awesomeness",
  "NewItemDesc": "This sword is incredibly awesome."
}

Configure Mob Spawning

Mobs can be configured to spawn in specific levels using levelsDesc/Bestiary.json. For example, Spider Nest configuration:

{
  "8s":{"SpiderServant":1,"SpiderExploding":0.5,"SpiderMind":0.2,"SpiderGuard":0.03,"SpiderMindAmber":0.006},
  "9s":{"SpiderServant":1,"SpiderExploding":1,"SpiderMind":0.3,"SpiderGuard":0.03,"SpiderMindAmber":0.012},
  "10s":{"SpiderServant":1,"SpiderExploding":1,"SpiderMind":0.5,"SpiderGuard":0.3, "SpiderElite":0.3 ,"SpiderMindAmber":0.018}
}

Common Lua Functions

Damage Functions

Summoning Functions

Effect Functions

Information Functions

Simple Custom Item (Complete Example)

1. Create the item JSON

items/weapon/ice_wand.json:

{
  "class": "com.watabou.pixeldungeon.items.weapon.missiles.MissileWeapon",
  "name:en": "Ice Wand",
  "desc:en": "A wand that shoots ice bolts. Freezes enemies temporarily.",
  "imageIndex": 25,
  "damageMin": 3,
  "damageMax": 7,
  "AC": "ZAP",
  "script": "items/ice_wand.lua",
  "onZap": "freezeBolt"
}

2. Create the Lua script

items/ice_wand.lua:

local RPD = require "scripts/lib/commonClasses"
local item = require "scripts/lib/item"
 
return item.init{
    desc = function()
        return {
            image         = 25,
            imageFile     = "items.png",
            name          = "Ice Wand",
            info          = "A wand that shoots ice bolts. Freezes enemies temporarily.",
            stackable     = false,
            upgradable    = true,
            isFlies       = false,
            defaultAction = "ZAP"
        }
    end,
 
    actions = function()
        return {RPD.Actions.ZAP}
    end,
 
    execute = function(self, item, hero, action)
        if action == RPD.Actions.ZAP then
            -- Find mob at target location
            local level = RPD.Dungeon.level()
            local allMobs = level:mobs()
            local target = nil
 
            for i = 0, allMobs:size()-1 do
                local mob = allMobs:get(i)
                if mob:getPos() == hero:getPos() then -- Simplified example - would need actual targeting
                    target = mob
                    break
                end
            end
 
            if target then
                -- Deal damage
                target:damage(5, hero)  -- Damage target, source is hero
                -- Freeze for 3 turns - using paralysis as an example
                RPD.affectBuff(target, RPD.Buffs.Paralysis, 3)
                RPD.glog("The ice bolt freezes " .. target:name() .. "!")
                -- Visual effect
                RPD.topEffect(target:getPos(), "ice")
            end
        end
    end
}

3. Add to your mod's version.json

{
  "version": 1,
  "name": "My Ice Mod",
  "author": "Your Name"
}

Common Modding Patterns

Equipment with On-Equip Effects

{
  "class": "com.watabou.pixeldungeon.items.armor.Armor",
  "onEquip": "equipEffect",
  "onUnequip": "unequipEffect"
}

function M.equipEffect(item, hero)
    -- In practice, you would use different mechanics as properties may not work this way
    RPD.glog("You feel protected from flames!")
end
 
function M.unequipEffect(item, hero)
    RPD.glog("Your fire protection fades.")
end

Mobs that Summon Others

function M.onTurn(mob)
    if math.random() < 0.1 then  -- 10% chance per turn
        local mobPos = mob:getPos()
        local summonPos = nil
        -- Find an empty adjacent cell
        local level = RPD.Dungeon.level()
        for direction = 0, 7 do
            local adjCell = mobPos + RPD.PathFinder.CIRCLE8[direction + 1]
            if level:cellValid(adjCell) and
               level:passable:adjCell(adjCell) and
               level:freeCell(adjCell) then
                summonPos = adjCell
                break
            end
        end
 
        if summonPos then
            local rat = RPD.spawnMob("Rat", summonPos, {})
            RPD.glog(mob:name() .. " summons help!")
        end
    end
end

Mobs with Special Attack Effects

Mobs can have special effects during attacks, similar to how SpiderElite applies the Vertigo debuff:

function M.attackProc(self, enemy, dmg)
    -- 20% chance to apply Vertigo effect (disorientation)
    if math.random() < 0.2 then
        RPD.affectBuff(enemy, "Vertigo", self:skillLevel())
    end
end

Items that Change Terrain

function M.useItem(item, cell)
    -- Change terrain at target location
    local level = RPD.Dungeon.level()
    level:set(cell.x, cell.y, RPD.Terrain.CHASM)
    RPD.glog("The ground opens up!")
end

Testing Checklist

Before releasing your mod:

Troubleshooting Common Issues

Mod Not Loading

Lua Scripts Not Working

Items/Mobs Not Appearing

This quick reference should help you tackle most non-Java modding tasks in Remixed Dungeon!