Difference between revisions of "T4 Modules Howto Guide/NPCs"

From Tales of Maj'Eyal
Jump to: navigation, search
m
(Formatting. Image section)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<h1 id="toc0">Actors: NPCs and Monsters</h1>
+
=Actors: NPCs and Monsters=
  
<h2 id="toc1">Important NPC Definitions</h2>
+
==Important NPC Definitions==
  
 
Note that these are also used in the copy table in a player descriptor. These expand on the properties available to all entities, see [[Entities]].
 
Note that these are also used in the copy table in a player descriptor. These expand on the properties available to all entities, see [[Entities]].
  
<table class="wikitable">
+
{|class="wikitable"
    <tr>
+
!Variable!!Effect
        <th>Variable</th>
+
|-
        <th>Effect</th>
+
|name||Displayed NPC name
    </tr>
+
|-
    <tr>
+
|short_name||NPC identifier. name is used if unset
        <td>name</td>
+
|-
        <td>Displayed NPC name.</td>
+
|desc||Optional description of NPC.
    </tr>
+
|-
    <tr>
+
|type||NPC Type (No known hardcoded types)
        <td>short_name</td>
+
|-
        <td>NPC identifier. name is used if unset</td>
+
|subtype||Better categorization for NPC.
    </tr>
+
|-
    <tr>
+
|display||Character that the NPC is displayed as in text mode.
        <td>desc</td>
+
|-
        <td>Optional description of NPC.</td>
+
|faction||Actor faction.  Defaults to "enemies".
    </tr>
+
|-
    <tr>
+
|ai||Selects which ai to use for NPC.
        <td>type</td>
+
|-
        <td>NPC Type (No known hardcoded types)</td>
+
|ai_state||(?) Depends on AI class.
    </tr>
+
|-
    <tr>
+
|rarity||How common this NPC is to generate.  Higher is rarer.  If not set will not ever generate. Do not set to 0, this is bad.
        <td>subtype</td>
+
|-
        <td>Better categorization for NPC.</td>
+
|level_range||Minimum and maximum levels for NPC. Read NPC Level Scaling below.
    </tr>
+
|-
    <tr>
+
|autolevel||Which leveling function to use to level up NPC.  Read NPC Level Scaling below.
        <td>display</td>
+
|-
        <td>Character that the NPC is displayed as in text mode.</td>
+
|max_life||Max life at level 1.
    </tr>
+
|-
    <tr>
+
|energy.mod||Scales how much energy is gained per tick.  Defaults to 1.
        <td>faction</td>
+
|-
        <td>Actor faction.  Defaults to &quot;enemies&quot;.</td>
+
|sight||Sight radius.
    </tr>
+
|-
    <tr>
+
|exp_mod||Scales how much exp is needed to reach a new level.  Defaults to 1.
        <td>ai</td>
+
|-
        <td>Selects which ai to use for NPC.</td>
+
|exp_worth||Indicator of Actor exp value.  By default, exp for killing an Actor is its level times this value.
    </tr>
+
|-
    <tr>
+
|egos||See ego section in [[Entities]]
        <td>ai_state</td>
+
|-
        <td>(?) Depends on AI class.</td>
+
|egos_chance||See ego section in [[Entities]]
    </tr>
+
|}
    <tr>
+
        <td>rarity</td>
+
        <td>How common this NPC is to generate.  Higher is rarer.  If not set will not ever generate.</td>
+
    </tr>
+
    <tr>
+
        <td>level_range</td>
+
        <td>Minimum and maximum levels for NPC. Read NPC Level Scaling below.</td>
+
    </tr>
+
    <tr>
+
        <td>autolevel</td>
+
        <td>Which leveling function to use to level up NPC.  Read NPC Level Scaling below.</td>
+
    </tr>
+
    <tr>
+
        <td>max_life</td>
+
        <td>Max life at level 1.</td>
+
    </tr>
+
    <tr>
+
        <td>energy.mod</td>
+
        <td>Scales how much energy is gained per tick.  Defaults to 1.</td>
+
    </tr>
+
    <tr>
+
        <td>sight</td>
+
        <td>Sight radius.</td>
+
    </tr>
+
    <tr>
+
        <td>exp_mod</td>
+
        <td>Scales how much exp is needed to reach a new level.  Defaults to 1.</td>
+
    </tr>
+
    <tr>
+
        <td>exp_worth</td>
+
        <td>Indicator of Actor exp value.  By default, exp for killing an Actor is its level times this value.</td>
+
    </tr>
+
    <tr>
+
        <td>egos</td>
+
        <td>See ego section in [[Entities]]</td>
