adaptive-ai/api.md
2018-06-26 19:20:49 +02:00

595 lines
27 KiB
Markdown

Adaptive AI API
===============
---
This is a simple platform for development and experimentation of simple adaptive
AI, in the form of a Minetest mod. This mod allows for the creation of mobs that
have some learning algorithm (like a genetic algorithm), as well as bring a
couple examples of learning mobs.
I decided to build this on top of some of the Mob Redo API. I wanted to have a
custom on_step function and skip some parts of the original API, yet keeping a
few auxiliar functions like do_jump, but since most of those auxiliar functions
are defined as local, many were copied here. These are accesible in
`adaptive_ai.helper.mobs`.
Registering Adaptive Mobs
-------------------------
---
To register an adaptive mob there's the following function:
adaptive_ai:register_ai(name, def)
This function calls the `mobs:register_mob(name, def)` function from Mobs Redo,
so all the def parameters from Mobs Redo API work here. In addition, there are
the following parameters:
- **asexual:** type bool. If true, the creature breeds asexually with only one
parent. If false, it breeds with 2 parents.
- **breed:** type `function(parent)` if asexual, or `function(mother, father)`
if not.
- **actions:** list of strings with the name of the possible mob actions.
- **action_managers:** list of `function(self, dtime)` that define the behavior
for each action of the corresponding index. *(More on this later)*
- **ai_manager (Optional):** type `function(self, dtime)` that is in charge of
checking the environment and deciding on the next `self.action` of the creature.
If it returns `false`, it skips the rest of the `on_step` functions (but not the
`action_managers`).
- **Camp (Optional):** if the mob is bound to a node (like a spawner, or a
"town square") this will be the default node if it is not provided in the func-
tion that spawns a new creature of this type.
Adaptive Mob Behavior
---------------------
---
There is no default behavior. Anyone using this API is expected to implement
their own mob behavior, using at least `action` and `action_managers`. However,
there is a default behavior *manager*, and works this way:
- At each game step, the manager will look at `self.action`, and then call a
specific function from the `action_managers` using the `self.action` value as an
index. This `self.action` of the creature should be set at the end of an
`action_managers` function if one wishes to change the next action taken. These
actions are the mob's "external" states.
- Then it will manage the movement behavior. For that, it uses a set of "inter-
nal" states. The current one is stored in `self.state` as one of `"stand"`,
`"wander"`, `"move"`; they replace Mobs Redo states. They do the following:
- - **Stand:** Equivalent to Mobs Redo `idle` state. The creature stands in
place, doing nothing.
- - **Wander:** Equivalent to Mobs Redo `walk` state. The creature walks aim-
lessly.
- - **Move:** The creature moves respectively to a target. This is used for
pathfinding, and can be used for either following or attacking. If
`self.target.dir` is `"towards"`, the creature will move towards the target. If
it's `"away"`, the creature will try to get away (equivalent to the running away
behavior of Mobs Redo).
The value stored in `self.action` can be either an integer or a string, but it
must be the index used to access the corresponding `action_managers` function.
If the pathfinding target is an object (a player or another entity), then it
must be stored in `self.target.obj`; else, the target position must be stored in
`self.target.pos`. And don't forget to store either `"towards"` or `"away"` in
`self.target.dir` whenever you do so.
Custom Mob Behavior
-------------------
---
If you wish to make your own behavior, you should implement a function with pa-
rameters `(self, dtime)` and save it in a value called `ai_manager` when regis-
tering the AI. This function should manage the different values of `self.state`,
as well as moving the environment checks to decide the next action from the
`action_managers` to this function. If using pathfinding and following a target
that is an object, it should also update `self.target.pos` with the position of
`self.target.obj` at the very beginning.
The default `ai_manager` is available in `adaptive_ai.ai_manager` to be called
from your own `ai_manager` function in case you want the default behavior as
part of yours without needing to retype it all. Auxiliar functions like
`do_jump` (checks if it is necessary to jump) in `adaptive_ai.helper.mobs`; and
`ai_pathfinding` (copied and edited from `smart_mobs` in Mobs Redo, does path-
finding from creature to `self.target.pos` if `self.target.dir` is `"towards"`)
are available too.
Like in Mobs Redo, returning false in your custom `ai_manager` will skip the
rest of the `on_step` auxiliar functions. By default, both `action_managers` and
`ai_manager` are used; if you wish not to do so, make a function called
`do_custom` instead, which will outright skip this API and be passed straight to
the Mobs Redo API.
To Do
-----
---
This API is incomplete; I have yet to port all of the features related to com-
bat, mob ownership, etc. In case you wish to use non-implemented Mobs Redo pa-
rameters, like `runaway_from`, you can use your own `ai_manager` that uses them
(together with the default `adaptive_ai.ai_manager`, if you want).
I also want to make the adaptive AI examples to be optional in the future, maybe
through `minetest.conf` or making a separate mod that uses this API (like Mobs
Redo does with its animals and monsters).
---
Bellow is a copy of the Mobs Redo API (omitting all the features that need to be
but have not yet been reimplemented, and editing the ones modified).
---
---
Mobs Redo API
=============
---
Welcome to the world of mobs in minetest and hopefully an easy guide to defining
your own mobs and having them appear in your worlds.
Registering Mobs
----------------
---
To register a mob and have it ready for use requires the following function:
mobs:register_mob(name, definition)
The 'name' of a mob usually starts with the mod name it's running from followed
by it's own name e.g.
"mobs_monster:sand_monster" or "mymod:totally_awesome_beast"
... and the 'definition' is a table which holds all of the settings and
functions needed for the mob to work properly which contains the following:
'nametag' contains the name which is shown above mob.
'hp_min' has the minimum health value the mob can spawn with.
'hp_max' has the maximum health value the mob can spawn with.
'armor' holds strength of mob, 100 is normal, lower is more powerful
and needs more hits and better weapons to kill.
'walk_velocity' is the speed that your mob can walk around.
'run_velocity' is the speed your mob can run with, usually when attacking.
'walk_chance' has a 0-100 chance value your mob will walk from standing,
set to 0 for jumping mobs only.
'jump' when true allows your mob to jump updwards.
'jump_height' holds the height your mob can jump, 0 to disable jumping.
'stepheight' height of a block that your mob can easily walk up onto,
defaults to 1.1.
'fly' when true allows your mob to fly around instead of walking.
'fly_in' holds the node name that the mob flies (or swims) around
in e.g. "air" or "default:water_source".
'view_range' how many nodes in distance the mob can see.
'damage' how many health points the mob does to a player or another
mob when melee attacking.
'knock_back' when true has mobs falling backwards when hit, the greater
the damage the more they move back.
'fear_height' is how high a cliff or edge has to be before the mob stops
walking, 0 to turn off height fear.
'fall_speed' has the maximum speed the mob can fall at, default is -10.
'fall_damage' when true causes falling to inflict damage.
'water_damage' holds the damage per second infliced to mobs when standing in
water.
'lava_damage' holds the damage per second inflicted to mobs when standing
in lava or fire.
'light_damage' holds the damage per second inflicted to mobs when it's too
bright (above 13 light).
'suffocation' when true causes mobs to suffocate inside solid blocks.
'floats' when set to 1 mob will float in water, 0 has them sink.
'follow' mobs follow player when holding any of the items which appear
on this table, the same items can be fed to a mob to tame or
breed e.g. {"farming:wheat", "default:apple"}
'reach' is how far the mob will stop from target in pathfinding.
'blood_amount' contains the number of blood droplets to appear when
mob is hit.
'blood_texture' has the texture name to use for droplets e.g.
"mobs_blood.png", or table {"blood1.png", "blood2.png"}
'pathfinding' set to 1 for mobs to use pathfinder feature, set to 2
so they can also build/break also (only works when
'mobs_griefing' in minetest.conf is not false).
'immune_to' is a table that holds specific damage when being hit by
certain items e.g.
{"default:sword_wood", 0} -- causes no damage.
{"default:gold_lump", -10} -- heals by 10 health points.
{"default:coal_block", 20} -- 20 damage when hit on head with coal blocks.
'makes_footstep_sound' when true you can hear mobs walking.
'sounds' this is a table with sounds of the mob
'distance' maximum distance sounds can be heard, default is 10.
'random' random sound that plays during gameplay.
'war_cry' special mob shout.
'damage' sound heard when mob is hurt.
'death' played when mob is killed.
'jump' played when mob jumps.
'fuse' sound played when mob explode timer starts.
'explode' sound played when mob explodes.
'drops' table of items that are dropped when mob is killed, fields are:
'name' name of item to drop.
'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc.
'min' minimum number of items dropped.
'max' maximum number of items dropped.
'visual' holds the look of the mob you wish to create:
'cube' looks like a normal node
'sprite' sprite which looks same from all angles.
'upright_sprite' flat model standing upright.
'wielditem' how it looks when player holds it in hand.
'mesh' uses separate object file to define mob.
'visual_size' has the size of the mob, defaults to {x = 1, y = 1}
'collisionbox' has the box in which mob can be interacted with the
world e.g. {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}
'selectionbox' has the box in which player can interact with mob
'textures' holds a table list of textures to be used for mob, or you
could use multiple lists inside another table for random
selection e.g. { {"texture1.png"}, {"texture2.png"} }
'child_texture' holds the texture table for when baby mobs are used.
'gotten_texture' holds the texture table for when self.gotten value is
true, used for milking cows or shearing sheep.
'mesh' holds the name of the external object used for mob model
e.g. "mobs_cow.b3d"
'gotten_mesh" holds the name of the external object used for when
self.gotten is true for mobs.
'rotate' custom model rotation, 0 = front, 90 = side, 180 = back,
270 = other side.
'double_melee_attack' when true has the api choose between 'punch' and
'punch2' animations.
'animation' holds a table containing animation names and settings for use with mesh models:
'stand_start' start frame for when mob stands still.
'stand_end' end frame of stand animation.
'stand_speed' speed of animation in frames per second.
'walk_start' when mob is walking around.
'walk_end'
'walk_speed'
'run_start' when a mob runs.
'run_end'
'run_speed'
'fly_start' when a mob is flying.
'fly_end'
'fly_speed'
'die_start' death animation
'die_end'
'die_speed'
'die_loop' when set to false stops the animation looping.
Using '_loop = false' setting will stop any of the above animations from
looping.
'speed_normal' is used for animation speed for compatibility with some
older mobs.
Node Replacement
----------------
---
Mobs can look around for specific nodes as they walk and replace them to mimic
eating.
'replace_what' group of items to replace e.g.
{"farming:wheat_8", "farming:carrot_8"}
or you can use the specific options of what, with and
y offset by using this instead:
{
{"group:grass", "air", 0},
{"default:dirt_with_grass", "default:dirt", -1}
}
'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg"
'replace_rate' how random should the replace rate be (typically 10)
'replace_offset' +/- value to check specific node to replace
'on_replace(self, pos, oldnode, newnode)' is called when mob is about to
replace a node.
'self' ObjectRef of mob
'pos' Position of node to replace
'oldnode' Current node
'newnode' What the node will become after replacing
If false is returned, the mob will not replace the node.
By default, replacing sets self.gotten to true and resets the object
properties.
Custom Definition Functions
---------------------------
---
Along with the above mob registry settings we can also use custom functions to
enhance mob functionality and have them do many interesting things:
'on_die' a function that is called when the mob is killed the
parameters are (self, pos)
'on_rightclick' its same as in minetest.register_entity()
'on_blast' is called when an explosion happens near mob when using TNT
functions, parameters are (object, damage) and returns
(do_damage, do_knockback, drops)
'on_spawn' is a custom function that runs on mob spawn with 'self' as
variable, return true at end of function to run only once.
'after_activate' is a custom function that runs once mob has been activated
with these paramaters (self, staticdata, def, dtime)
'on_breed' called when two similar mobs breed, paramaters are
(parent1, parent2) objects, return false to stop child from
being resized and owner/tamed flags and child textures being
applied. Function itself must spawn new child mob.
'on_grown' is called when a child mob has grown up, only paramater is
(self).
'do_punch' called when mob is punched with paramaters (self, hitter,
time_from_last_punch, tool_capabilities, direction), return
false to stop punch damage and knockback from taking place.
'custom_attack' when set this function is called instead of the normal mob
melee attack, parameters are (self, to_attack).
'on_die' a function that is called when mob is killed (self, pos)
'do_custom' a custom function that is called every tick while mob is
active and which has access to all of the self.* variables
e.g. (self.health for health or self.standing_in for node
status), return with 'false' to skip remainder of mob API.
Internal Variables
------------------
---
The mob api also has some preset variables and functions that it will remember
for each mob.
'self.health' contains current health of mob (cannot exceed
self.hp_max)
'self.texture_list' contains list of all mob textures
'self.child_texture' contains mob child texture when growing up
'self.base_texture' contains current skin texture which was randomly
selected from textures list
'self.gotten' this is used for obtaining milk from cow and wool from
sheep
'self.horny' when animal fed enough it is set to true and animal can
breed with same animal
'self.hornytimer' background timer that controls breeding functions and
mob childhood timings
'self.child' used for when breeding animals have child, will use
child_texture and be half size
'self.nametag' contains the name of the mob which it can show above
Spawning Mobs in World
----------------------
---
mobs:register_spawn(name, nodes, max_light, min_light, chance,
active_object_count, max_height, day_toggle)
mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval,
chance, active_object_count, min_height, max_height, day_toggle, on_spawn)
These functions register a spawn algorithm for the mob. Without this function
the call the mobs won't spawn.
'name' is the name of the animal/monster
'nodes' is a list of nodenames on that the animal/monster can
spawn on top of
'neighbors' is a list of nodenames on that the animal/monster will
spawn beside (default is {"air"} for
mobs:register_spawn)
'max_light' is the maximum of light
'min_light' is the minimum of light
'interval' is same as in register_abm() (default is 30 for
mobs:register_spawn)
'chance' is same as in register_abm()
'active_object_count' number of this type of mob to spawn at one time inside
map area
'min_height' is the minimum height the mob can spawn
'max_height' is the maximum height the mob can spawn
'day_toggle' true for day spawning, false for night or nil for
anytime
'on_spawn' is a custom function which runs after mob has spawned
and gives self and pos values.
A simpler way to handle mob spawns has been added with the mobs:spawn(def)
command which uses above names to make settings clearer:
mobs:spawn({name = "mobs_monster:tree_monster",
nodes = {"group:leaves"},
max_light = 7,
})
For each mob that spawns with this function is a field in `mobs.spawning_mobs`.
It tells if the mob should spawn or not. Default is true. So other mods can
only use the API of this mod by disabling the spawning of the default mobs in
this mod.
mobs:spawn_abm_check(pos, node, name)
This global function can be changed to contain additional checks for mobs to
spawn e.g. mobs that spawn only in specific areas and the like. By returning
true the mob will not spawn.
'pos' holds the position of the spawning mob
'node' contains the node the mob is spawning on top of
'name' is the name of the animal/monster
Spawn Eggs
----------
---
mobs:register_egg(name, description, background, addegg, no_creative)
This function registers a spawn egg which can be used by admin to properly spawn in a mob.
'name' this is the name of your new mob to spawn e.g. "mob:sheep"
'description' the name of the new egg you are creating e.g. "Spawn Sheep"
'background' the texture displayed for the egg in inventory
'addegg' would you like an egg image in front of your texture (1 = yes,
0 = no)
'no_creative' when set to true this stops spawn egg appearing in creative
mode for destructive mobs like Dungeon Masters.
Explosion Function
------------------
---
mobs:explosion(pos, radius) -- DEPRECATED!!! use mobs:boom() instead
---
mobs:boom(self, pos, radius)
'self' mob entity
'pos' centre position of explosion
'radius' radius of explosion (typically set to 3)
This function generates an explosion which removes nodes in a specific radius
and damages any entity caught inside the blast radius. Protection will limit
node destruction but not entity damage.
Capturing Mobs
--------------
---
mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso,
force_take, replacewith)
This function is generally called inside the `on_rightclick` section of the mob
api code, it provides a chance of capturing the mob by hand, using the net or
lasso items, and can also have the player take the mob by force if tamed and
replace with another item entirely.
'self' mob information
'clicker' player information
'chance_hand' chance of capturing mob by hand (1 to 100) 0 to disable
'chance_net' chance of capturing mob using net (1 to 100) 0 to disable
'chance_lasso' chance of capturing mob using magic lasso (1 to 100) 0 to
disable
'force_take' take mob by force, even if tamed (true or false)
'replacewith' once captured replace mob with this item instead (overrides
new mob eggs with saved information)
Feeding and Taming/Breeding
---------------------------
---
mobs:feed_tame(self, clicker, feed_count, breed, tame)
This function allows the mob to be fed the item inside `self.follow` be it apple,
wheat or whatever a set number of times and be tamed or bred as a result.
Will return true when mob is fed with item it likes.
'self' mob information
'clicker' player information
'feed_count' number of times mob must be fed to tame or breed
'breed' true or false stating if mob can be bred and a child created
afterwards
'tame' true or false stating if mob can be tamed so player can pick
them up
Protecting Mobs
---------------
---
mobs:protect(self, clicker)
This function can be used to right-click any tamed mob with `mobs:protector` item,
this will protect the mob from harm inside of a protected area from other
players. Will return true when mob right-clicked with `mobs:protector` item.
'self' mob information
'clicker' player information
Riding Mobs
-----------
---
Mobs can be ridden by players and the following shows its functions and
usage:
mobs:attach(self, player)
This function attaches a player to the mob so it can be ridden.
'self' mob information
'player' player information
---
mobs:detach(player, offset)
This function will detach the player currently riding a mob to an offset
position.
'player' player information
'offset' position table containing offset values
---
mobs:drive(self, move_animation, stand_animation, can_fly, dtime)
This function allows an attached player to move the mob around and animate it at
same time.
'self' mob information
'move_animation' string containing movement animation e.g. "walk"
'stand_animation' string containing standing animation e.g. "stand"
'can_fly' if true then jump and sneak controls will allow mob to fly
up and down
'dtime' tick time used inside drive function
---
mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_animation)
This function allows an attached player to fly the mob around using directional
controls.
'self' mob information
'dtime' tick time used inside fly function
'speed' speed of flight
'can_shoot' true if mob can fire arrow (sneak and left mouse button
fires)
'arrow_entity' name of arrow entity used for firing
'move_animation' string containing name of pre-defined animation e.g. "walk"
or "fly" etc.
'stand_animation' string containing name of pre-defined animation e.g.
"stand" or "blink" etc.
Note: animation names above are from the pre-defined animation lists inside mob
registry without extensions.
---
mobs:set_animation(self, name)
This function sets the current animation for mob, defaulting to "stand" if not
found.
'self' mob information
'name' name of animation
Certain variables need to be set before using the above functions:
'self.v2' toggle switch used to define below values for the
first time
'self.max_speed_forward' max speed mob can move forward
'self.max_speed_reverse' max speed mob can move backwards
'self.accel' acceleration speed
'self.terrain_type' integer containing terrain mob can walk on
(1 = water, 2 or 3 = land)
'self.driver_attach_at' position offset for attaching player to mob
'self.driver_eye_offset' position offset for attached player view
'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1}
External Settings for "minetest.conf"
------------------------------------
---
'enable_damage' if true monsters will attack players (default is true)
'only_peaceful_mobs' if true only animals will spawn in game (default is
false)
'mobs_disable_blood' if false blood effects appear when mob is hit (default
is false)
'mobs_spawn_protected' if set to false then mobs will not spawn in protected
areas (default is true)
'remove_far_mobs' if true then untamed mobs that are outside players
visual range will be removed (default is true)
'mobname' can change specific mob chance rate (0 to disable) and
spawn number e.g. mobs_animal:cow = 1000,5
'mob_difficulty' sets difficulty level (health and hit damage
multiplied by this number), defaults to 1.0.
'mob_show_health' if false then punching mob will not show health status
(true by default)
'mob_chance_multiplier' multiplies chance of all mobs spawning and can be set
to 0.5 to have mobs spawn more or 2.0 to spawn less.
e.g. 1 in 7000 * 0.5 = 1 in 3500 so better odds of
spawning.
'mobs_spawn' if false then mobs no longer spawn without spawner or
spawn egg.
'mobs_drop_items' when false mobs no longer drop items when they die.
'mobs_griefing' when false mobs cannot break blocks when using either
pathfinding level 2, replace functions or mobs:boom
function.
Players can override the spawn chance for each mob registered by adding a line
to their minetest.conf file with a new value, the lower the value the more each
mob will spawn e.g.
mobs_animal:sheep_chance 11000
mobs_monster:sand_monster_chance 100