AI Interface: GetLosMap() might be broken (or wrong usage?)

AI Interface: GetLosMap() might be broken (or wrong usage?)

Post just about everything that isn't directly related to Spring here!

Moderator: Moderators

Post Reply
submarine
AI Developer
Posts: 833
Joined: 31 Jan 2005, 20:04

AI Interface: GetLosMap() might be broken (or wrong usage?)

Post by submarine »

Hello,

I have been debugging the partially broken attacking behaviour of AAI and it seems that the LOS map it gets via
const unsigned short* GetLosMap();
contains only zeroes.

Am I using it wrong? From the documentation in the header I took that values != 0u indicate that the AI currently has sight on the specific tile.
lamer
Posts: 153
Joined: 08 Mar 2014, 23:13

Re: AI Interface: GetLosMap() might be broken (or wrong usage?)

Post by lamer »

Legacy GetLosMap: https://github.com/spring/spring/blob/m ... k.cpp#L777
It is bugged: one-time function, i see no way to reset empty state of internal temporary holder.
Luckily you can write and execute similar code to what's inside brackets.
https://github.com/spring/spring/blob/m ... #L778-L783
You can find and save for the future true callback struct during init event in AIExport.cpp; ex.

Code: Select all

#include "ExternalAI/Interface/SSkirmishAICallback.h"
AAI::AAI(int skirmishAIId, const struct SSkirmishAICallback* callback)
lamer
Posts: 153
Joined: 08 Mar 2014, 23:13

Re: AI Interface: GetLosMap() might be broken (or wrong usage?)

Post by lamer »

Actual engine-side fix should look like :

Code: Select all

const unsigned short* springLegacyAI::CAIAICallback::GetLosMap()
{
	if (losMap.empty()) {
		losMap.resize(sAICallback->Map_getLosMap(skirmishAIId, nullptr, 0));
	}

	std::vector<int> tmpMap(losMap.size());  // required because of short -> int -> short

	sAICallback->Map_getLosMap(skirmishAIId, &tmpMap[0], losMap.size());
	CopyArray(&tmpMap[0], &losMap[0], losMap.size());

	return &losMap[0];
}
Also all other sensor maps have same bug. But religion forbids me from touching legacy wrapper, it's like synonym to deprecated, so i'm not the person who will create PR.
submarine
AI Developer
Posts: 833
Joined: 31 Jan 2005, 20:04

Re: AI Interface: GetLosMap() might be broken (or wrong usage?)

Post by submarine »

lamer wrote: 17 Sep 2020, 01:21 It is bugged: one-time function, i see no way to reset empty state of internal temporary holder.
Luckily you can write and execute similar code to what's inside brackets.
...
You can find and save for the future true callback struct during init event in AIExport.cpp; ex.
:lol:
When I was checking the implementation of GetLosMap() yesterday I had exactly the same thought but when I saw that the implementation of the other maps is similar I thought "No, you just dont understand the code right; otherwise it would mean that all maps are broken" ....

Thank your very much for your hint! I implemented a workaround the way you proposed, it seems to work. Testing AAI can continue :)
(AAI uses an internal scout map containing all enemy units at their last known position. It gets updated for cells within LOS. Thus, it was never updated and once spotted units never got deleted which lead to AAI attacking "ghost" units)

Maybe I should think about migrating to the "new" cpp interface. Do you know of any other limitation of the legacy cpp interface?
lamer
Posts: 153
Joined: 08 Mar 2014, 23:13

Re: AI Interface: GetLosMap() might be broken (or wrong usage?)

Post by lamer »

Tricky decision about moving to new cpp interface. I'd recommend doing so after planned initial big PR with AAI.

Things to consider about new cpp interface:
+) more up-to-date, bugfixes likely to go here;
+) evey ID is an object. unit->GetPos() looks better than callback->GetUnitPos(unitID);

-) evey ID is an object. AI usually store additional data associated with units inside own structures, so having Unit* object returned every time by interface is useless;
-) works awful with vectors; Due to some ancient bug in gcc3.x (or something) functions like GetLosMap are written in a way that will perform triple copy of data (when single is enough) and few intermediate array allocations.

Feature-wise new cpp can read {Team/Game/Unit}RulesParams, but with workaround above this limitation easy to overcome in legacy.
Vector-wise i ended up with own implementation of all GetSensorMap, GetHeightMap etc. And GetUnitsIn() that returns only IDs.
So new cpp is not without issues.

Moving to single AI interface should allow removing big old chunk of code from engine, and that cause is worth updating to new cpp interface in my opinion.
User avatar
AF
AI Developer
Posts: 20686
Joined: 14 Sep 2004, 11:32

Re: AI Interface: GetLosMap() might be broken (or wrong usage?)

Post by AF »

The new CPP API is undocumented, I used it for Shard, and there are big sections of it that don't have the objects and methods generated for it. It's a noble endeavour but unless you know how Awk scripts work and run on a Linux machine, you're out of luck.

The legacy CPP API is a well known quantity though, with more similarities with internal engine APIs, and multiple example projects. Unless you're starting a new AI I wouldn't bother migrating. If you do, check out Shard native which was built with it.

Otherwise feel free to submit PR's fixing bugs in the legacy interface, it'll help multiple AIs ( I imagine KAIK will get a significant boost from this LOS fix )
Post Reply

Return to “Off Topic Discussion”