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.
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.
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?
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
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[i]) if currentUnitDefID = some unit's ID then do stuff elseif currentUnitDefID = some other unit's ID then do other stuff ........................... end end
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.
Quote:
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[i]) 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.
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.
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.
Joined: 22 Feb 2006, 01:02 Location: cheap kitchen
Quote:
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:
Quote:
if currentunitdefid = 94 then
Replace the 94 with something like local coreCommanderID = UnitDefNames["corcom"].id ("corcom" being the unitname)
Joined: 22 Feb 2006, 01:02 Location: cheap kitchen
Quote:
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:
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.
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?
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.
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.
Users browsing this forum: No registered users and 2 guests
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum