Bots and teamIDs

Bots and teamIDs

Requests for features in the spring code.

Moderator: Moderators

Post Reply
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Bots and teamIDs

Post by Forboding Angel »

Code: Select all

Spring.Echo("[Default Mex Layout] Map size is: " .. mapx + mapz)
local players = Spring.GetPlayerList()
local count = 0
for i = 1, #players do
    local playerID = players[i]
    if not select(3, Spring.GetPlayerInfo(playerID)) then
        count = count + 1
    end
end
Spring.SetGameRulesParam("peopleCount", count)

teamIDCount = Spring.GetGameRulesParam("peopleCount")

Spring.Echo("[Default Mex Layout] Number of teamIDs in this match: " .. teamIDCount)
I can't be the only one that gets annoyed by this.When using getplayerinfo, bot players are ignored. In order to get bots, you have to use a roundabout way using getteamlist. Tbh it's frustrating that getplayerinfo doesn't spit out all teamids, bots and human. I would think that an extra table entry could be added flagging that entry as a human or bot.

Could we please have bots listed in getplayerinfo as well?
Last edited by Forboding Angel on 28 May 2018, 10:50, edited 2 times in total.
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Bots and teamIDs

Post by Silentwings »

Since including them in GetPlayerList would have the unpleasant effect of removing the command used to list humans players, and AIs are not players anyway -- it would be better it to add a Spring.GetAITeamList(), although I'm not sure its really needed, they are already easily filtered in/out of GetTeamList (https://github.com/Balanced-Annihilatio ... ds.lua#L82)

Edit: post above originally was more confused and referred to GetPlayerList
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Bots and teamIDs

Post by Forboding Angel »

No it wouldn't. It would add another field which you could then use to filter humans and non-humans. Assuming you're just using the first value, it wouldn't even break any widget/gadgets.

Data Degradation", similar to bitrot, is when you simply keep bandaging code to just make it work. Later on down the line, things get so bad that fixing it at the source becomes insurmountable because it breaks everything built upon it in such a way that most of it needs to be rebuilt. We run across this a LOT in businesses with growing pains.

"Just lua it" has that same connotation if you (generic you) insist on using lua hacks to work around actual issues in the engine. Having to use a block of code 30 lines long as opposed to one half that size that contains a workaround as opposed to a direct method is a perfect example of the beginnings of what eventually turns into data degradation.

I am proposing that we simply add a flag to the getplayerlist entries, true for human, false for bot. By simply adding another entry, it should not break existing code afaia.
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Bots and teamIDs

Post by Silentwings »

Tbh it's frustrating that getplayerlist doesn't spit out all teamids, bots and human.
I guess you are confused: GetPlayerList outputs a list of playerIDs, and not a list of teamIDs. The relationship is:
  • player -- a unique connection to the host (Spring.GetPlayerList)
  • team -- a group who share control of the same units (Spring.GetTeamList)
  • allyTeam -- a group of teams who share the same winning condition (Spring.GetAllyTeamList)

Since two AIs do not share control of the same units, they are naturally uniquely associated to teamIDs, and consequently are found via GetTeamList rather than GetPlayerList.
Having to use a block of code 30 lines long as opposed to one half that size
Less than one third of "that size":

Code: Select all

local teamList = Spring.GetTeamList()
for _,teamID in pairs(teamList)
	local _,_,_,isAiTeam = Spring.GetTeamInfo(teamID)
	local isLuaAI = (Spring.GetTeamLuaAI(teamID) ~= "")
	if isAiTeam or isLuaAi then
		...
	end
end
Assuming you're just using the first value, it wouldn't even break any widget/gadgets.
Adding AIs into the player list table would require changes to the gadget linked above, or this one, or this one, etc.

Data Degradation", similar to bitrot, is when you simply keep bandaging code to just make it work.
No, it isn't, https://en.wikipedia.org/wiki/Data_degradation
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Bots and teamIDs

Post by Forboding Angel »

