Hello World Lua AI

Hello World Lua AI

Here is where ideas can be collected for the skirmish AI in development

Moderators: hoijui, Moderators

User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Hello World Lua AI

Post by zyxar »

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
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Hello World Lua AI

Post by zwzsg »

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.
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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
User avatar
Beherith
Posts: 5145
Joined: 26 Oct 2007, 16:21

Re: Hello World Lua AI

Post by Beherith »

Pretty much yes.
Just put the echo in gadget:GameFrame(n)
that will echo every frame.
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Hello World Lua AI

Post by knorke »

Now what I'm wrestling with is bridging the gap between that gadget and an ai gadget.
See http://springrts.com/wiki/AI:Developmen ... _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.
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
yes, basically like that.
Keep in mind that there might be multiple botplayers using the same AI, but for start does not matter.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7049
Joined: 16 Nov 2004, 13:08

Re: Hello World Lua AI

Post by zwzsg »

zyxar wrote:Anyway, what I understand is that the ai has to by synced between all players.
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.
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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
Attachments
MyLuaAI.lua
(1.47 KiB) Downloaded 21 times
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Hello World Lua AI

Post by knorke »

myteamid = Spring.GetMyTeamId()
hm no. See my post and wiki example how AI can get the teamIDs it is controlling.
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:
if currentunitdefid = 94 then
Replace the 94 with something like
local coreCommanderID = UnitDefNames["corcom"].id
("corcom" being the unitname)
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

Ok, so

Code: Select all

Spring.GetMyTeamID()
returns the ID of the player, then what does

Code: Select all

Spring.GetTeamLuaAI()
return?
I read the lua synced read page and it says that the output is
Spring.GetTeamLuaAI

( number teamID ) -> string "luaAI"
This doesn't seem right to me.
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Hello World Lua AI

Post by knorke »

Spring.GetMyTeamID() returns the ID of the player
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.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
Unless there was some fuckup you could try to use it like that and put your logic where it says:
------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?
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

Wow, thanks a lot. This will probably keep me busy for a while. Thanks for the time you put into explaining this to me.
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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
Attachments
MyLuaAI3.lua
(1.45 KiB) Downloaded 18 times
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Hello World Lua AI

Post by knorke »

local _,_,_,ai,side = Spring.GetTeamInfo(t)
if Spring.GetTeamLuaAI(t) == gadget:GetInfo().name then

try changing to

if ai and Spring.GetTeamLuaAI(t) == ...
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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
User avatar
knorke
Posts: 7971
Joined: 22 Feb 2006, 01:02

Re: Hello World Lua AI

Post by knorke »

what game?
maybe the attackbutton is just hidden, try a-hotkey
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

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.
User avatar
zyxar
Posts: 18
Joined: 18 Dec 2012, 04:39

Re: Hello World Lua AI

Post by zyxar »

Ok, yes it appears to be the mutation, because it works if I just put it into the mod the usual way
Google_Frog
Moderator
Posts: 2464
Joined: 12 Oct 2007, 09:24

Re: Hello World Lua AI

Post by Google_Frog »

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.
Post Reply

Return to “AI”