- Unzip relevant .lua files:
Inside HoN/game/
unzip resources0.s2z "bots/behaviorlib.lua"
unzip resources0.s2z "bots/botbraincore.lua"
unzip resources0.s2z "bots/core.lua"
unzip resources0.s2z "bots/eventslib.lua"
You might want to add these to your .gitignore
Don't write any of your bot logic inside these files. :)
- Create template
2.1) Create a folder under HoN/game/bots/teams/
2.2) Add $BOTNAME.bot file with contents like:
<?xml version="1.0" encoding="UTF-8"?>
<bot
name="Your_Botname"
description="My Awesome Bot"
heroname="Hero_Heroname"
rootlua="$BOTNAME.lua"
defaultplayername="AwesomeBot"
/>
2.3) Create $BOTNAME.lua file:
-- _G is global enviroment
local object = _G.object
object.myName = object:GetName()
-- Initialize your bot with default AI
runfile "bots/core_herobot.lua"
-- Shorter names for often used stuff
local core, eventsLib, behaviorLib, skills = object.core, object.eventsLib, object.behaviorLib, object.skills
-- BotEcho() is the main print function
local BotEcho = core.BotEcho
-- Override your skill leveling order (0-3=skills, 4=attributes):
-- This table is used inside herobot:SkillBuild() (bots/core_herobot.lua)
object.tSkills = {
1, 2, 1, 0, 1,
3, 1, 2, 2, 2,
3, 0, 0, 0, 4,
3, 4, 4, 4, 4,
4, 4, 4, 4, 4
}
-- Override default bot AI with your own one.
-- You can keep the old implementation and call it after you're done if you want.
function object:onthinkOverride(tGameVariables)
-- tGameVariables is quite useless, mostly there to inform you about game tick
-- see function object:onthink(tGameVariables) (bots/botbraincore.lua) for default functionality
self:onthinkOld(tGameVariables)
end
object.onthinkOld = object.onthink
object.onthink = object.onthinkOverride
function object:oncombateventOverride(EventData)
-- EventData contains inforamtion about damage, projectiles etc
-- see function object:oncombatevent(EventData) (bots/eventslib.lua) for default functionality
self:oncombateventOld(EventData)
end
object.oncombateventOld = object.oncombatevent
object.oncombatevent = object.oncombateventOverride
-- You can also overwrite bunch
- Utility:
Default AI checks bunch of Utility functions that react to conditions.
Each of them returns numeric value. Largest value gets executed.
See bots/behaviorutility.lua for default utility functions.
behaviorLib.SomeFunctionality["Utility"] --checks for utility value
behaviorLib.SomeFunctionality["Execute"] --executes that behavior
behaviorLib.SomeFunctionality["Name"] --shouldn't be too hard to understand
tinsert(behaviorLib.tBehaviors, behaviorLib.SomeFunctionality) --adds behavior
- Abilities:
See function behaviorLib.HarassHeroUtility(botBrain) (bots/behaviorlib.lua)
when checked this utility function acquires target while calculating utility value.
If HarassHeroUtility is highest priority, HarassHeroBehavior["Execute"] is called.
local function HarassHeroExecuteOverride(botBrain)
-- Get target that was acquired from HarassHeroUtility
local unitTarget = behaviorLib.heroTarget
if unitTarget == nil then
return object.harassExecuteOld(botBrain)
end
local unitSelf = core.unitSelf
-- Get distance^2 to target
local nTargetDistanceSq = Vector3.Distance2DSq(unitSelf:GetPosition(), unitTarget:GetPosition())
local bActionTaken = false
if core.CanSeeUnit(botBrain, unitTarget) then
local abilNuke = self.core.unitSelf:GetAbility(0)
if abilNuke:CanActivate() then
local nRange = abilNuke:GetRange()
-- Check if target is within range of this ability
if nTargetDistanceSq < (nRange * nRange) then
bActionTaken = core.OrderAbilityEntity(botBrain, abilNuke, unitTarget)
end
end
if not bActionTaken then
return object.harassExecuteOld(botBrain)
end
end
object.harassExecuteOld = behaviorLib.HarassHeroBehavior["Execute"]
behaviorLib.HarassHeroBehavior["Execute"] = HarassHeroExecuteOverride