Overview
The Npc class represents all Non-Player Characters in the game world, including monsters, friendly NPCs, merchants, guards, and quest NPCs. It extends Creature and uses templates to define static properties.
Package: org.l2jmobius.gameserver.model.actor
Hierarchy:
WorldObject
└── Creature
└── Npc
├── Attackable (Monsters)
├── Monster
├── Guard
├── Merchant
├── Teleporter
└── ... (50+ specialized types)
Source: model/actor/Npc.java:126
Class Hierarchy
Npc (Base) Core NPC functionality for all non-player creatures
Attackable Monsters and hostile creatures with AI
Guard Town guards and defenders
Merchant Shop NPCs and traders
Key Properties
Core Identity
The spawn object that manages this NPC’s respawn behavior
Whether this NPC is currently busy (in dialogue, etc.)
Message to display when NPC is busy
Whether the decay task has been called (for corpses)
Behavior Flags
Whether this NPC can be auto-attacked
_isRandomAnimationEnabled
Enables random idle animations
Enables random walking behavior
Whether players can talk to this NPC (from template)
Whether this is a quest-related monster (from template)
Whether this NPC appears as a fake player (from template)
Visual Properties
Current left-hand weapon/item ID
Current right-hand weapon/item ID
Current weapon enchant level (visual)
Current collision height (used for grow effects)
Current collision radius (used for grow effects)
Combat Properties
Soulshot count for this NPC
Spiritshot count for this NPC
Bitmask of active shot types
Core Methods
Template and Configuration
Returns the NPC’s template with base stats and configuration NpcTemplate template = npc . getTemplate ();
int npcId = template . getId ();
String name = template . getName ();
Returns the NPC’s template ID int npcId = npc . getId ();
if (npcId == 30001 ) {
// Specific NPC logic
}
Spawn Management
Returns the spawn object managing this NPC Spawn spawn = npc . getSpawn ();
if (spawn != null ) {
int respawnDelay = spawn . getRespawnDelay ();
}
Sets the spawn object for this NPC npc . setSpawn (spawnObject);
Behavior Control
Checks if NPC is busy if ( npc . isBusy ()) {
player . sendMessage ( npc . getBusyMessage ());
return ;
}
Sets the busy state and message npc . setBusy ( true );
npc . setBusyMessage ( "I'm currently helping someone else." );
Checks if NPC can be auto-attacked boolean canAttack = npc . isAutoAttackable (player);
Sets auto-attackable state npc . setIsAutoAttackable ( true );
Animation and Movement
setRandomAnimationEnabled
Enables or disables random animations npc . setRandomAnimationEnabled ( false ); // Disable idle animations
Enables or disables random walking npc . setRandomWalkingEnabled ( true );
Dialogue and Interaction
Shows HTML dialogue window to player npc . showChatWindow (player);
// Or with custom HTML file
npc . showChatWindow (player, "data/html/merchant/30001.htm" );
Handles bypass commands from HTML buttons @ Override
public void onBypassFeedback ( Player player, String command) {
if ( command . startsWith ( "Quest" )) {
// Handle quest bypass
}
}
Checks if NPC can be talked to if ( npc . isTalkable ()) {
npc . showChatWindow (player);
}
Decay and Cleanup
Checks if NPC corpse has decayed if ( npc . isDead () && ! npc . isDecayed ()) {
// Corpse still visible
}
Removes NPC from the world
Script Integration
Gets script-specific value int value = npc . getScriptValue ();
Sets script-specific value npc . setScriptValue ( 1 ); // Use for script state
Summoning
Gets all NPCs summoned by this NPC Map < Integer , Npc > summons = npc . getSummonedNpcs ();
if (summons != null ) {
for ( Npc summon : summons . values ()) {
// Process summoned NPCs
}
}
Common Subclasses
Attackable (Monsters)
Extends Npc with combat AI and aggression mechanics.
Attackable monster = (Attackable) npc;
monster . addDamageHate (player, 0 , 1000 ); // Add hate
boolean isAggressive = monster . isAggressive ();
Guard
Town guards that protect areas and attack criminals.
Guard guard = new Guard (template);
guard . setIsAutoAttackable ( false );
Merchant
NPCs that can buy and sell items.
Merchant merchant = new Merchant (template);
merchant . showBuyWindow (player, 0 );
Teleporter
NPCs that provide teleportation services.
Teleporter teleporter = new Teleporter (template);
teleporter . showTeleportList (player);
Usage Examples
Creating and Spawning NPCs
// Get NPC template
NpcTemplate template = NpcData . getInstance (). getTemplate ( 30001 );
// Create spawn
Spawn spawn = new Spawn (template);
spawn . setLocation (x, y, z, heading);
spawn . setRespawnDelay ( 60 ); // 60 seconds
// Spawn the NPC
Npc npc = spawn . doSpawn ();
Custom NPC Dialogue
public class CustomNpc extends Npc {
public CustomNpc ( NpcTemplate template ) {
super (template);
}
@ Override
public void showChatWindow ( Player player ) {
NpcHtmlMessage html = new NpcHtmlMessage ( getObjectId ());
html . setFile (player, "data/html/custom/welcome.htm" );
html . replace ( "%name%" , player . getName ());
player . sendPacket (html);
}
@ Override
public void onBypassFeedback ( Player player , String command ) {
if ( command . equals ( "givereward" )) {
player . addItem ( "Reward" , 57 , 10000 , this , true );
}
}
}
Quest NPC Implementation
// In quest script
public class MyQuest extends Quest {
private static final int QUEST_NPC = 30001 ;
@ Override
public String onTalk ( Npc npc , Player player ) {
QuestState qs = getQuestState (player, true );
if ( npc . getId () == QUEST_NPC) {
if ( qs . isStarted ()) {
return "quest_running.htm" ;
} else {
return "quest_start.htm" ;
}
}
return null ;
}
@ Override
public String onKill ( Npc npc , Player killer , boolean isSummon ) {
QuestState qs = getQuestState (killer, false );
if (qs != null && qs . isCond ( 1 )) {
qs . setCond ( 2 , true );
}
return null ;
}
}
Boss Mechanics
public class RaidBoss extends GrandBoss {
private static final int MINION_ID = 20001 ;
public RaidBoss ( NpcTemplate template ) {
super (template);
}
@ Override
protected void onDeath ( Creature killer ) {
// Despawn all minions
Map < Integer , Npc > summons = getSummonedNpcs ();
if (summons != null ) {
for ( Npc minion : summons . values ()) {
minion . deleteMe ();
}
}
// Handle rewards
if ( killer . getActingPlayer () != null ) {
Player player = killer . getActingPlayer ();
// Give rewards to party/raid
}
super . onDeath (killer);
}
// Spawn minions when HP drops
@ Override
public void reduceCurrentHp ( double damage , Creature attacker ,
Skill skill , boolean isDOT ) {
double hpRatio = getCurrentHp () / getMaxHp ();
if (hpRatio < 0.5 && getScriptValue () == 0 ) {
setScriptValue ( 1 ); // Mark as triggered
spawnMinions ();
}
super . reduceCurrentHp (damage, attacker, skill, isDOT);
}
private void spawnMinions () {
for ( int i = 0 ; i < 5 ; i ++ ) {
addMinion (MINION_ID, false );
}
}
}
NPC with Custom AI
// Set custom AI
Npc npc = spawn . doSpawn ();
npc . setAI ( new CustomAI (npc));
// Custom AI class
public class CustomAI extends NpcAI {
public CustomAI ( Npc npc ) {
super (npc);
}
@ Override
protected void onEvtAttacked ( Creature attacker , int damage ) {
// Custom attack response
if ( getRandom ( 100 ) < 30 ) {
// 30% chance to teleport when attacked
Npc npc = (Npc) _actor;
npc . teleToLocation ( npc . getSpawn (). getLocation ());
}
super . onEvtAttacked (attacker, damage);
}
}
Constants
Constant Value Description INTERACTION_DISTANCE250 Interaction distance offset RANDOM_ITEM_DROP_LIMIT70 Max distance for item drops MINIMUM_SOCIAL_INTERVAL6000 Min time between social actions (ms)
Events
The NPC class triggers various events that can be listened to:
OnNpcSpawn - When NPC spawns
OnNpcTeleport - When NPC teleports
OnNpcSkillFinished - When NPC finishes casting
OnNpcCanBeSeen - Visibility check event
OnNpcEventReceived - Custom event handling
NpcTemplate Template defining NPC base stats and behavior
Spawn Manages NPC spawning and respawning
NpcAI AI controller for NPC behavior
Attackable Monster subclass with combat AI
Notes
NPC templates are loaded once and shared across all instances
Use getScriptValue() for temporary NPC state in scripts
NPCs auto-cleanup via DecayTaskManager after death
Fake player NPCs appear as players in the client
Quest monsters have special loot mechanics