Skip to main content

Overview

The spawn management system handles NPC spawning, respawning, territory-based spawning, and spawn data persistence in L2J Mobius Chronicle 4. Key Classes:
  • org.l2jmobius.gameserver.model.Spawn - Individual spawn instance
  • org.l2jmobius.gameserver.data.xml.SpawnData - XML spawn loader (singleton)
  • org.l2jmobius.gameserver.data.SpawnTable - Central spawn registry (singleton)
  • org.l2jmobius.gameserver.managers.DayNightSpawnManager - Day/night spawn control

Spawn Class

Location: org.l2jmobius.gameserver.model.Spawn Represents a single NPC spawn point with respawn mechanics.

Constructor

// By template
public Spawn(NpcTemplate template) throws ClassNotFoundException, NoSuchMethodException

// By NPC ID
public Spawn(int npcId) throws ClassNotFoundException, NoSuchMethodException
Example:
Spawn spawn = new Spawn(20001); // Orc Fighter
spawn.setXYZ(-84080, 243298, -3728);
spawn.setAmount(5);
spawn.setRespawnDelay(60); // 60 seconds
spawn.init();

Core Properties

_maximumCount
int
Maximum number of NPCs this spawn manages.
public void setAmount(int amount)
public int getAmount()
_currentCount
int
Current number of spawned NPCs (read-only).
_respawnMinDelay
int
Minimum respawn delay in milliseconds.
public int getRespawnMinDelay()
_respawnMaxDelay
int
Maximum respawn delay in milliseconds.
public int getRespawnMaxDelay()
_doRespawn
boolean
Whether automatic respawning is enabled.
public boolean isRespawnEnabled()
public void stopRespawn()
public void startRespawn()

Key Methods

Initialization

init
int
Initializes the spawn and creates all NPCs.
public int init()
Process:
  1. Spawns NPCs until _currentCount reaches _maximumCount
  2. Sets _doRespawn based on respawn delay (enabled if > 0)
Returns: Number of NPCs spawned
doSpawn
Npc
Spawns a single NPC instance.
public Npc doSpawn()
public Npc doSpawn(boolean isSummonSpawn)
Parameters:
  • isSummonSpawn - If true, shows summon animation
Returns: Spawned Npc instance or null on failureProcess:
  1. Creates NPC from template using reflection
  2. Sets instance ID
  3. Calculates spawn position (random if territory-based)
  4. Corrects Z coordinate using GeoEngine
  5. Sets HP/MP to maximum
  6. Sets random or fixed heading
  7. Spawns NPC into world
  8. Increments _currentCount

Respawn Control

decreaseCount
void
Handles NPC death and schedules respawn.
public void decreaseCount(Npc oldNpc)
Process:
  1. Decrements _currentCount
  2. Removes NPC from spawn list
  3. If respawn enabled and under max count:
    • Increments _scheduledCount
    • Schedules respawn via RespawnTaskManager
    • Uses random delay if _respawnMaxDelay differs from _respawnMinDelay
respawnNpc
void
Immediately respawns an NPC.
public void respawnNpc(Npc oldNpc)
Reinitializes the NPC at spawn location (used by RespawnTaskManager).

Location Management

setXYZ
void
Sets spawn coordinates (inherited from Location).
public void setXYZ(int x, int y, int z)
setLocation
void
Sets spawn location from Location object.
public void setLocation(Location loc)
setSpawnTerritory
void
Sets spawn territory for random position spawning.
public void setSpawnTerritory(NpcSpawnTerritory territory)
When territory is set, NPCs spawn at random positions within the territory boundaries.
isTerritoryBased
boolean
Checks if spawn uses territory-based positioning.
public boolean isTerritoryBased()
Returns: true if territory is set and X/Y coordinates are 0

Respawn Timing

setRespawnDelay
void
Sets respawn delay with optional randomization.
public void setRespawnDelay(int delay)
public void setRespawnDelay(int delay, int randomInterval)
Parameters:
  • delay - Base respawn delay in seconds
  • randomInterval - Random variance in seconds (±)
Example:
spawn.setRespawnDelay(60, 20);
// Respawns between 40-80 seconds
Converted to milliseconds internally:
  • _respawnMinDelay = (delay - randomInterval) * 1000
  • _respawnMaxDelay = (delay + randomInterval) * 1000
getRespawnDelay
int
Gets average respawn delay.
public int getRespawnDelay()
Returns: Average of min and max delays in milliseconds
hasRespawnRandom
boolean
Checks if respawn has random component.
public boolean hasRespawnRandom()

Other Properties

setChaseRange
void
Sets maximum chase distance for monsters.
public void setChaseRange(int chaseRange)
public int getChaseRange()
NPCs won’t pursue targets beyond this range from spawn point.
setRandomWalking
void
Enables/disables random walking.
public void setRandomWalking(boolean value)
public boolean getRandomWalking()
setName
void
Sets spawn identifier name.
public void setName(String name)
public String getName()

Spawned NPC Tracking