+
    </tr>
+
    <tr>
+
        <td>egos_chance</td>
+
        <td>See ego section in [[Entities]]</td>
+
    </tr>
+
</table>
+
  
 
These variables are not set in the definitions file, though they can be.  They can be useful to access in code however.
 
These variables are not set in the definitions file, though they can be.  They can be useful to access in code however.
  
<table class="wikitable">
+
{|class="wikitable"
    <tr>
+
!Important runtime variables!!Effect
        <th>Important runtime variables</th>
+
|-
        <th>Effect</th>
+
|energy.value||Current energy of this actor. Defaults to 0.
    </tr>
+
|-
    <tr>
+
|self.energy.used||Set to true if some energy was used this tick.
        <td>energy.value</td>
+
|-
        <td>Current energy of this actor. Defaults to 0.</td>
+
|life||Current life.  Defaults to max_life.
    </tr>
+
|-
    <tr>
+
|dead||true if entity is dead.  Different from undead.
        <td>self.energy.used</td>
+
|-
        <td>Set to true if some energy was used this tick.</td>
+
|level||Current Actor level.
    </tr>
+
|-
    <tr>
+
|exp||Current experience.
        <td>life</td>
+
|-
        <td>Current life.  Defaults to max_life.</td>
+
|max_level||Maximum level for the Actor.
    </tr>
+
|}
    <tr>
+
        <td>dead</td>
+
        <td>true if entity is dead.  Different from undead.</td>
+
    </tr>
+
    <tr>
+
        <td>level</td>
+
        <td>Current Actor level.</td>
+
    </tr>
+
    <tr>
+
        <td>exp</td>
+
        <td>Current experience.</td>
+
    </tr>
+
    <tr>
+
        <td>max_level</td>
+
        <td>Maximum level for the Actor.</td>
+
    </tr>
+
</table>
+
  
 
The example module implements several other variables in its Actor class and Combat interface.  These are not hardcoded, but can be used as a base or example for implementing your own module.
 
The example module implements several other variables in its Actor class and Combat interface.  These are not hardcoded, but can be used as a base or example for implementing your own module.
  
<table class="wikitable">
+
{|class="wikitable"
    <tr>
+
!Variable!!Effect
        <th>Variable</th>
+
|-
        <th>Effect</th>
+
|combat_armor||Removes this amount from damage taken.
    </tr>
+
|-
    <tr>
+
|combat.dam||This is added to strength to determine the damage done by attacks.
        <td>combat_armor</td>
+
|}
        <td>Removes this amount from damage taken.</td>
+
    </tr>
+
    <tr>
+
        <td>combat.dam</td>
+
        <td>This is added to strength to determine the damage done by attacks.</td>
+
    </tr>
+
</table>
+
  
 
<h2 id="toc2">Actor class important methods</h2>
 
<h2 id="toc2">Actor class important methods</h2>
Line 146: Line 81:
 
For more information, read the documentation.
 
For more information, read the documentation.
  
