Schemes
From Mod Wiki
Revision as of 15:36, 8 September 2010 (edit) Gannebamm (Talk | contribs) ← Previous diff |
Revision as of 12:49, 9 September 2010 (edit) (undo) Gannebamm (Talk | contribs) Next diff → |
||
Line 1: | Line 1: | ||
[[Category:Articles]] | [[Category:Articles]] | ||
- | + | thanks to barin for explaining this! | |
- | + | Schemes are the basis of AIs brain. Other then logic which is usually written for one specific npc and one very special area and purpose a scheme could be used from every npc or mutant in online gameworld dynamicly (i know some of this could be done with logic, too). | |
- | + | This article should give you a general idea of how schemes could be used: | |
'''Structure___''' | '''Structure___''' | ||
- | + | Each scheme consists of four parts | |
- | + | ''evaluator'' - evaluates (thus the name) conditions which have to be met to perform action; each action may have more then one evaluator, but that depends on action itself | |
- | ''action'' - describes what happens with object, what actions it should perform; action is executed only when all evaluators binded to this action returns true (or false - that depends) | + | |
- | ''manager'' - all npcs have access to special object called planner (manager) (returned by function motivation_action_manager) which runs in background and checks all evaluators; if certain evaluator (or group of evaluators) succeeds then assigned (binded to those evaluators) action is performed; to find action and evaluator, planner is using constants, that is evaluators and actions have special (unique) ids: for evaluators such ids are called ''properties'' and for actions - ''operators'', so in other words, those are just numeric values which identifies evaluators and actions. | + | ''action'' - describes what happens with object, what actions it should perform; action is executed only when all evaluators binded to this action returns true (or false - that depends) |
+ | |||
+ | ''manager'' - all npcs have access to special object called planner (manager) (returned by function motivation_action_manager) which runs in background and checks all evaluators; if certain evaluator (or group of evaluators) succeeds then assigned (binded to those evaluators) action is performed; | ||
+ | |||
+ | to find action and evaluator, planner is using constants, that is evaluators and actions have special (unique) ids: for evaluators such ids are called ''properties'' and for actions - ''operators'', so in other words, those are just numeric values which identifies evaluators and actions. | ||
'''Example___''' | '''Example___''' |
Revision as of 12:49, 9 September 2010
thanks to barin for explaining this! Schemes are the basis of AIs brain. Other then logic which is usually written for one specific npc and one very special area and purpose a scheme could be used from every npc or mutant in online gameworld dynamicly (i know some of this could be done with logic, too). This article should give you a general idea of how schemes could be used:
Structure___
Each scheme consists of four parts evaluator - evaluates (thus the name) conditions which have to be met to perform action; each action may have more then one evaluator, but that depends on action itself
action - describes what happens with object, what actions it should perform; action is executed only when all evaluators binded to this action returns true (or false - that depends)
manager - all npcs have access to special object called planner (manager) (returned by function motivation_action_manager) which runs in background and checks all evaluators; if certain evaluator (or group of evaluators) succeeds then assigned (binded to those evaluators) action is performed;
to find action and evaluator, planner is using constants, that is evaluators and actions have special (unique) ids: for evaluators such ids are called properties and for actions - operators, so in other words, those are just numeric values which identifies evaluators and actions.
Example___
______________________ -- xr_test.script (had to be written) ---------------------------------------------------------------------------------------------------------------------- -- EVALUATORs ---------------------------------------------------------------------------------------------------------------------- class "evaluator_name" (property_evaluator) -- is evaluator function evaluator_name:__init(name, storage, npc) super (nil, name) -- inheritance stuff, just copy it :) self.a = storage -- assign storage "in" npc for evaluator end function evaluator_name:evaluate() -- this function will be called each game update local npc = self.object -- self.object is online gameobject (see lua_info.script or online offline alife article for more info) debug_utils.debug_write("test_eval for %s", tostring(npc:character_name())) if npc:character_community() == "zombied" then -- if npc is zombie then dont use action return false end if xr_wounded.is_wounded(npc) then -- if npc is wounded then dont use action return false end if gbamm.test == true then -- if variable test in gbamm.script is true then use action (for every npc not wounded nor zombie) return true else return false -- otherwise dont use action end end ---------------------------------------------------------------------------------------------------------------------- --ACTIONs ---------------------------------------------------------------------------------------------------------------------- class "action_name" (action_base) -- is action function action_name:__init (npc_name,action_name, storage) super (nil, action_name) -- inheritance stuff, just copy it :) self.a = storage -- assign storage "in" npc for action end function action_name:initialize() -- initialize stuff needed for the action called >>once<< action is evaluated true local npc = self.object -- as in evaluator self.object == online game object action_base.initialize(self) npc:set_desired_position() -- clear npcs before used desired position and direction npc:set_desired_direction() --thats a check for getting nearest for npcs accessible level vertex id of actor(player) local lvid = db.actor:level_vertex_id() if not npc:accessible(lvid) then local dummy = vector():set(0, 0, 0) lvid = npc:accessible_nearest(level.vertex_position(lvid), dummy) end end npc:set_dest_level_vertex_id(lvid) -- set new target for npcs movement npc:set_path_type(game_object.level_path) -- set path for npcs movement state_mgr.set_state(npc, "assault") -- set npcs state to assault (look into state_lib.script for states) end function action_name:execute () -- execute the action (called >>updated = repeated in intervalls<< since action initialized, till "action:add_effect" (see below) is called ) local npc = self.object -- same as above action_base.execute(self) -- execute the action end function action_name:finalize () -- finalize action called once if action:add_effect is used action_base.finalize(self) -- finish action end ---------------------------------------------------------------------------------------------------------------------- -- BINDER ---------------------------------------------------------------------------------------------------------------------- function add_to_binder(npc, char_ini, scheme, section, st) -- is called from xr_logic.script see below -- list of stuff which had added to binder -- unique ids local evid_test = 25000 --properties id (evaluator) local acid_test = 25000 --operators id (actions) local manager = npc:motivation_action_manager() -- Evaluators manager:add_evaluator (evid_test, evaluator_name("eval_name", st)) -- Actions local action = action_name (npc:name(),"action_name", st) -- preconditions when action is executed action:add_precondition (world_property(stalker_ids.property_alive, true)) -- had to be alive action:add_precondition (world_property(stalker_ids.property_enemy, false)) -- no enemy in memory action:add_precondition (world_property(stalker_ids.property_danger,false)) -- no danger in memory action:add_precondition (world_property(stalker_ids.property_anomaly,false)) -- no anomaly in memory ? action:add_precondition (world_property(evid_test, true)) -- evid_test (property = our evaluators ID) had to return true -- when action shall be stopped action:add_effect (world_property(evid_test, false)) -- if evid_test returns false then stop action -- what action to add manager:add_action (acid_test, action) -- add our operator with its ID (acid_test) action = manager:action (xr_actions_id.alife) action:add_precondition (world_property(evid_test, false)) -- ?? end function set_test(npc, ini, scheme, section) -- this is called from xr_logic.script in "function enable_generic_schemes(...)" local st = xr_logic.assign_storage_and_bind(npc, ini, scheme, section) -- calls through xr_logic.script function add_to_binder above end -- xr_test.script ends _____________________ -- in xr_logic.script ... function enable_generic_schemes(ini, npc, stype, section) if stype == modules.stype_stalker then ... --insert xr_test.set_test (npc, ini, "test") ... elseif stype == modules.stype_mobile then ... -- xr_logic.script ends ________________ --modules.script ... load_scheme("xr_reach_task", "reach_task", stype_stalker) -- insert load_scheme("xr_test", "test", stype_stalker) ... -- modules.script ends
This is a work in progress, it will be updated with more content soon.
-- new content:
- quote from talk with barin
To force nps to shoot (in SHOC):
self.object:set_item(shoot_type, weapon, NUMBER, direction) > - shoot_type - one of the flags from object class (check lua help) - this is basically a one shot, or a burst etc. > - weapon - weapon object, best to use self.object:best_weapon() so game will select best weapon for npc > - NUMBER - no idea really, try 1 > - direction - position to shoot at (for instance db.actor:position() to fire towards actor)
for instance: > self.object:set_item(object.fire1, self.object:best_weapon(), 1,db.actor:position())
download this file to test schemes in COP: http://www.file-upload.net/download-2807474/scheme_scripts.zip.html
--Gannebamm 17:28, 8 September 2010 (EEST)