getSpawnedNpcs
Deque<Npc>
Gets all NPCs currently spawned by this spawn.
public Deque<Npc> getSpawnedNpcs()
Returns: Thread-safe deque of spawned NPCs
getLastSpawn
Npc
Gets the most recently spawned NPC.
public Npc getLastSpawn()

SpawnData

Location: org.l2jmobius.gameserver.data.xml.SpawnData Loads and manages NPC spawns from XML files.

Singleton Pattern

SpawnData spawnData = SpawnData.getInstance();

XML Spawn Format

File Location: data/spawns/
<?xml version="1.0" encoding="UTF-8"?>
<list enabled="true">
    <spawn name="town_gludio">
        <!-- Fixed position spawn -->
        <npc id="30001" x="-80826" y="149775" z="-3043" 
             heading="0" respawnDelay="60" />
        
        <!-- Multiple count spawn -->
        <npc id="20001" count="5" x="-84080" y="243298" z="-3728"
             respawnDelay="300" respawnRandom="60" />
        
        <!-- Territory-based spawn -->
        <territory shape="NPoly" minZ="-4000" maxZ="-3000">
            <node x="-85000" y="240000" />
            <node x="-83000" y="240000" />
            <node x="-83000" y="245000" />
            <node x="-85000" y="245000" />
        </territory>
        
        <npc id="20002" count="10" zone="town_gludio" 
             respawnDelay="180" />
        
        <!-- Day/night spawn -->
        <npc id="20010" x="-80000" y="150000" z="-3000"
             periodOfDay="night" respawnDelay="60" />
        
        <!-- Custom AI parameters -->
        <AIData>
            <disableRandomWalk>true</disableRandomWalk>
            <disableRandomAnimation>true</disableRandomAnimation>
        </AIData>
        <npc id="30100" x="-80000" y="150000" z="-3000" />
    </spawn>
</list>

Key Methods

addNewSpawn
void
Adds a new spawn and persists to XML.
public synchronized void addNewSpawn(Spawn spawn)
Process:
  1. Adds to SpawnTable
  2. Determines XML file based on world tile coordinates
  3. Appends spawn entry to existing file or creates new one
  4. Creates directory data/spawns/Others/ if needed
deleteSpawn
void
Removes spawn from table and XML file.
public synchronized void deleteSpawn(Spawn spawn)
Process:
  1. Removes from SpawnTable
  2. Locates XML file
  3. Removes matching spawn entry
  4. Deletes file if it becomes empty
getSpawnFile
String
Gets the XML file path for a spawn template ID.
public String getSpawnFile(int templateId)

Territory Shapes

Supported Shapes:
  1. NPoly - N-sided polygon (3+ vertices)
    <territory shape="NPoly" minZ="-4000" maxZ="-3000">
        <node x="-85000" y="240000" />
        <node x="-83000" y="240000" />
        <node x="-83000" y="245000" />
    </territory>
    
  2. Cuboid - Rectangular box (2 vertices)
    <territory shape="Cuboid" minZ="-4000" maxZ="-3000">
        <node x="-85000" y="240000" />
        <node x="-83000" y="245000" />
    </territory>
    
  3. Cylinder - Circular area (1 center point + radius)
    <territory shape="Cylinder" minZ="-4000" maxZ="-3000" rad="1000">
        <node x="-84000" y="242500" />
    </territory>
    

Banned Territories

Exclude areas within spawn territories:
<spawn name="hunting_ground" zone="forest_area">
    <territory shape="NPoly" minZ="-4000" maxZ="-3000">
        <!-- Main spawn area -->
        <node x="-90000" y="240000" />
        <node x="-80000" y="240000" />
        <node x="-80000" y="250000" />
        <node x="-90000" y="250000" />
    </territory>
    
    <banned_territory shape="Cylinder" minZ="-4000" maxZ="-3000" rad="500">
        <!-- Don't spawn near this point -->
        <node x="-85000" y="245000" />
    </banned_territory>
    
    <npc id="20001" count="20" zone="forest_area" />
</spawn>

SpawnTable

Location: org.l2jmobius.gameserver.data.SpawnTable Central registry for all active spawns.

Singleton Pattern

SpawnTable spawnTable = SpawnTable.getInstance();

Key Methods

getSpawnTable
Map<Integer, Set<Spawn>>
Gets complete spawn table.
public Map<Integer, Set<Spawn>> getSpawnTable()
Returns: Map of NPC ID → Set of spawns
getSpawns
Set<Spawn>
Gets all spawns for an NPC ID.
public Set<Spawn> getSpawns(int npcId)
Returns: Set of spawns or empty set if none
getSpawnCount
int
Counts spawns for an NPC.
public int getSpawnCount(int npcId)
getAnySpawn
Spawn
Gets any spawn for an NPC ID.
public Spawn getAnySpawn(int npcId)
Returns: First spawn found or null
addSpawn
void
Registers a spawn.
public void addSpawn(Spawn spawn)
Creates new spawn set if needed (thread-safe).
removeSpawn
void
Unregisters a spawn.
public void removeSpawn(Spawn spawn)
Removes spawn set if it becomes empty.

Usage Examples

Create and Initialize Spawn