Silentwings wrote:
Assuming you're just using the first value, it wouldn't even break any widget/gadgets.
Adding AIs into the player list table would require changes to the gadget linked above, or this one, or this one, etc.
This part is irrelevant because of below.
Silentwings wrote:
Tbh it's frustrating that getplayerlist doesn't spit out all teamids, bots and human.
I guess you are confused: GetPlayerList outputs a list of playerIDs, and not a list of teamIDs. The relationship is:
  • player -- a unique connection to the host (Spring.GetPlayerList)
  • team -- a group who share control of the same units (Spring.GetTeamList)
  • allyTeam -- a group of teams who share the same winning condition (Spring.GetAllyTeamList)

Since two AIs do not share control of the same units, they are naturally uniquely associated to teamIDs, and consequently are found via GetTeamList rather than GetPlayerList.
You are correct, if I was in fact talking about getplayerlist. I actually meant getplayerinfo. Big difference, my bad. I've corrected the OP.
Silentwings wrote:
Data Degradation", similar to bitrot, is when you simply keep bandaging code to just make it work.
No, it isn't, https://en.wikipedia.org/wiki/Data_degradation
Correct, Data Degradation is bitrot. Unfortunately the correct term for what I was describing doesn't come to mind at the moment, but it is irrelevant to the original statement (I.E. The original statement stands on it's own irrespective of the incorrect terminology).

Edit:
... you locked my post for editing? That's rather petty, and an abuse of moderation powers.
https://i.imgur.com/4YsdMhH.png

https://i.imgur.com/4cGK8MI.png

https://i.imgur.com/wxVsYWM.png
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Bots and teamIDs

Post by Forboding Angel »

Now that the OP has been corrected, we can address this:
Silentwings wrote:
Assuming you're just using the first value, it wouldn't even break any widget/gadgets.
Adding AIs into the player list table would require changes to the gadget linked above, or this one, or this one, etc.
I mean getplayerinfo, not getplayerlist.
I am proposing that this:

Code: Select all

Spring.GetPlayerInfo

 ( number playerID ) -> 
   nil | string  "name",  (PRE-83.0: in synced code this is "SYNCED_NONAME"!)
         boolean active,
         boolean spectator,
         number  teamID,
         number  allyTeamID,
         number  pingTime,
         number  cpuUsage,
         string  country,
         number  rank
         table   customPlayerKeys
Become this:

Code: Select all

Spring.GetPlayerInfo

 ( number playerID ) -> 
   nil | string  "name",  (PRE-83.0: in synced code this is "SYNCED_NONAME"!)
         boolean active,
         boolean spectator,
         number  teamID,
         number  allyTeamID,
         number  pingTime,
         number  cpuUsage,
         string  country,
         number  rank
         table   customPlayerKeys
         boolean human
Which would result in no current luaz being broken afaiaa.
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Bots and teamIDs

Post by Silentwings »

