Hello World Lua AI
Moderators: hoijui, Moderators
Hello World Lua AI
Hi,
I've been looking at some lua ai scripts and am having some trouble writing something that works. The ai page dedicated to lua ais is pretty sparse. I'm wondering if anyone can help me with figuring out what is necessary to have in order to write a lua ai, and an explanation of what each part does.
Thanks
Zyxar
I've been looking at some lua ai scripts and am having some trouble writing something that works. The ai page dedicated to lua ais is pretty sparse. I'm wondering if anyone can help me with figuring out what is necessary to have in order to write a lua ai, and an explanation of what each part does.
Thanks
Zyxar
Re: Hello World Lua AI
You make a synced gadget.
You use that to gather info and that to issue commands.
The trick is to stop looking for an "AI" interface and just write a regular gadget.
Edit: Oh wait, you're a new person? I confused you with a regular. Well, you'll have to learn the Lua language, and what is a Spring gadget I'm afraid. Say, have you read http://springrts.com/wiki/AI:Development:Lang:Lua ? Have you looked at Spring Tanks Lua AI, which is maybe the shortest? Though if you're new, first step would be to make a hello world gadget.
You use that to gather info and that to issue commands.
The trick is to stop looking for an "AI" interface and just write a regular gadget.
Edit: Oh wait, you're a new person? I confused you with a regular. Well, you'll have to learn the Lua language, and what is a Spring gadget I'm afraid. Say, have you read http://springrts.com/wiki/AI:Development:Lang:Lua ? Have you looked at Spring Tanks Lua AI, which is maybe the shortest? Though if you're new, first step would be to make a hello world gadget.
Re: Hello World Lua AI
I've looked at the spring tanks ai some, but I don't have a whole lot of knowledge about that game. I started playing ota and recently found spring, so I mostly enjoy playing xta. I'm attempting to write a more agressive ai to supplement rai's strong base-building skills.
Anyway, what I understand is that the ai has to by synced between all players. I can tell that the spring tanks has a synced section of code, but I'm not sure what each of the individual functions contributes.
I'm new to lua and know a little java. I already had a look at the link to the spring lua ai page you posted.
A hello world gadget sounds helpful.
Edit: In order to write a hello world gadget do I need to put Spring.Echo("string") inside of a callin?
Thank you
Zyxar
Anyway, what I understand is that the ai has to by synced between all players. I can tell that the spring tanks has a synced section of code, but I'm not sure what each of the individual functions contributes.
I'm new to lua and know a little java. I already had a look at the link to the spring lua ai page you posted.
A hello world gadget sounds helpful.
Edit: In order to write a hello world gadget do I need to put Spring.Echo("string") inside of a callin?
Thank you
Zyxar
Re: Hello World Lua AI
Pretty much yes.
Just put the echo in gadget:GameFrame(n)
that will echo every frame.
Just put the echo in gadget:GameFrame(n)
that will echo every frame.
Re: Hello World Lua AI
Ok, so I have written a gadget that spams "Hello World!" every game frame. If I try to sync the code and run it in single player it fails. Is this because spring doesn't take into account that you're the only human in the game? If I were to run this in a two-player game with the synced code would it then work?
Thanks,
Zyxar
function gadget:GetInfo()
return {
name = "HelloWorld",
desc = "Prints Hello World! to the game screen each game frame",
author = "zyxar",
date = "12-17-12",
license = "Public Domain",
layer = 82,
enabled = true
}
end
function gadget:GameFrame(n)
Spring.Echo("Hello World!")
end
Thanks,
Zyxar
function gadget:GetInfo()
return {
name = "HelloWorld",
desc = "Prints Hello World! to the game screen each game frame",
author = "zyxar",
date = "12-17-12",
license = "Public Domain",
layer = 82,
enabled = true
}
end
function gadget:GameFrame(n)
Spring.Echo("Hello World!")
end
Re: Hello World Lua AI
Now what I'm wrestling with is bridging the gap between that gadget and an ai gadget.
Do I just replace the Spring.Echo() with stuff like
Spring.GiveOrderToUnit()?
I came up with something like
some function that gets the ai's team ID
local myunits = Spring.GetTeamUnits(myteamid)
for i, o in pairs(myunits) do
local currentUnitDefID = Spring.GetUnitDefID(myunits)
if currentUnitDefID = some unit's ID then
do stuff
elseif currentUnitDefID = some other unit's ID then
do other stuff
...........................
end
end
Do I just replace the Spring.Echo() with stuff like
Spring.GiveOrderToUnit()?
I came up with something like
some function that gets the ai's team ID
local myunits = Spring.GetTeamUnits(myteamid)
for i, o in pairs(myunits) do
local currentUnitDefID = Spring.GetUnitDefID(myunits)
if currentUnitDefID = some unit's ID then
do stuff
elseif currentUnitDefID = some other unit's ID then
do other stuff
...........................
end
end
Re: Hello World Lua AI
See http://springrts.com/wiki/AI:Developmen ... _AI_GadgetNow what I'm wrestling with is bridging the gap between that gadget and an ai gadget.
Basically you need that file LuaAI.lua, so that the AI will show up in the "add bot player" menu in lobby. (But it will not show up in the add-bot menu of spring.exe, that is normal.)
The gadgetAI then has to use Spring.GetTeamLuaAI to decide which team(s) it is assigned to and which units it is allowed to control.
yes, basically like that.I came up with something like
some function that gets the ai's team ID
local myunits = Spring.GetTeamUnits(myteamid)
for i, o in pairs(myunits) do
local currentUnitDefID = Spring.GetUnitDefID(myunits)
if currentUnitDefID = some unit's ID then
do stuff
elseif currentUnitDefID = some other unit's ID then
do other stuff
...........................
end
end
Keep in mind that there might be multiple botplayers using the same AI, but for start does not matter.
Re: Hello World Lua AI
It doesn't have to. It would even probably be a bit better if it was in unsynced. But it is way more easier to have it in the synced part of the gadget.zyxar wrote:Anyway, what I understand is that the ai has to by synced between all players.
Re: Hello World Lua AI
Ok,
So I've made the ai (if it can be called that at this point) print different messages at different frames.
Now I am having trouble getting the commander to actually DO something. I have had a look at the spring tanks ai and tried to simplify it, but I'm not getting anywhere with it.
thanks for the help
So I've made the ai (if it can be called that at this point) print different messages at different frames.
Now I am having trouble getting the commander to actually DO something. I have had a look at the spring tanks ai and tried to simplify it, but I'm not getting anywhere with it.
thanks for the help
- Attachments
-
- MyLuaAI.lua
- (1.47 KiB) Downloaded 21 times
Re: Hello World Lua AI
hm no. See my post and wiki example how AI can get the teamIDs it is controlling.myteamid = Spring.GetMyTeamId()
GetMyTeamId() gets the team of the local player, but in synced "local player" does not make sense.
beside that it should work i think...
hm and this:
Replace the 94 with something likeif currentunitdefid = 94 then
local coreCommanderID = UnitDefNames["corcom"].id
("corcom" being the unitname)
Re: Hello World Lua AI
Ok, so returns the ID of the player, then what does return?
I read the lua synced read page and it says that the output is
Code: Select all
Spring.GetMyTeamID()
Code: Select all
Spring.GetTeamLuaAI()
I read the lua synced read page and it says that the output is
This doesn't seem right to me.Spring.GetTeamLuaAI
( number teamID ) -> string "luaAI"
Re: Hello World Lua AI
It is only for unsynced (widgets), it returns the ID of the team that the local player is in. But for gadget does not know who the "local player" is, for gadget (synced) all players are equal.Spring.GetMyTeamID() returns the ID of the player
Spring.GetTeamLuaAI(teamID)
Returns string containing name of AI defined in file LuaAI.lua as name="<AI name>".
So it returns "MyAwesomeAI" or "KillerBot" or nil (nothing) and gadget can check that to see if it should care about this team.
Not sure how to better explain it so I took one of my AIs and trimmed it down to only the initializing part and added some comments.
Not tested if I messed up some details but in principle it works like that:
Code: Select all
local myTeams = {} --stores which teams the AI controls
function gadget:Initialize()
--figure out which teams the gadget will control
for _,teamID in ipairs(Spring.GetTeamList()) do --loop through all teams
local _,_,_,ai,_ = Spring.GetTeamInfo(teamID) --is an AI team?
if ai and Spring.GetTeamLuaAI(t) == "HorstAI" then --is it the LuaAI from THIS gadget?
myTeams[teamID] = true --save this as one of "our" teams
Spring.Echo ("Horst AI will play for team " .. teamID)
end
end
if (myTeams == nil) then --no entries? Means this game no bot uses this AI
Spring.Echo ("Horst AI: not used, byebye.")
gadgetHandler:RemoveGadget() --disable gadget
end
end
function gadget:GameFrame (frame)
if (frame % 60 ~=0) then return end --every 2 seconds
for _,teamID in pairs(myTeams) do --loop over all our teams
Spring.Echo ("now ordering teamID " .. teamID)
local units = Spring.GetTeamUnits (teamID) --
for i,unitID in pairs(units) do
------AI LOGIC GOES HERE-----
Spring.Echo ("now ordering unit " .. unitID .. " of team " .. teamID)
--move somewhere random
local x = math.random(Game.mapSizeX)
local z = math.random(Game.mapSizeZ)
local y = Spring.GetGroundHeight (x,z)
Spring.GiveOrderToUnit(unitID, CMD.MOVE , {x,y,z }, {})
end
end
end
function gadget:UnitDestroyed(unitID, unitDefID, teamID, attackerID)
Spring.Echo ("a unit died!")
if (myTeams[teamID]) then --is this teamID one of ours?
Spring.Echo ("it was from one of our teams!")
else
Spring.Echo ("was not from one of our teams")
end
end
------AI LOGIC GOES HERE-----
As zwzsg sugggested that is not the only way to do it.
It can be better to have an AI with unsynced parts.
Or use some OO design for the multiple teams.
This is an AI that can only control one team at once:
http://code.google.com/p/conflictterra/ ... p_KTAI.lua
because here myTeam is a variable instead of array and can only store one value (team)
Here is a video of what it does, maybe helpful when looking at the gadget:
http://www.youtube.com/watch?v=aOtnOEOtVTM
I would really like to continue with the AIs because it is so funny and maybe even make tutorial but all the lobbies that have "add bot" button suck and do not work on my computer. So I can not add botplayers. Isnt that fascinating?
Re: Hello World Lua AI
Wow, thanks a lot. This will probably keep me busy for a while. Thanks for the time you put into explaining this to me.
Re: Hello World Lua AI
Ok, I've gotten the ai to move finally taking small steps from printing hello world. I noticed that The "attack" option was missing from the UI, so I tested a pristine mod and it worked like normal. It appears that whatever I did in this gadget for the ai removed the ability to attack from the game. I checked the error log and found this referencing my gadget. I'm not really sure what to do with it.
[f=0000000] Error: Lua LoadCode pcall error = 0, LuaRules/main.lua, error = 2, LuaGadgets/gadgets.lua, [string "LuaRules/Gadgets/myluaai.lua"]:19: Bad teamID type in GetTeamLuaAI()
I assume bad teamID means that I messed up the array or the loop for the team stuff, but I'm not sure what to do to fix it, and I'm also not sure what this has to do with the attack option being removed.
thanks for any help
zyxar
here's the code I was running
[f=0000000] Error: Lua LoadCode pcall error = 0, LuaRules/main.lua, error = 2, LuaGadgets/gadgets.lua, [string "LuaRules/Gadgets/myluaai.lua"]:19: Bad teamID type in GetTeamLuaAI()
I assume bad teamID means that I messed up the array or the loop for the team stuff, but I'm not sure what to do to fix it, and I'm also not sure what this has to do with the attack option being removed.
thanks for any help
zyxar
here's the code I was running
- Attachments
-
- MyLuaAI3.lua
- (1.45 KiB) Downloaded 18 times
Re: Hello World Lua AI
local _,_,_,ai,side = Spring.GetTeamInfo(t)
if Spring.GetTeamLuaAI(t) == gadget:GetInfo().name then
try changing to
if ai and Spring.GetTeamLuaAI(t) == ...
if Spring.GetTeamLuaAI(t) == gadget:GetInfo().name then
try changing to
if ai and Spring.GetTeamLuaAI(t) == ...
Re: Hello World Lua AI
Ok, that fixed the error, but it still won't let me attack the ai's commander. Do you have any idea why this is?
Thanks
Zyxar
Thanks
Zyxar
Re: Hello World Lua AI
what game?
maybe the attackbutton is just hidden, try a-hotkey
maybe the attackbutton is just hidden, try a-hotkey
Re: Hello World Lua AI
It's an xta mutation
maybe I should try putting into the mod?
The attack hotkey just causes them to walk to the unit they're supposed to attack.
maybe I should try putting into the mod?
The attack hotkey just causes them to walk to the unit they're supposed to attack.
Re: Hello World Lua AI
Ok, yes it appears to be the mutation, because it works if I just put it into the mod the usual way
-
- Moderator
- Posts: 2464
- Joined: 12 Oct 2007, 09:24
Re: Hello World Lua AI
Have my LuaAI for reference. It is probably not that useful because it is a bit monolithic but that link points out the initialization step.
http://code.google.com/p/zero-k/source/ ... I.lua#3834
I suggest at least starting out with a synced luaAI because it is easier to get your head around. The AI can then read and change almost everything. This is because AIs are just normal spring gadgets which handle teams which were created as a LuaAI.
http://code.google.com/p/zero-k/source/ ... I.lua#3834
I suggest at least starting out with a synced luaAI because it is easier to get your head around. The AI can then read and change almost everything. This is because AIs are just normal spring gadgets which handle teams which were created as a LuaAI.