try {
    // Create spawn for Orc Fighter (20001)
    Spawn spawn = new Spawn(20001);
    
    // Set location
    spawn.setXYZ(-84080, 243298, -3728);
    spawn.setHeading(0);
    
    // Configure spawn behavior
    spawn.setAmount(5); // Spawn 5 NPCs
    spawn.setRespawnDelay(300, 60); // 240-360 seconds
    spawn.setRandomWalking(true);
    spawn.setChaseRange(1000);
    
    // Initialize and spawn NPCs
    int spawned = spawn.init();
    System.out.println("Spawned " + spawned + " NPCs");
    
} catch (Exception e) {
    e.printStackTrace();
}

Territory-Based Spawning

try {
    Spawn spawn = new Spawn(20002);
    
    // Create spawn territory
    NpcSpawnTerritory territory = ZoneManager.getInstance()
        .getSpawnTerritory("hunting_ground_1");
    
    spawn.setSpawnTerritory(territory);
    spawn.setAmount(10);
    spawn.setRespawnDelay(180);
    
    spawn.init(); // Spawns at random positions in territory
    
} catch (Exception e) {
    e.printStackTrace();
}

Day/Night Spawns

try {
    Spawn nightSpawn = new Spawn(20010); // Night monster
    nightSpawn.setXYZ(-80000, 150000, -3000);
    nightSpawn.setRespawnDelay(60);
    
    // Register as night creature (don't init directly)
    DayNightSpawnManager.getInstance().addNightCreature(nightSpawn);
    
    // Create day spawn
    Spawn daySpawn = new Spawn(20011); // Day monster
    daySpawn.setXYZ(-80000, 150000, -3000);
    daySpawn.setRespawnDelay(60);
    
    DayNightSpawnManager.getInstance().addDayCreature(daySpawn);
    
} catch (Exception e) {
    e.printStackTrace();
}

Query Spawns from Table

SpawnTable spawnTable = SpawnTable.getInstance();

// Get all Orc spawns
int orcId = 20001;
Set<Spawn> orcSpawns = spawnTable.getSpawns(orcId);

System.out.println("Found " + orcSpawns.size() + " Orc spawn points");

for (Spawn spawn : orcSpawns) {
    System.out.println("  Location: " + spawn.getX() + "," + spawn.getY() + "," + spawn.getZ());
    System.out.println("  Amount: " + spawn.getAmount());
    System.out.println("  Respawn: " + spawn.getRespawnDelay() / 1000 + "s");
}

Dynamic Spawn Creation

// Create spawn at player location
Player player = ...;

try {
    Spawn spawn = new Spawn(30001); // Guard
    spawn.setXYZ(player.getX(), player.getY(), player.getZ());
    spawn.setHeading(player.getHeading());
    spawn.setAmount(1);
    spawn.setRespawnDelay(0); // No respawn
    
    Npc npc = spawn.doSpawn();
    if (npc != null) {
        player.sendMessage("Spawned: " + npc.getName());
        
        // Add to spawn table and persist
        SpawnData.getInstance().addNewSpawn(spawn);
    }
    
} catch (Exception e) {
    player.sendMessage("Failed to spawn NPC");
}

Delete Spawn

Spawn spawn = ...; // Get spawn instance

// Despawn all NPCs
for (Npc npc : spawn.getSpawnedNpcs()) {
    npc.deleteMe();
}

// Remove from table and XML
SpawnData.getInstance().deleteSpawn(spawn);

Stop/Start Respawning

Spawn spawn = ...;

// Temporarily disable respawn
spawn.stopRespawn();

// Kill remaining NPCs (won't respawn)
for (Npc npc : spawn.getSpawnedNpcs()) {
    npc.doDie(null);
}

// Re-enable respawn later
spawn.startRespawn();
spawn.init(); // Spawn new NPCs

Random Spawn System

If enabled in configuration (RandomSpawnsConfig.ENABLE_RANDOM_MONSTER_SPAWNS):
// Monsters spawn with random offset from defined position
int randX = spawnX + Rnd.get(MIN_RANGE, MAX_RANGE);
int randY = spawnY + Rnd.get(MIN_RANGE, MAX_RANGE);

// Validated with GeoEngine
if (GeoEngine.canMoveToTarget(...) && GeoEngine.canSeeTarget(...)) {
    // Use random position
}
Requirements:
  • Heading must not be -1 (fixed heading disables random)
  • Must be monster (not NPC/quest monster)
  • Not in water zone
  • Not raid/minion/flying
  • Not in instance
  • Not in exclusion list
  • RespawnTaskManager - Schedules NPC respawns
  • DayNightSpawnManager - Manages day/night creature spawning
  • RaidBossSpawnManager - Handles raid boss spawns
  • GrandBossManager - Manages grand boss spawns
  • NpcPersonalAIData - Custom AI parameters per spawn
  • ZoneManager - Spawn territory management

Source Reference

  • Source: java/org/l2jmobius/gameserver/model/Spawn.java:50
  • Source: java/org/l2jmobius/gameserver/data/xml/SpawnData.java:62
  • Source: java/org/l2jmobius/gameserver/data/SpawnTable.java:33

Build docs developers (and LLMs) love