<table class="wikitable">
+
{|class="wikitable"
    <tr>
+
!Method!!Purpose
        <th>Method</th>
+
|-
        <th>Purpose</th>
+
|act()||Code that gets executed every time the entity gets to act.
    </tr>
+
|-
    <tr>
+
|canSee(actor)||Test if the actor can see the target actor.  This does not check LOS or such, only the actual ability to see it, such as influenced by stealth, invisibility or telepathy.  Returns true or false and a number from 0 to 100 representing the 'chance' to be seen.
        <td>act()</td>
+
|-
        <td>Code that gets executed every time the entity gets to act.</td>
+
|getTarget()||Gets the Actor target. Redefined by player and AI.
    </tr>
+
|-
    <tr>
+
|setTarget(target)||Sets the actor target.  Redefined by player and AI.
        <td>canSee(actor)</td>
+
|-
        <td>Test if the actor can see the target actor.  This does not check LOS or such, only the actual ability to see it, such as influenced by stealth, invisibility or telepathy.  Returns true or false and a number from 0 to 100 representing the 'chance' to be seen.</td>
+
|move(x, y, force)||Do NOT manually set the actor's x and y values.  Use this method instead.  Set force to true to not test for the presence of other entities.  Returns true if a move was attempted and energy should probably be used.
    </tr>
+
|-
    <tr>
+
|moveDir(dir)||Moves in a certain direction.  Calls move() internally.
        <td>getTarget()</td>
+
|-
        <td>Gets the Actor target. Redefined by player and AI.</td>
+
|canMove(x, y, terrain_only)||Checks if the Actor can go there.  if terrain_only is true it only checks terrain and ignores the presence of actors and other entities.
    </tr>
+
|-
    <tr>
+
|teleportRandom(x, y, dist, min_dist)||Teleports randomly to x,y.  dist is the radius of the effect, min_dist is a minimum radius of the effect and defaults to 0.  Set dist to 0 for precise teleport.
        <td>setTarget(target)</td>
+
|-
        <td>Sets the actor target.  Redefined by player and AI.</td>
+
|useEnergy(amount)||Amount of energy to subtract from the actor in energy based time systems.  Often used in the act() method after taking an action that takes time.
    </tr>
+
|-
    <tr>
+
|reactionToward(target)||Uses factions to check for hostility.  -100 is fully hostile, 0 is neutral and 100 is friendly.
        <td>move(x, y, force)</td>
+
|-
        <td style="text-align: left;">Do NOT manually set the actor's x and y values.  Use this method instead.  Set force to true to not test for the presence of other entities.  Returns true if a move was attempted and energy should propably be used.</td>
+
|addTemporaryValue(prop, v, noupdate)||Changes a property on the actor, but returns an id so the value change can be reversed with a call to removeTemporaryValue(). If noupdate is true the property is not actually changed.
    </tr>
+
|-
    <tr>
+
|removeTemporaryValue(prop, id, noupdate)||Reverses a previous call to addTemporaryValue().  Use its returned id to reverse its change.
        <td>moveDir(dir)</td>
+
|-
        <td>Moves in a certain direction.  Calls move() internally.</td>
+
|onTemporaryValueChange(prop, sub, v)||Does nothing.  Redefine to perform some action when temporary values are applied or removed.
    </tr>
+
|-
    <tr>
+
|attr(prop, v, fix)||Non-temporarily increases or decreases an actor property. Use this for compatibility with temporary values above.  If fix is set the property is set to v, not increased or decreased. Commonly, attr(prop) alone is used to check for the existance of a property instead of modifying it.
        <td>canMove(x, y, terrain_only)</td>
+
|-
        <td>Checks if the Actor can go there.  if terrain_only is true it only checks terrain and ignores the presence of actors and other entities.</td>
+
|isNear(x, y, radius)||Checks whether the actor is within a certain radius of the passed coordinate.
    </tr>
+
|}
    <tr>
+
        <td>teleportRandom(x, y, dist, min_dist)</td>
+
        <td>Teleports randomly to x,y.  dist is the radius of the effect, min_dist is a minimum radius of the effect and defaults to 0.  Set dist to 0 for precise teleport.</td>
+
    </tr>
+
    <tr>
+
        <td>useEnergy(amount)</td>
+
        <td>Amount of energy to subtract from the actor in energy based time systems.  Often used in the act() method after taking an action that takes time.</td>
+
    </tr>
+
    <tr>
+
        <td>reactionToward(target)</td>
+
        <td>Uses factions to check for hostility.  -100 is fully hostile, 0 is neutral and 100 is friendly.</td>
+
    </tr>
+
    <tr>
+
        <td>addTemporaryValue(prop, v, noupdate)</td>
+
        <td>Changes a property on the actor, but returns an id so the value change can be reversed with a call to removeTemporaryValue(). If noupdate is true the property is not actually changed.</td>
+
    </tr>
+
    <tr>
+
        <td>removeTemporaryValue(prop, id, noupdate)</td>
+
        <td>Reverses a previous call to addTemporaryValue().  Use its returned id to reverse its change.</td>
+
    </tr>
+
    <tr>
+
        <td>onTemporaryValueChange(prop, sub, v)</td>
+
        <td>Does nothing.  Redefine to perform some action when temporary values are applied or removed.</td>
+
    </tr>
+
    <tr>
+
        <td>attr(prop, v, fix)</td>
+
        <td>Non-temporarily increases or decreases an actor property. Use this for compatibility with temporary values above.  If fix is set the property is set to v, not increased or decreased. Commonly, attr(prop) alone is used to check for the existance of a property instead of modifying it.</td>
+
    </tr>
+
    <tr>
+
        <td>isNear(x, y, radius)</td>
+
        <td>Checks whether the actor is within a certain radius of the passed coordinate.</td>
+
    </tr>
+
</table>
+
  
In addition, defining stats automatically creates a getStat() function.  For example, defining the stat str creates a getStr() function for you.
+
In addition, defining stats automatically creates a <code>getStat()</code> function.  For example, defining the stat str creates a <code>getStr()</code> function for you.
  
<h2 id="toc3">NPC Egos</h2>
+
==Image tiles==
  
