Difference between revisions of "Ai Overview"
(→The State Machine) |
|||
Line 11: | Line 11: | ||
The model of implementation is a Finite State Machine(FSM). [[https://en.wikipedia.org/wiki/Finite-state_machine Wikipedia Article Finite State Machine]] | The model of implementation is a Finite State Machine(FSM). [[https://en.wikipedia.org/wiki/Finite-state_machine Wikipedia Article Finite State Machine]] | ||
− | To understand how | + | All AI files used by mobs require directly or indirectly the FSM and extend or alter it or its parameters to their needs. |
+ | |||
+ | To understand how the FSM would transition from one state (e.g. "Idle") to another state (e.g. "Combat") in Shards Online (SO) it is important to understand the first step: "Sense". | ||
=== Sense === | === Sense === | ||
Line 78: | Line 80: | ||
=== Act === | === Act === | ||
A state in the SO statemachine is implemented as a collection of stuff inside a table. So - lets have a look at that table: | A state in the SO statemachine is implemented as a collection of stuff inside a table. So - lets have a look at that table: | ||
− | + | <syntaxhighlight lang="lua"> | |
− | + | --Essential states of any mob | |
− | + | AI.StateMachine.AllStates = { | |
− | + | Disabled = {-- More Stuff in here }, | |
+ | DecidingIdle = {-- More Stuff in here }, | ||
+ | Idle = {-- More Stuff in here }, | ||
+ | GoToLocation = {-- More Stuff in here }, | ||
+ | Pursue = {-- More Stuff in here }, | ||
+ | GoHome = {-- More Stuff in here }, | ||
+ | Alert = {-- More Stuff in here }, | ||
+ | WhereDidHeGo = {-- More Stuff in here }, | ||
+ | Wander = {-- More Stuff in here }, | ||
+ | DecidingCombat = {-- More Stuff in here }, | ||
+ | AttackSpecial = {-- More Stuff in here }, | ||
+ | AttackAbility = {-- More Stuff in here }, | ||
+ | Chase = {-- More Stuff in here }, | ||
+ | FleeToSafeLocation = {-- More Stuff in here }, | ||
+ | Flee = {-- More Stuff in here }, | ||
+ | Dead = {-- More Stuff in here }, | ||
+ | Melee = {-- More Stuff in here }, | ||
+ | } | ||
+ | </syntaxhighlight> | ||
Revision as of 20:52, 1 November 2016
Ai Overview
This article is about helping to understand how the Ai in Shards Online works.
Some Basics:
The Artificial Intelligence for NPCs follows a general Ai Principle which is the cycle of
- Sense
- Think
- Act
The State Machine
The model of implementation is a Finite State Machine(FSM). [Wikipedia Article Finite State Machine]
All AI files used by mobs require directly or indirectly the FSM and extend or alter it or its parameters to their needs.
To understand how the FSM would transition from one state (e.g. "Idle") to another state (e.g. "Combat") in Shards Online (SO) it is important to understand the first step: "Sense".
Sense
How does an NPC sense the world?
There are several ways:
- Messages
- Messages using the
Sendmessage
function tell the NPC someone or something sent it a message. To understand Messages the NPC needs to have the appropriate EventHandlers. - Views
- Views are added to objects by using the
AddView
function. A view is basically a search function performed on a configurably regular basis which triggers an event if something matching that search function enters its configured range. Mobiles can carry around views with them. - FindObjects
- The
FindObjects
function can be executed whenever an NPC needs to find something.
Each of these sensing mechanisms can call functions provided by the core Ai which lives in base_ai_state_machine.lua
.
SchedulePulse() AI.StateMachine.Init(initialState) AI.StateMachine.Shutdown() AI.StateMachine.ChangeState(newState) AI.StateMachine.ChangeSubState(newState) AI.StateMachine.EndSubStates(success,reason) HandleAiPulse()
Especially important is function AI.StateMachine.ChangeState(newState)
which could be called when something happens our NPC needs to react to, e.g. a wolf entering the perception range of a turkey.
In base_ai_mob.lua
we find the following line of code in the initialization part:
AddView("chaseRange",SearchMobileInRange(chaseViewRange,false,false,true))
And at the end of the file we find the Event Handler in case some Mobile enters that range and triggered the view:
--On the target coming into range
RegisterEventHandler(EventType.EnterView, "chaseRange",
function (objRef)
HandleMobEnterView(objRef,false)
end)
Think
So it seems that HandleMobEnterView
is our canditate doing the real stuff.
Below is a shortened version cleared from comments and DebugMessages, with added comments to better understand it.
Nothing of the core logic of the function is changed
function HandleMobEnterView(mobileObj,ignoreVision,forceAttack)
-- Sanity Checks
if (ignoreVision == nil) then ignoreVision = false end
if not(AI.IsActive()) then return end
-- This check makes mobs ignore admins as possible targets
if (not AI.IsValidTarget(mobileObj)) then return end
-- Is what we see frined of foe?
local isFriend = IsFriend(mobileObj)
if (forceAttack) then isFriend = false end
-- if it is foe either attack or be alert
if (not isFriend) then
AI.AddToAggroList(mobileObj,2)
if (forceAttack) then
this:SendMessage("AttackEnemy",mobileObj,true)
else
AI.StateMachine.ChangeState("Alert")
end
end
end
In the last part there are two ways to react, either by a manual state change to the "Alert" state of the FSM or an indirect way by sending a message to attack, which in turn will find the appropriate combat state.
So - it seems we have at least half-way understood the sensing, and the function above is already "thinking", but what about the acting and what are these dreaded "states" which seem to be so important?
Act
A state in the SO statemachine is implemented as a collection of stuff inside a table. So - lets have a look at that table:
--Essential states of any mob
AI.StateMachine.AllStates = {
Disabled = {-- More Stuff in here },
DecidingIdle = {-- More Stuff in here },
Idle = {-- More Stuff in here },
GoToLocation = {-- More Stuff in here },
Pursue = {-- More Stuff in here },
GoHome = {-- More Stuff in here },
Alert = {-- More Stuff in here },
WhereDidHeGo = {-- More Stuff in here },
Wander = {-- More Stuff in here },
DecidingCombat = {-- More Stuff in here },
AttackSpecial = {-- More Stuff in here },
AttackAbility = {-- More Stuff in here },
Chase = {-- More Stuff in here },
FleeToSafeLocation = {-- More Stuff in here },
Flee = {-- More Stuff in here },
Dead = {-- More Stuff in here },
Melee = {-- More Stuff in here },
}