That would result in your additional "human" variable always being true, because, as said in my previous post, AIs do not have playerIDs.
locked my post for editing
Fixed (to copy/paste more easily I used your posts edit button - I hate phones - which admittedly I wouldn't be able to do without moderator edit powers!).
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Bots and teamIDs

Post by Forboding Angel »

Silentwings wrote:because (as said in my previous post) AIs do not have playerIDs.
You never said that (explicitly). Ok, well then the question becomes, is there any real reason that AIs can't be given playerIDs by the engine?
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Bots and teamIDs

Post by Silentwings »

Silentwings wrote:The relationship is:
  • player -- a unique connection to the host (Spring.GetPlayerList)
  • team -- a group who share control of the same units (Spring.GetTeamList)
  • allyTeam -- a group of teams who share the same winning condition (Spring.GetAllyTeamList)
Since two AIs do not share control of the same units, they are naturally uniquely associated to teamIDs, and consequently are found via GetTeamList rather than GetPlayerList.
There may also be issues of extra work with re-classification inside engine, since its sharing its own data here, idk without checking through code. And as said above, giving AIs playerIDs would make them appear in GetPlayerList, forcing changes to much existing lua, to filter them out again.
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Bots and teamIDs

Post by Forboding Angel »

Silentwings wrote:
Silentwings wrote:The relationship is:
  • player -- a unique connection to the host (Spring.GetPlayerList)
  • team -- a group who share control of the same units (Spring.GetTeamList)
  • allyTeam -- a group of teams who share the same winning condition (Spring.GetAllyTeamList)
Since two AIs do not share control of the same units, they are naturally uniquely associated to teamIDs, and consequently are found via GetTeamList rather than GetPlayerList.
Image
Silentwings wrote:There may also be issues of extra work with re-classification inside engine, since its sharing its own data here, idk without checking through code. Giving AIs playerIDs would make them appear in GetPlayerList, forcing changes to much existing lua, as explained above..
No it wouldn't. Getting them via that workaround method would still work, it would just be a much crappier method. But the fact that that method is so crappy compared to getplayerinfo, is the whole reason for this. I see no good, valid reasons that bots should not be treated in much the same way as humans when it comes to things like getplayerinfo, playerid, etc (except with a bot flag ofc).

Edit: Nevermind, I get what you're saying, but what it would amount to is deleting a bunch of redundant, useless code, which is a GOOD thing.
User avatar
Silentwings
Posts: 3720
Joined: 25 Oct 2008, 00:23

Re: Bots and teamIDs

Post by Silentwings »

I guess enough is enough here, for me, afaics viewtopic.php?f=21&t=36873#p586026 contains all info.
User avatar
Forboding Angel
Evolution RTS Developer
Posts: 14673
Joined: 17 Nov 2005, 02:43

Re: Bots and teamIDs

Post by Forboding Angel »

Technical Debt was the term I was referring to but could not remember.
sprunk
Posts: 100
Joined: 29 Jun 2015, 07:36

Re: Bots and teamIDs

Post by sprunk »

Bots are handled quite differently in the engine so it makes sense that the Lua interface reflects this. It might take a lot of effort to modify the engine and such change could break backward compatibility. It's probably easier to poison your callouts:

Code: Select all

local AIs = {}
do
	local teamList = Spring.GetTeamList()
	for _, teamID in pairs(teamList) do
		local _, playerID, _, isAI, _, allyTeamID = Spring.GetTeamInfo(teamID)
		if isAI then
			local aiID, aiName, aiHost = Spring.GetAIInfo(teamID)
			local data = {
				name = aiName,
				teamID = teamID,
				allyTeamID = allyTeamID,
				playerID = aiHost,
			}

			local luaAI = Spring.GetTeamLuaAI(teamID)
			if luaAI ~= "" then
				data.luaAI = luaAI
				data.country = "AI" -- Anguilla, British overseas territory
				data.rank = 0
			else
				data.country = select(8, Spring.GetPlayerInfo(playerID))
				data.rank = select(9, Spring.GetPlayerInfo(playerID))
			end
	
			AIs[-aiID] = data
		end
	end
end

local origGPI = Spring.GetPlayerInfo
Spring.GetPlayerInfo = function(playerID)
	local aiData = AIs[playerID]
	if not aiData then
		return origGPI(playerID)
	end

	local active, ping, cpu = true, 0, 0
	if not aiData.luaAI then
		active = select(2, origGPI(aiData.playerID))
		ping = select(6, origGPI(aiData.playerID))
		cpu = select(7, origGPI(aiData.playerID))
	end

	return aiData.name, active, false, aiData.teamID, aiData.allyTeamID, ping, cpu, aiData.country, aiData.rank, {} -- 104.0
	-- return aiData.name, active, false, aiData.teamID, aiData.allyTeamID, ping, cpu, aiData.country, aiData.rank, true, {} -- develop
end

local origGPL = Spring.GetPlayerList
Spring.GetPlayerList = function (teamID, active)
	local ret = origGPL(teamID, active)
	for aiID, aiData in pairs(AIs) do
		if (not teamID or aiData.teamID == teamID)
		and (not active or select(2, origGPI(aiData.playerID)))
		then
			ret[#ret + 1] = aiID
		end		
	end
	return ret
end
Post Reply

Return to “Feature Requests”