<h2 id="toc4">NPC Level Scaling</h2>
+
The image field doesn't necessarily have intrinsic display power. Displays are handled by an object called an MO, or MapObject. These are stored in various places on an Actor (foo._mo and foo.add_mos primarily). If an actor has a very complex (moddable) tile (ie Player) its mos are made in <code>Actor:updateModdableTile</code>. If an actor has a mildly complex tile (image + shader aura, or a "fake" image that's used to handle an extra tall graphic (ie. Prox the Troll)), its handled in <code>Actor:updateModdableTilePrepare</code>. If its a simple tile (just an image), its actually handled in <code>Entity:makeMapObject()</code> all the way in <code>engines/default/engine/Entity.lua</code>.
<p>Depending on the zone settings, the spawned creatures can actually level with the player. This requires a level_range variable to be properly set and a levelup() method in the Actor class.</p>
+
  
<p>The level_range variable defines the possible range the creature can be. The entity will always be leveled up to at least its minimum level in the level range.  It will also never be leveled above that range either.</p>
+
'''Edit:''' Note that both Actor methods are ToME methods, not general T-Engine methods.
  
<p>The leveling method should be defined in Actor.lua.  In ToME this method adds to the life, stamina and mana of actors.  Alternatively, you can create several, and use the autolevel variable to pick which to call.</p>
+
Its important to realize that MOs are only made when they need to be, and are otherwise just puppeted around the screen. <code>Entity:removeAllMOs()</code> and <code>Map:updateMap()</code> are used to force a rebuild of the MOs of an actor.
  
<p>All creatures are always generated at level 1, then leveled up to reach their required level.  Keep this is mind when creating the NPC descriptor.  Note also that you can create your own levelup() function in the NPC descriptor if a unique levelup method is needed.</p>
+
==NPC Egos==
  
<p>See [[Dev-Zones]] for more info</p>
+
==NPC Level Scaling==
 +
Depending on the zone settings, the spawned creatures can actually level with the player.  This requires a level_range variable to be properly set and a levelup() method in the Actor class.
 +
 
 +
The level_range variable defines the possible range the creature can be. The entity will always be leveled up to at least its minimum level in the level range.  It will also never be leveled above that range either.
 +
 
 +
The leveling method should be defined in Actor.lua.  In ToME this method adds to the life, stamina and mana of actors.  Alternatively, you can create several, and use the autolevel variable to pick which to call.
 +
 
 +
All creatures are always generated at level 1, then leveled up to reach their required level.  Keep this is mind when creating the NPC descriptor.  Note also that you can create your own levelup() function in the NPC descriptor if a unique levelup method is needed.
 +
 
 +
See [[Dev-Zones]] for more info
 +
 
 +
==Rarities==
 +
How does rarity work? We know it's not a straight percentile chance - it's relative to the other rarities in the pool.
 +
 
 +
Let's assume there is a NPC with a rarity of 5, a NPC with a rarity of 10, a NPC with a rarity of 25 and a NPC with a rarity of 50. That's the entire pool. What are the chances for each one to be generated and what's the calculation?
  
 
Go back to [[T4 Modules Howto Guide]]
 
Go back to [[T4 Modules Howto Guide]]
  
 
{{Module Guides}}
 
{{Module Guides}}

Latest revision as of 19:03, 16 January 2021

Actors: NPCs and Monsters

Important NPC Definitions

Note that these are also used in the copy table in a player descriptor. These expand on the properties available to all entities, see Entities.

Variable Effect
name Displayed NPC name
short_name NPC identifier. name is used if unset
desc Optional description of NPC.
type NPC Type (No known hardcoded types)
subtype Better categorization for NPC.
display Character that the NPC is displayed as in text mode.
faction Actor faction. Defaults to "enemies".
ai Selects which ai to use for NPC.
ai_state (?) Depends on AI class.
rarity How common this NPC is to generate. Higher is rarer. If not set will not ever generate. Do not set to 0, this is bad.
level_range Minimum and maximum levels for NPC. Read NPC Level Scaling below.
autolevel Which leveling function to use to level up NPC. Read NPC Level Scaling below.
max_life Max life at level 1.
energy.mod Scales how much energy is gained per tick. Defaults to 1.
sight Sight radius.
exp_mod Scales how much exp is needed to reach a new level. Defaults to 1.
exp_worth Indicator of Actor exp value. By default, exp for killing an Actor is its level times this value.
egos See ego section in Entities
egos_chance See ego section in Entities

These variables are not set in the definitions file, though they can be. They can be useful to access in code however.

Important runtime variables Effect
energy.value Current energy of this actor. Defaults to 0.
self.energy.used Set to true if some energy was used this tick.
life Current life. Defaults to max_life.
dead true if entity is dead. Different from undead.
level Current Actor level.
exp Current experience.
max_level Maximum level for the Actor.

The example module implements several other variables in its Actor class and Combat interface. These are not hardcoded, but can be used as a base or example for implementing your own module.

Variable Effect
combat_armor Removes this amount from damage taken.
combat.dam This is added to strength to determine the damage done by attacks.

Actor class important methods

For more information, read the documentation.

Method Purpose
act() Code that gets executed every time the entity gets to act.
canSee(actor) Test if the actor can see the target actor. This does not check LOS or such, only the actual ability to see it, such as influenced by stealth, invisibility or telepathy. Returns true or false and a number from 0 to 100 representing the 'chance' to be seen.
getTarget() Gets the Actor target. Redefined by player and AI.
setTarget(target) Sets the actor target. Redefined by player and AI.
move(x, y, force) Do NOT manually set the actor's x and y values. Use this method instead. Set force to true to not test for the presence of other entities. Returns true if a move was attempted and energy should probably be used.
moveDir(dir) Moves in a certain direction. Calls move() internally.
canMove(x, y, terrain_only) Checks if the Actor can go there. if terrain_only is true it only checks terrain and ignores the presence of actors and other entities.
teleportRandom(x, y, dist, min_dist) Teleports randomly to x,y. dist is the radius of the effect, min_dist is a minimum radius of the effect and defaults to 0. Set dist to 0 for precise teleport.
useEnergy(amount) Amount of energy to subtract from the actor in energy based time systems. Often used in the act() method after taking an action that takes time.
reactionToward(target) Uses factions to check for hostility. -100 is fully hostile, 0 is neutral and 100 is friendly.
addTemporaryValue(prop, v, noupdate) Changes a property on the actor, but returns an id so the value change can be reversed with a call to removeTemporaryValue(). If noupdate is true the property is not actually changed.
removeTemporaryValue(prop, id, noupdate) Reverses a previous call to addTemporaryValue(). Use its returned id to reverse its change.
onTemporaryValueChange(prop, sub, v) Does nothing. Redefine to perform some action when temporary values are applied or removed.
attr(prop, v, fix) Non-temporarily increases or decreases an actor property. Use this for compatibility with temporary values above. If fix is set the property is set to v, not increased or decreased. Commonly, attr(prop) alone is used to check for the existance of a property instead of modifying it.
isNear(x, y, radius) Checks whether the actor is within a certain radius of the passed coordinate.

In addition, defining stats automatically creates a getStat() function. For example, defining the stat str creates a getStr() function for you.

Image tiles

The image field doesn't necessarily have intrinsic display power. Displays are handled by an object called an MO, or MapObject. These are stored in various places on an Actor (foo._mo and foo.add_mos primarily). If an actor has a very complex (moddable) tile (ie Player) its mos are made in Actor:updateModdableTile. If an actor has a mildly complex tile (image + shader aura, or a "fake" image that's used to handle an extra tall graphic (ie. Prox the Troll)), its handled in Actor:updateModdableTilePrepare. If its a simple tile (just an image), its actually handled in Entity:makeMapObject() all the way in engines/default/engine/Entity.lua.

Edit: Note that both Actor methods are ToME methods, not general T-Engine methods.

Its important to realize that MOs are only made when they need to be, and are otherwise just puppeted around the screen. Entity:removeAllMOs() and Map:updateMap() are used to force a rebuild of the MOs of an actor.

NPC Egos

NPC Level Scaling

Depending on the zone settings, the spawned creatures can actually level with the player. This requires a level_range variable to be properly set and a levelup() method in the Actor class.

The level_range variable defines the possible range the creature can be. The entity will always be leveled up to at least its minimum level in the level range. It will also never be leveled above that range either.

The leveling method should be defined in Actor.lua. In ToME this method adds to the life, stamina and mana of actors. Alternatively, you can create several, and use the autolevel variable to pick which to call.

All creatures are always generated at level 1, then leveled up to reach their required level. Keep this is mind when creating the NPC descriptor. Note also that you can create your own levelup() function in the NPC descriptor if a unique levelup method is needed.

See Dev-Zones for more info

Rarities

How does rarity work? We know it's not a straight percentile chance - it's relative to the other rarities in the pool.

Let's assume there is a NPC with a rarity of 5, a NPC with a rarity of 10, a NPC with a rarity of 25 and a NPC with a rarity of 50. That's the entire pool. What are the chances for each one to be generated and what's the calculation?

Go back to T4 Modules Howto Guide