User Tools

Site Tools


rpd:modding_non_java_techniques

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.json with 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 target
  • RPD.permanentBuff(target, buffClass) - Apply a permanent buff to a target
  • RPD.removeBuff(target, buffClass) - Remove a buff from a target
  • RPD.glog(message) - Display a message in game log
  • RPD.spawnMob(className, cell, mobDesc) - Create a new mob at a cell location
  • RPD.item(itemClass, quantity) - Create an item
  • RPD.GameAction - Check if currently in game (not in menu)
  • RPD.GameLoop.currentTurn - Current turn count
  • RPD.Dungeon.level() - Current level object
  • RPD.Dungeon.hero - Player character
  • RPD.Dungeon.level():mobs() - All mobs on current level
  • RPD.Dungeon.level():cell(x, y) - Cell at coordinate
  • RPD.Dungeon.level():distance(pos1, pos2) - Distance between positions
  • RPD.Terrain.WALL, RPD.Terrain.EMPTY, etc. - Terrain constants
  • RPD.Blobs.Fire, RPD.Blobs.Water, etc. - Environmental effects
  • math.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

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 location
  • item_spawn - Places an item at the location
  • exit - Level exit point
  • entrance - Level entrance point
  • feature - 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!

rpd/modding_non_java_techniques.txt · Last modified: by 127.0.0.1