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

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

Text and Localization

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

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

Level Structure

Object Types

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

File Organization

Testing and Debugging

Community Resources

With these techniques, you can create extensive modifications to Remixed Dungeon without writing a single line of Java code!