NTai XE10.1b
Moderators: hoijui, Moderators
How does NTAI know what is a geo?
Because when I give a "Classic_TA_5.6" corcv a "b_geo" task, it does it. But when I give a Kernel Panic assembler a "b_geo" task, it stays idle.
I have changed the yarmap of my socket from yardmap=gccg gccg gccg gccg; to YardMap=GGGGGGGGGGGGGGGG; in case it what was confused the AI, but no luck.
And no, to ask it to build a socket does not work because the AI is too dumb to realise sockets have to built on geos, so will only build one if it happens, by chance, to stand next to a geovent.
Hint: When a unit has even one g or G in its yardmap, a cons trying to build it should find a geovent first.
b_random move the unit by so little it's useless. No really, I was expecting to move a least by the unit length, if not ten times that, but now it moves like 2 pixels.
b_na does not work. My kernel was set to have only one tak, assembler,b_na ; yet it keeps spamming assemblers.
b_artillery is said to be "unreliable, don't use", what a shame, KP has an archetypical arty! (Which need to stop to fire btw)
Task that "cannot be done" are not skipped. I told a corvp to to build an armcv, and it tried to (I saw an hologram of an armcv in an otherwise stuck to idlness corcv). Or I gave a kernel the task kernel=assembler,dos; and it went stuck after one asm showing a dos hologram as dos is another race unit.
I was using that NTAI because I have no idea where is the lastest and http://www.darkstars.co.uk has no download but only whiteish webpages looping back to themselves instead of content.
There is a rule "b_rule - a set of constructions rules, see documentation", but said documentation is nowhere to be found!
Because when I give a "Classic_TA_5.6" corcv a "b_geo" task, it does it. But when I give a Kernel Panic assembler a "b_geo" task, it stays idle.
I have changed the yarmap of my socket from yardmap=gccg gccg gccg gccg; to YardMap=GGGGGGGGGGGGGGGG; in case it what was confused the AI, but no luck.
And no, to ask it to build a socket does not work because the AI is too dumb to realise sockets have to built on geos, so will only build one if it happens, by chance, to stand next to a geovent.
Hint: When a unit has even one g or G in its yardmap, a cons trying to build it should find a geovent first.
b_random move the unit by so little it's useless. No really, I was expecting to move a least by the unit length, if not ten times that, but now it moves like 2 pixels.
b_na does not work. My kernel was set to have only one tak, assembler,b_na ; yet it keeps spamming assemblers.
b_artillery is said to be "unreliable, don't use", what a shame, KP has an archetypical arty! (Which need to stop to fire btw)
Task that "cannot be done" are not skipped. I told a corvp to to build an armcv, and it tried to (I saw an hologram of an armcv in an otherwise stuck to idlness corcv). Or I gave a kernel the task kernel=assembler,dos; and it went stuck after one asm showing a dos hologram as dos is another race unit.
I was using that NTAI because I have no idea where is the lastest and http://www.darkstars.co.uk has no download but only whiteish webpages looping back to themselves instead of content.
There is a rule "b_rule - a set of constructions rules, see documentation", but said documentation is nowhere to be found!
zwzsg, B_NA is ignored from XE9.5 onwards. It is an error return value now. But that does not explain why on earth you would want to use it.
I have built kernel panic configs before. I have ran them, I tested and built the first working kernel panic config. NTai is not too stupid to realize that a socket needs to be built on a geothermal because I have seen it with my very own eyes doing just that.
I also said b_random_move shouldnt be used for the same reason I removed scouting. Its broken. But why would you want to use b_random_move in a mod like kernel panic anyway?
Why would you want a keyword like b_rule in a mod that has no resources?
NTai doesnt handle geothermals at all, because spring handles it for ais perfectly well. Spring will return a geo spot without mentioning anything about geothermals when asked.
I suggest you look at my config for kernel panic, and the 3 other configs there are. Reading the last 5 or 6 pages of this thread should also be enlightening. You'd know that assemblers work best with sockets and only sockets in their build order, and not via b_factory or b_rule but 2 tasks specifically building sockets by name. Mines type units also dont work well with AIs as no AI has yet to attempt to manage minefields and very few players use them either.
I have had a lot of work to do. I havent had time to perfect the content of darkstars.co.uk, write 10 page documents or trim the odd little things off of Toolkit, or cater for unusual usage of features in unusual mods.
Also
read the logs
If NTai doesnt do what it says, do you go to the logs for an explanation or do you complain to me? If NTai builds everything in a tasklist but refuses to do the last item for some reason, do you ask me or do you look at the reason NTai put in a logfile and modify your config?
Things will go wrong, and NTai cannot blindly follow a config to the letter. It may not have building space, it may lack resources, it may be following a rule you've forgotten and cancelled the task.
But do read the log file. There are a huge number of possible bugs that have occurred and I've not known whats happened because nobody has told me anything useful. Without logs I cant fix most issues. lale is proof of that because I ahd peopel complaining and I could do nothing untill lale came and managed to give me what I needed and they got solved.
70% of the time an AI bug report is useless unless it comes with a log.
50% of AI bug reports can be avoided by config builders who read a logfile.
I have built kernel panic configs before. I have ran them, I tested and built the first working kernel panic config. NTai is not too stupid to realize that a socket needs to be built on a geothermal because I have seen it with my very own eyes doing just that.
I also said b_random_move shouldnt be used for the same reason I removed scouting. Its broken. But why would you want to use b_random_move in a mod like kernel panic anyway?
Why would you want a keyword like b_rule in a mod that has no resources?
NTai doesnt handle geothermals at all, because spring handles it for ais perfectly well. Spring will return a geo spot without mentioning anything about geothermals when asked.
I suggest you look at my config for kernel panic, and the 3 other configs there are. Reading the last 5 or 6 pages of this thread should also be enlightening. You'd know that assemblers work best with sockets and only sockets in their build order, and not via b_factory or b_rule but 2 tasks specifically building sockets by name. Mines type units also dont work well with AIs as no AI has yet to attempt to manage minefields and very few players use them either.
I have had a lot of work to do. I havent had time to perfect the content of darkstars.co.uk, write 10 page documents or trim the odd little things off of Toolkit, or cater for unusual usage of features in unusual mods.
Also
read the logs
If NTai doesnt do what it says, do you go to the logs for an explanation or do you complain to me? If NTai builds everything in a tasklist but refuses to do the last item for some reason, do you ask me or do you look at the reason NTai put in a logfile and modify your config?
Things will go wrong, and NTai cannot blindly follow a config to the letter. It may not have building space, it may lack resources, it may be following a rule you've forgotten and cancelled the task.
But do read the log file. There are a huge number of possible bugs that have occurred and I've not known whats happened because nobody has told me anything useful. Without logs I cant fix most issues. lale is proof of that because I ahd peopel complaining and I could do nothing untill lale came and managed to give me what I needed and they got solved.
70% of the time an AI bug report is useless unless it comes with a log.
50% of AI bug reports can be avoided by config builders who read a logfile.
For testing purpose, I wanted to make my kernel build one asm and stop. It was annoying to have dozen of asm pilling up. I can definitively see use for units that do one action and stop forever though. Or at least remove a task from their task list.AF wrote:zwzsg, B_NA is ignored from XE9.5 onwards. It is an error return value now. But that does not explain why on earth you would want to use it.
Yes, I tested your config, an even in your config, assembler builds sockets extremely rarely, like, one socket after 15 min. After some more testing I found that's because they don't look for geo spot, so only build socket when they happen to be bumped near one. It is critical for the success of any KP ai they they actively go and build socket on every free geo as quickly as possible.I have built kernel panic configs before. I have ran them, I tested and built the first working kernel panic config. NTai is not too stupid to realize that a socket needs to be built on a geothermal because I have seen it with my very own eyes doing just that.
Both would be very valuable. I guess I have to read the 56 pages of that topic to know why on earth you removed them? I wanted to use b_random so assembler actually wander randomly around the map then try to build a socket, instead of staying idle next to kernel.I also said b_random_move shouldnt be used for the same reason I removed scouting. Its broken. But why would you want to use b_random_move in a mod like kernel panic anyway?
I had, no, have, no idea what b_rule was about, and simply wanted to see what it was in case it would help me.Why would you want a keyword like b_rule in a mod that has no resources?
Perfectly well? I'm sorry I have to disagree here.NTai doesnt handle geothermals at all, because spring handles it for ais perfectly well. Spring will return a geo spot without mentioning anything about geothermals when asked.
I looked at it, couldn't understand why the assembler only task is made of fivetime the same command. Wouln't one be enough? I mean, it's not like it risk switching to another task, since there's only one task. And anyway your config fails at building sockets, or at least more sockets than one per half hour.I suggest you look at my config for kernel panic
I tried that, building socket by name. Works only when a geo spot happens to be near.You'd know that assemblers work best with sockets and only sockets in their build order ... but 2 tasks specifically building sockets by name.
I don't care if the AI doesn't build minefield, they aren't that essential.Mines type units also dont work well with AIs as no AI has yet to attempt to manage minefields and very few players use them either.
I complain to you.If NTai doesnt do what it says, do you go to the logs for an explanation or do you complain to me?
Haven't I mentionned how you never run out of ressources in KP?it may lack resources
I hoped that the comprehensive config thing would make NTai able to handle a small simple mod that's not 100% TA-like. But it looks like it fails on something as simple as recognising geo's that aren't TA ones verbatim.unusual mods
Here is the config I used:
[AI]
{
author=;
version=0.1;
message=;
abstract=0;
use_mod_default_if_absent=0;
defence_spacing=7;
power_spacing=6;
factory_spacing=4;
default_spacing=5;
dynamic_selection=1;
spacemod=0;
hard_target=0;
antistall=3;
interpolate_tag=b_na;
MaxStallTimeMobile=0;
MaxStallTimeImmobile=0;
normal_handicap=0;
antistallwindow=43;
initial_threat_value=5;
hold_pos=;
maneouvre=;
roam= ;
hold_fire=;
return_fire=;
fire_at_will= ;
NoAntiStall=;
AlwaysAntiStall=;
singlebuild=;
solobuild=;
scouters=;
attackers=;
}
[TASKLISTS]
{
[NORMAL]
{
builder=;
commander=;
hub=;
factory=;
}
[CHEAT]
{
builder=list1;
commander=list1;
hub=list1;
factory=list1;
}
[LISTS]
{
kernel=assembler,dos;
assembler=b_randmove,b_geo;
}
}
[ECONOMY]
{
[RULES]
{
power=0.7;
mex=0.7;
factorymetal=0.95;
factoryenergy=0.95;
factorymetalgap=10;
energystorage=0.7;
metalstorage=0.7;
makermetal=0.5;
makerenergy=0.7;
[EXTREME]
{
power=0.3;
mex=0.3;
factorymetal=0.99;
factoryenergy=0.99;
factorymetalgap=0.7;
energystorage=0.7;
metalstorage=0.7;
makermetal=0.3;
makerenergy=0.8;
}
}
}
[Resource]
{
[ConstructionRepairRanges]
{
}
[ConstructionExclusionRange]
{
}
[MaxEnergy]
{
}
[MinEnergy]
{
}
}
Here is the log file, couldn't find anything useful in it. Beside that your AI doesn't handle dot in map SMD filename, but that's irrelevant.
Nevermind, I found out. Indeed reading the previous page was useful. It couldn't build because my "spacing" was too high and cliff too close to my geospot. By putting all spacing to 0, and telling asm to build socket and not geo, they know spam socket fast, as they should. Good, maybe I'll get some KP ai after all.:: NTAI XE9.7 Log File
:: Programmed and maintained by AF/T.Nowell
:: Copyright (C) 2004-7 Tom Nowell/AF
:: Game started: 20.4.2007 0:3:19
:: Kernel Panic Evilless
:: The one side mutator
:: First instance of NTAI
:: greenmeanie
:: zwzsg
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: spring_engine
:: AI DLL's in game
[-] < Frame: 0 >logging started
KAI Metal Class by Krogothe
Metal Spots loaded from file
Metal Spots Found 24
:: Found 24 Metal Spots
[-] < Frame: 0 >Order Router constructed
[-] < Frame: 0 >DTHandler constructed
[-] < Frame: 0 >RadarHandler constructed
[-] < Frame: 0 >Planning constructed
[-] < Frame: 0 >Assigner constructed
[-] < Frame: 0 >Scouter constructed
[-] < Frame: 0 >Economy constructed
[-] < Frame: 0 >Manufacturer constructed
[-] < Frame: 0 >BuildingPlacer constructed
[-] < Frame: 0 >Chaser constructed
[-] < Frame: 0 >Initialisising
[-] < Frame: 0 >Mod TDF loaded
[-] < Frame: 0 >Mod TDF loaded
[-] < Frame: 0 >values filled
[-] < Frame: 0 >Arrays filled
[-] < Frame: 0 >Loading unit data
[-] < Frame: 0 >Unit data loaded
:: Direct Memory Access 0.5e (beta).smf
:: Kernel_Panic_No_Evil.sd7
:: map size 16 x 12
[-] < Frame: 0 >Assigner Init'd
[-] < Frame: 0 >Planner Init'd
No MetaTags where defined
[-] < Frame: 0 >Manufacturer Init'd
[-] < Frame: 0 >BuildingPlacement Init'd
[-] < Frame: 0 >Value ai\kamikaze missing in file buffer
[-] < Frame: 0 >Chaser Init'd
[-] < Frame: 0 >file maps\Direct Memory Access 0.smd not found
[-] < Frame: 0 >Scouter Init'd
[-] < Frame: 0 >Value tasklists\normal\kernel missing in file buffer
[-] < Frame: 0 >loading contents of tasklist :: kernel :: filling tasklist with #2 items
[-] < Frame: 0 >CUnitConstructionTask::CUnitConstructionTask building :: assembler
[-] < Frame: 0 >CUnitConstructionTask::CUnitConstructionTask building :: dos
[-] < Frame: 0 >loaded contents of tasklist :: kernel :: loaded tasklist at 2 items
[-] < Frame: 0 >CUnitConstructionTask::Init :: assembler
[-] < Frame: 0 >CUnitConstructionTask::RecieveMessage G->OrderRouter->GiveOrder(tc)== true :: kernel
[-] < Frame: 0 >CUnitConstructionTask::RecieveMessage wiping and creaiing the plan :: kernel
[-] < Frame: 3 >issuing command in update()
[-] < Frame: 3 >Command: ID: -1 Timeout: 320 params: 1216, 1002.58, 704, 0, source of command: CBuild
[-] < Frame: 3 >issuing command in update() succeeded
[greenmeanie] [00:06] < Frame: 209 > :: .cheat
[00:08] < Frame: 263 >issuing command in update()
[00:08] < Frame: 263 >Command: ID: 10 Timeout: 2147483647 params: 1216.01, 1002.58, 814.01, source of command: move CActions
[00:08] < Frame: 263 >issuing command in update() succeeded
[greenmeanie] [00:08] < Frame: 263 > :: .team 1
[00:24] < Frame: 721 >next task?
[00:24] < Frame: 721 >CUnitConstructionTask::Init :: dos
[00:24] < Frame: 721 >CUnitConstructionTask::RecieveMessage G->OrderRouter->GiveOrder(tc)== true :: kernel
[00:24] < Frame: 721 >CUnitConstructionTask::RecieveMessage wiping and creaiing the plan :: kernel
[00:24] < Frame: 722 >issuing command in update()
[00:24] < Frame: 722 >Command: ID: -7 Timeout: 977 params: 1216, 1002.58, 704, 0, source of command: CBuild
[00:24] < Frame: 722 >issuing command in update() succeeded
[00:26] < Frame: 791 >next task?
[00:26] < Frame: 791 >Value tasklists\normal\assembler missing in file buffer
[00:26] < Frame: 791 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:26] < Frame: 791 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:26] < Frame: 791 >CKeywordConstructionTask::Init b_randmove
[00:26] < Frame: 791 >issuing random move
[00:26] < Frame: 794 >issuing command in update()
[00:26] < Frame: 794 >Command: ID: 10 Timeout: 2147483647 params: 1218.87, 984.34, 902.995, source of command: move CActions
[00:26] < Frame: 794 >issuing command in update() succeeded
[00:27] < Frame: 831 >next task?
[00:27] < Frame: 831 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:27] < Frame: 836 >next task?
[00:27] < Frame: 836 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:27] < Frame: 836 >Value tasklists\normal\assembler missing in file buffer
[00:27] < Frame: 836 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:27] < Frame: 836 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:27] < Frame: 836 >CKeywordConstructionTask::Init b_randmove
[00:27] < Frame: 836 >issuing random move
[00:27] < Frame: 839 >issuing command in update()
[00:27] < Frame: 839 >Command: ID: 10 Timeout: 2147483647 params: 1207.51, 979.569, 908.286, source of command: move CActions
[00:27] < Frame: 839 >issuing command in update() succeeded
[00:29] < Frame: 898 >next task?
[00:29] < Frame: 898 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:29] < Frame: 899 >next task?
[00:29] < Frame: 899 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:29] < Frame: 899 >Value tasklists\normal\assembler missing in file buffer
[00:29] < Frame: 899 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:29] < Frame: 899 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:29] < Frame: 899 >CKeywordConstructionTask::Init b_randmove
[00:29] < Frame: 899 >issuing random move
[00:30] < Frame: 902 >issuing command in update()
[00:30] < Frame: 902 >Command: ID: 10 Timeout: 2147483647 params: 1227.98, 975.352, 899.255, source of command: move CActions
[00:30] < Frame: 902 >issuing command in update() succeeded
[00:30] < Frame: 923 >next task?
[00:30] < Frame: 923 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:31] < Frame: 934 >next task?
[00:31] < Frame: 934 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:31] < Frame: 934 >Value tasklists\normal\assembler missing in file buffer
[00:31] < Frame: 934 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:31] < Frame: 934 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:31] < Frame: 934 >CKeywordConstructionTask::Init b_randmove
[00:31] < Frame: 934 >issuing random move
[00:31] < Frame: 935 >issuing command in update()
[00:31] < Frame: 935 >Command: ID: 10 Timeout: 2147483647 params: 1224.37, 975.352, 927.184, source of command: move CActions
[00:31] < Frame: 935 >issuing command in update() succeeded
[00:31] < Frame: 944 >next task?
[00:31] < Frame: 944 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:32] < Frame: 968 >next task?
[00:32] < Frame: 968 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:32] < Frame: 968 >Value tasklists\normal\assembler missing in file buffer
[00:32] < Frame: 968 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:32] < Frame: 968 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:32] < Frame: 968 >CKeywordConstructionTask::Init b_randmove
[00:32] < Frame: 968 >issuing random move
[00:32] < Frame: 971 >issuing command in update()
[00:32] < Frame: 971 >Command: ID: 10 Timeout: 2147483647 params: 1215.37, 975.328, 929.85, source of command: move CActions
[00:32] < Frame: 971 >issuing command in update() succeeded
[00:32] < Frame: 974 >next task?
[00:32] < Frame: 974 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:32] < Frame: 986 >next task?
[00:32] < Frame: 986 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:32] < Frame: 986 >Value tasklists\normal\assembler missing in file buffer
[00:32] < Frame: 986 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:32] < Frame: 986 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:32] < Frame: 986 >CKeywordConstructionTask::Init b_randmove
[00:32] < Frame: 986 >issuing random move
[00:32] < Frame: 989 >issuing command in update()
[00:32] < Frame: 989 >Command: ID: 10 Timeout: 2147483647 params: 1211.24, 972.226, 938.923, source of command: move CActions
[00:32] < Frame: 989 >issuing command in update() succeeded
[00:34] < Frame: 1039 >next task?
[00:34] < Frame: 1039 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:35] < Frame: 1079 >next task?
[00:35] < Frame: 1079 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:35] < Frame: 1079 >Value tasklists\normal\assembler missing in file buffer
[00:35] < Frame: 1079 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:35] < Frame: 1079 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:35] < Frame: 1079 >CKeywordConstructionTask::Init b_randmove
[00:35] < Frame: 1079 >issuing random move
[00:36] < Frame: 1082 >issuing command in update()
[00:36] < Frame: 1082 >Command: ID: 10 Timeout: 2147483647 params: 1211.06, 966.097, 956.834, source of command: move CActions
[00:36] < Frame: 1082 >issuing command in update() succeeded
[00:36] < Frame: 1099 >next task?
[00:36] < Frame: 1099 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:37] < Frame: 1139 >next task?
[00:37] < Frame: 1139 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:37] < Frame: 1139 >Value tasklists\normal\assembler missing in file buffer
[00:37] < Frame: 1139 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:37] < Frame: 1139 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:37] < Frame: 1139 >CKeywordConstructionTask::Init b_randmove
[00:37] < Frame: 1139 >issuing random move
[00:38] < Frame: 1142 >issuing command in update()
[00:38] < Frame: 1142 >Command: ID: 10 Timeout: 2147483647 params: 1193.13, 959.982, 956.191, source of command: move CActions
[00:38] < Frame: 1142 >issuing command in update() succeeded
[00:40] < Frame: 1206 >next task?
[00:40] < Frame: 1206 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:40] < Frame: 1223 >next task?
[00:40] < Frame: 1223 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:40] < Frame: 1223 >Value tasklists\normal\assembler missing in file buffer
[00:40] < Frame: 1223 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:40] < Frame: 1223 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:40] < Frame: 1223 >CKeywordConstructionTask::Init b_randmove
[00:40] < Frame: 1223 >issuing random move
[00:40] < Frame: 1226 >issuing command in update()
[00:40] < Frame: 1226 >Command: ID: 10 Timeout: 2147483647 params: 1196.49, 957.037, 983.461, source of command: move CActions
[00:40] < Frame: 1226 >issuing command in update() succeeded
[00:41] < Frame: 1247 >next task?
[00:41] < Frame: 1247 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:42] < Frame: 1272 >next task?
[00:42] < Frame: 1272 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:42] < Frame: 1272 >Value tasklists\normal\assembler missing in file buffer
[00:42] < Frame: 1272 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:42] < Frame: 1272 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:42] < Frame: 1272 >CKeywordConstructionTask::Init b_randmove
[00:42] < Frame: 1272 >issuing random move
[00:42] < Frame: 1274 >issuing command in update()
[00:42] < Frame: 1274 >Command: ID: 10 Timeout: 2147483647 params: 1168.98, 954.469, 969.674, source of command: move CActions
[00:42] < Frame: 1274 >issuing command in update() succeeded
[00:42] < Frame: 1275 >next task?
[00:42] < Frame: 1275 >CKeywordConstructionTask::Init b_geo
if(targ == string("")) for b_geo
[00:44] < Frame: 1322 >next task?
[00:44] < Frame: 1322 >CKeywordConstructionTask::Init b_geo
[00:44] < Frame: 1322 >Given the go ahead :: socket
[00:44] < Frame: 1322 >Given the go ahead :: badblock
[00:44] < Frame: 1322 >Given the go ahead :: logic_bomb
[00:44] < Frame: 1322 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:44] < Frame: 1322 >Value tasklists\normal\assembler missing in file buffer
[00:44] < Frame: 1322 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:44] < Frame: 1322 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:44] < Frame: 1322 >CKeywordConstructionTask::Init b_randmove
[00:44] < Frame: 1322 >issuing random move
[00:44] < Frame: 1325 >issuing command in update()
[00:44] < Frame: 1325 >Command: ID: 10 Timeout: 2147483647 params: 1184.48, 952.597, 968.025, source of command: move CActions
[00:44] < Frame: 1325 >issuing command in update() succeeded
[00:44] < Frame: 1332 >next task?
[00:44] < Frame: 1332 >CKeywordConstructionTask::Init b_geo
[00:44] < Frame: 1332 >Given the go ahead :: socket
[00:44] < Frame: 1332 >Given the go ahead :: badblock
[00:44] < Frame: 1332 >Given the go ahead :: logic_bomb
[00:44] < Frame: 1332 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:45] < Frame: 1356 >next task?
[00:45] < Frame: 1356 >CKeywordConstructionTask::Init b_geo
[00:45] < Frame: 1356 >Given the go ahead :: socket
[00:45] < Frame: 1356 >Given the go ahead :: badblock
[00:45] < Frame: 1356 >Given the go ahead :: logic_bomb
[00:45] < Frame: 1356 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:45] < Frame: 1356 >Value tasklists\normal\assembler missing in file buffer
[00:45] < Frame: 1356 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:45] < Frame: 1356 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:45] < Frame: 1356 >CKeywordConstructionTask::Init b_randmove
[00:45] < Frame: 1356 >issuing random move
[00:45] < Frame: 1358 >issuing command in update()
[00:45] < Frame: 1358 >Command: ID: 10 Timeout: 2147483647 params: 1153.93, 956.468, 973.528, source of command: move CActions
[00:45] < Frame: 1358 >issuing command in update() succeeded
[00:45] < Frame: 1362 >next task?
[00:45] < Frame: 1362 >CKeywordConstructionTask::Init b_geo
[00:45] < Frame: 1362 >Given the go ahead :: socket
[00:45] < Frame: 1362 >Given the go ahead :: badblock
[00:45] < Frame: 1362 >Given the go ahead :: logic_bomb
[00:45] < Frame: 1362 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:45] < Frame: 1367 >next task?
[00:45] < Frame: 1367 >CKeywordConstructionTask::Init b_geo
[00:45] < Frame: 1367 >Given the go ahead :: socket
[00:45] < Frame: 1367 >Given the go ahead :: badblock
[00:45] < Frame: 1367 >Given the go ahead :: logic_bomb
[00:45] < Frame: 1367 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:45] < Frame: 1367 >Value tasklists\normal\assembler missing in file buffer
[00:45] < Frame: 1367 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:45] < Frame: 1367 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:45] < Frame: 1367 >CKeywordConstructionTask::Init b_randmove
[00:45] < Frame: 1367 >issuing random move
[00:45] < Frame: 1370 >issuing command in update()
[00:45] < Frame: 1370 >Command: ID: 10 Timeout: 2147483647 params: 1161.71, 958.623, 971.891, source of command: move CActions
[00:45] < Frame: 1370 >issuing command in update() succeeded
[00:45] < Frame: 1374 >next task?
[00:45] < Frame: 1374 >CKeywordConstructionTask::Init b_geo
[00:45] < Frame: 1374 >Given the go ahead :: socket
[00:45] < Frame: 1374 >Given the go ahead :: badblock
[00:45] < Frame: 1374 >Given the go ahead :: logic_bomb
[00:45] < Frame: 1374 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:45] < Frame: 1376 >next task?
[00:45] < Frame: 1376 >CKeywordConstructionTask::Init b_geo
[00:45] < Frame: 1376 >Given the go ahead :: socket
[00:45] < Frame: 1376 >Given the go ahead :: badblock
[00:45] < Frame: 1376 >Given the go ahead :: logic_bomb
[00:45] < Frame: 1376 >Given the go ahead :: mineblaster
if(targ == string("")) for b_geo
[00:45] < Frame: 1376 >Value tasklists\normal\assembler missing in file buffer
[00:45] < Frame: 1376 >loading contents of tasklist :: assembler :: filling tasklist with #2 items
[00:45] < Frame: 1376 >loaded contents of tasklist :: assembler :: loaded tasklist at 2 items
[00:45] < Frame: 1376 >CKeywordConstructionTask::Init b_randmove
[00:45] < Frame: 1376 >issuing random move
[00:45] < Frame: 1379 >issuing command in update()
[00:45] < Frame: 1379 >Command: ID: 10 Timeout: 2147483647 params: 1181.14, 958.623, 943.588, source of command: move CActions
[00:45] < Frame: 1379 >issuing command in update() succeeded
By the way, is there any way to assign "weight" to tasks?
Edit: Now, the AI plays fine. However, only on certain start positions. The AI fails to notice geos that are north or far. It only "sees" the geos that are south. Exemple:

Pink and red found the geo on the nearest corner, and went to build there.
White and blue assembler stays idle right out of kernel. It doesn't see the geo that are north, or far south. And so white and blue don't develop, and offer no match. This is 100% replicable.
Relevant section of log:
Yes, your AI refuse any "Up" build location. Plz fix kthx etc.[01:38] < Frame: 2950 >BuildPlacement returned UpVector or some other nasty position, a build location wasn't found!
[01:39] < Frame: 2973 >next task?
[01:39] < Frame: 2973 >CUnitConstructionTask::Init :: socket
[01:39] < Frame: 2973 >loading contents of tasklist :: assembler9 :: filling tasklist with #1 items
[01:39] < Frame: 2973 >CUnitConstructionTask::CUnitConstructionTask building :: socket using builder::assembler
[01:39] < Frame: 2973 >loaded contents of tasklist :: assembler9 :: loaded tasklist at 1 items
[01:39] < Frame: 2973 >CUnitConstructionTask::Init :: socket
[01:39] < Frame: 2973 >bad pos(1)6
[01:39] < Frame: 2973 >BuildPlacement returned UpVector or some other nasty position, a build location wasn't found!
[01:40] < Frame: 3001 >next task?
[01:40] < Frame: 3001 >CUnitConstructionTask::Init :: socket
[01:40] < Frame: 3001 >loading contents of tasklist :: assembler9 :: filling tasklist with #1 items
[01:40] < Frame: 3001 >CUnitConstructionTask::CUnitConstructionTask building :: socket using builder::assembler
[01:40] < Frame: 3001 >loaded contents of tasklist :: assembler9 :: loaded tasklist at 1 items
[01:40] < Frame: 3001 >CUnitConstructionTask::Init :: socket
[01:40] < Frame: 3001 >bad pos(1)6
[01:40] < Frame: 3001 >BuildPlacement returned UpVector or some other nasty position, a build location wasn't found!
[01:41] < Frame: 3034 >next task?
Note: If I manually move the white assembler north of the white kernel (good thing ntAI now doesn't immediatly cancel any order I give it), then the white AI starts to accept to go build on the geos. (Another case where b_random_mov could be useful to workaround other bugs, if b_random_mov moved more than 2 pixels.)
Code: Select all
antistall=3;
NTais build algorithm searches within 2000 pixels on the map for buildspots. If the next geo is 3k away it wont bother searching that far out. I tested on marble madness and it did fine.
And no you read the log before going to me. That way you can give 'my NTai cofning keeps giving bad location errors' rather than 'my NTai doesnt work', see the latter is extremely ambiguous and not very helpful. That entire set of paragraphs was aimed at everybody not specifically you though.
Also 'socket' gives better performance than 'b_factory', as in this case b_factory is a waste of computer power because theres only 1 factory buildable, the socket.
If the next geo is 50 pixels away, but north, it will be noticed of that geo, but refuse that position with a:NTais build algorithm searches within 2000 pixels on the map for buildspots. If the next geo is 3k away it wont bother searching that far out.
<Frame 4333>CUnitConstructionTask::Init :: socket
<Frame 4333>bad pos(1)6
<Frame 4333>BuildPlacement returned UpVector or some other nasty psition, a build location wasn't found!
<Frame 4339>next task?
Try again, with the AI on the second start position (bottom right).AF wrote:I tested on marble madness and it did fine.
Thanks for the insight into spring economy, I├óÔé¼Ôäóve been wondering why the metal production numbers didn├óÔé¼Ôäót add up.AF wrote: As a result sometimes antistall is extremely strict yet the same setup is extremely lax under different circumstances and its never the same. Antistall can help, but it can also be unreliable at the same time because of springs economics. My agorithms cant create reliable predictions of the future resources available on which to make sound judgements.

I think you give the current implementation of the antistall algorithm too little credit, as I have good experience using it at limited situations.
BUT, I understand and supports the notion, that all configs should be built and tested with antistall=0 first, then as a more advance optimizing effort the antistall can be used on a narrow limited number of units. (setting all other to noantistall=>unitname<)
OK, my beef is with the b_rand_assault keyword, as the random part might not work for certain factories.(with or without antistall active)AF wrote: btw: Given the go ahead :: is a message that the feasable() routine said yes aka no stall detected. This doesnt mean a unti was added to the list of candidates to be returned instead of the b_assault keyword, it just means that a check occured for stall condition before the unit was definition processed aka "before we check this build option lets see if we'd stall when we built it, if so discard it and dont bother checking"
I have to do some testing tonight, and provide a log file to demonstrate if there is a minor problem.
My thesis is; that setting a hovercraft plant to corhp=b_rand_assault; and for minenergy : nsaclash=300000; no hovercrafts will be produced.
AF wrote: You would do well to look at ubuild.h/cpp in the NTai source. Its relatively simple in structure and functionality and provides the logistics behind the universal build keywords.



http://www.koders.com/noncode/fid15EAED ... 0DF29.aspx
And that source, contains log reference. "CUBuild::GetRAND_ASSAULT" which i think is replaced by CKeywordConstructionTask. Basicly I think you revampd a great part of the manifacture system since 9.22 build.
CKeywordTask doesnt contain that logic, CUbuild is a helper class that handles universal building. aka that is the unviersal build routine class.
http://pastebin.ca/500229
There's the source to ubuild.cpp, you'll note some keywords arent implemented correctly, such air air support, amphibious, subs, and antimissile, and that all the mine keywords are the same so theres no difference between b_mine and b_focal_mine.
http://pastebin.ca/500229
There's the source to ubuild.cpp, you'll note some keywords arent implemented correctly, such air air support, amphibious, subs, and antimissile, and that all the mine keywords are the same so theres no difference between b_mine and b_focal_mine.
Setup:
Mod AA 2.23, spring 74b3
Configfile with:
Observation:
With this setup the hoverplants produce nothing!
Snip from logfile: (below repeats many times)
Either:
Number 1: Might be a logic error in:

Number 2: could be a bug in: "defnum = G->mrand()%defnum"
or method: "possibles.push_back" 
Update: corlab/kbots do NOT suffer from this problem. corlab=b_rand_assault, builds random/different kbots.
Mod AA 2.23, spring 74b3
Configfile with:
NOTE: the config file contains more default parms, not shown in aboveAA.tdf wrote:[AI]
{
>>usual setup parms, from clean run of ntai<<
antistall=0;
attackers=corsh,corah,corsnap,cormh,nsaclash;
}
- {
corcom=>power and mexes<, corlab;
corck=corhp;
corhp=b_rand_assault;
}
[MinEnergy]
{
nsaclash=100000;
}
Observation:
With this setup the hoverplants produce nothing!
Snip from logfile: (below repeats many times)
Conclusion:LOG wrote:[15:50] < Frame: 28519 >next task?
[15:50] < Frame: 28519 >CKeywordConstructionTask::Init b_rand_assault
[15:50] < Frame: 28519 >Given the go ahead :: CORCH
[15:50] < Frame: 28519 >Given the go ahead :: CORSH
[15:50] < Frame: 28519 >Given the go ahead :: CORSNAP
[15:50] < Frame: 28519 >Given the go ahead :: CORAH
[15:50] < Frame: 28519 >Given the go ahead :: CORMH
[15:50] < Frame: 28519 >Given the go ahead :: CORTHOVR
[15:50] < Frame: 28519 >Given the go ahead :: NSACLASH
[15:50] < Frame: 28519 >CKeywordConstructionTask::Build() :: NSACLASH
[15:50] < Frame: 28519 >CKeywordConstructionTask::Build emin NSACLASH
[15:50] < Frame: 28519 >loading contents of tasklist :: CORHP :: filling tasklist with #1 items
[15:50] < Frame: 28519 >loaded contents of tasklist :: CORHP :: loaded tasklist at 1 items
[15:50] < Frame: 28519 >CKeywordConstructionTask::Init b_rand_assault
[15:50] < Frame: 28519 >Given the go ahead :: CORCH
[15:50] < Frame: 28519 >Given the go ahead :: CORSH
[15:50] < Frame: 28519 >Given the go ahead :: CORSNAP
[15:50] < Frame: 28519 >Given the go ahead :: CORAH
[15:50] < Frame: 28519 >Given the go ahead :: CORMH
[15:50] < Frame: 28519 >Given the go ahead :: CORTHOVR
[15:50] < Frame: 28519 >Given the go ahead :: NSACLASH
[15:50] < Frame: 28519 >CKeywordConstructionTask::Build() :: NSACLASH
[15:50] < Frame: 28519 >CKeywordConstructionTask::Build emin NSACLASH
Either:
- 1) CUBuild::GetRAND_ASSAULT considers nsaclash the only assault hover unit, and the above "Given the go ahead" comes from a previous run class/method.
- 2) CUBuild::GetRAND_ASSAULT always return the last unit in sequence (NSACLASH) and a later check of "emin" prohibits production of this unit.
Number 1: Might be a logic error in:

But comparing corsnap and nsaclash in AA2.23 gives little reason to think that the above "if" classifies one as attacker and the other not.UBuild.cpp wrote:if(((pd->weapons.empty() == false)&&((pd->movedata)||(pd->canfly == true)))&& ((((pd->speed > 70)&&(pd->canfly == false))||((pd->weapons.empty() == true)&&(pd->canfly == true)&&(pd->builder == false)&&(pd->isCommander == false))) == false)&&(pd->transportCapacity == 0))

Number 2: could be a bug in: "defnum = G->mrand()%defnum"


Update: corlab/kbots do NOT suffer from this problem. corlab=b_rand_assault, builds random/different kbots.
Code: Select all
[NORMAL]
{
gdcom2=gdcombo;
urccom2=urccombo;
urcbhub2=urclv1hubbo;
gdbhub2=gdlv1hubbo;
gdtfact2=gdlv1gndfact;
urcmfact2=urclv1gndfact;
urcspidercon2=urclv1gndcon,urclv1gndcon,urclv1gndcon;
gdltankcon2=gdlv1gndcon,gdlv1gndcon;
}
[CHEAT]
{
gdcom2=gdcombo;
urccom2=urccombo;
urcbhub2=urclv1hubbo;
gdtfact2=gdlv1gndfact;
urcspidercon2=urclv1gndcon;
gdltankc2=gdlv1gndcon;
}
[LISTS]
{
gdcombo=b_power, gdbhub2, b_mex, b_mex, b_mex, b_mex, b_radar, b_retreat, b_defence,b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_fortification, b_fortification,b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_retreat, b_guardian;
urccombo=b_power, urcbhub2, b_mex, b_power, b_mex, b_mex,b_power, b_radar, b_retreat, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_defence, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_fortification, b_retreat, b_guardian;
urclv1hubbo=b_factory, b_guard_factory;
gdlv1hubbo=b_factory, b_guard_factory;
gdlv1gndfact=is_factory, gdltankcon2, gdltankcon2, gdltankcon2, gdltankcon2, gdltankl2,gdltankl2, gdltankc2, gdltankc2, gdltankc2, gdltankr2, gdltankr2, gdltankr2, gdltankrad2, gdltanki2, gdltanki2, gdltanka2, gdltanka2, gdltankaaa2, gdltankc2, gdltankc2, gdltankc2, gdltankr2, gdltankr2, gdltankr2;
urclv1gndfact=is_factory, urcspidercon2, urcspidercon2, urcspidercon2, urcspidercon2, urcspiderf2, urcspiderf2, urcspiderp2, urcspiderp2, urcspiderp2, urcspiderr2, urcspiderr2, urcspiderr2, urcspiderrad2, urcspiderp2, urcspiderp2, urcspiderp2, urcspiderr2, urcspiderr2, urcspiderr2, urcspiderg2, urcspiderg2,urcspideraap2;
urclv1gndcon=urcreact2, b_mex, b_radar, b_estore, b_mstore, b_defence, b_defence;
gdlv1gndcon=gdreact2, b_power, b_mex, b_defence, b_defence, b_estore, b_mstore;
}
However I do think its time I made it rely on the Attacker checkboxes in toolkit rather than that little dynamic check when appropriate.
Quite clear...AF wrote:As you can see defining a list isnt th same as assigning a list, and this might interfere with your results.
I forgot to mention that my [NORMAL] section contains:
corcom=corcom;
corck=corck;
corhp=corhp;
corxxx=corxxx etc.
Also the config, is made with the toolkit.
Might do the trick, but I can't find anything in the dynamic "if" check that makes CUBuild::GetRAND_ASSAULT think nsaclash is an assault, when corsnap isn't.AF wrote: However I do think its time I made it rely on the Attacker checkboxes in toolkit rather than that little dynamic check when appropriate.
- corsnap is has a weapon, and the structure should contain movedata. So the first 3 parenthises in the "if" statement should evaluate true

Besides "Given the go ahead" log message identifies assaults perfect??
The most confusing part is the fact that the problem with b_rand_assault affects hovercrafts and L2 ships, but NOT with L1 kbots and vehicles??
UPDATE: -GOT IT!

All units that are NOT (corsnap, corbats,cormship,corcrus,corarch) selected by b_rand_assault has a speed/maxvelocity HIGHER than 2.33 in unit definition. If spring simulates 30 fps, and 2.33*30 = 70 then this might relate to the speed check in the IF statement
eg:
- if(((pd->weapons.empty() == false)&&((pd->movedata)|| (pd->canfly == true)))&& ((((:arrow: pd->speed>70) && (pd->canfly == false))||((pd->weapons.empty() == true)&&(pd->canfly == true)&&(pd->builder == false)&&(pd->isCommander == false))) == false)&&(pd->transportCapacity == 0)).
Last edited by lale on 21 May 2007, 22:47, edited 1 time in total.
e.g.:
Code: Select all
bool Planning::feasable(const UnitDef* uud, const UnitDef* pud){
NLOG("Planning::feasable");
if(NoAntiStall.empty() == false){
string n2 = uud->name;
trim(n2);
tolowercase(n2);
for(vector<string>::iterator i = NoAntiStall.begin(); i != NoAntiStall.end(); ++i){
string i2 = *i;
trim(i2);
tolowercase(i2);
if(i2 == n2){
G->L.print("Given the go ahead @:: "+uud->name);
return true;
}
}
}
Not the best formated list, but relates to previous post.
First 5 units candidate from b_rand_assault, next 5 units NOT selected by "if" statement
Code: Select all
unitname:
corthud corstorm corcrash corblackhy nsaclash corsnap corbats corcrus cormship corarch
maxvelocity:
1.5 1.5 1.6 1.96 1.63 2.53 2.64 2.64 2.64 2.64
Singlebuild works almost perfect in newest testcase. Only remains very small and rare issue with two construction units asking to build the same unit at the very same time.
Also if a singlebuild item is destroyed, NTAI do NOT allow for a new one to be built.
Solobuild works better now (in testcase build), but still needs some optimization. I think AF is look into it...
Also if a singlebuild item is destroyed, NTAI do NOT allow for a new one to be built.
Solobuild works better now (in testcase build), but still needs some optimization. I think AF is look into it...
BS.AF wrote:Thats an engine bug not an AI bug, it's caused by units getting stuck in factories. But suffice to say I and the people who have tested have never gotten it save once on comet catcher v1 when a freaker got stuck in a kbot lab.
U need to set a waypoint just outside the factory, on the side it's facing..
Then all will be fine.
Same goes for leading bots from factories to battle fields - waypoints lead the way.
gavan, its an engine bug. lets look at the points:
- This bug has cropped up in OTAI NTai AAI JCAI TSI and some other AIs. Each AI used an independant code base written from scratch.
- This bug can be reproduced by the player without an AI being present, albeit its less noticeable as AIs do extra calcs to slow it down each time the moveorderfailed call is made. Go build a peewee and set it to repeat orders and move into the factory wall, and watch what happens when it gets built.
- An engine unit AI behaviour shouldnt require a skirmish AI kludge.
Why you chose to bring up that long dead topic I dont know. That bug was highlighted months possibly a year ago, and since then its been handled and its cropped up in other AIs since.
A few hypotheticals showing how ridiculous the point your making is:
*Spring doesnt let you use the right mouse button but you have to use it so its not an engine bug its your fault for not writting a lua script implementing right clicks to play the game*
*Its your fault maps dont work because spring reads the colours back to front and its your job as a mapper to invert all the colours in your textures*
At the veyr least the engine should have the sense to do proper pathfinding around a factory wall.
- This bug has cropped up in OTAI NTai AAI JCAI TSI and some other AIs. Each AI used an independant code base written from scratch.
- This bug can be reproduced by the player without an AI being present, albeit its less noticeable as AIs do extra calcs to slow it down each time the moveorderfailed call is made. Go build a peewee and set it to repeat orders and move into the factory wall, and watch what happens when it gets built.
- An engine unit AI behaviour shouldnt require a skirmish AI kludge.
Why you chose to bring up that long dead topic I dont know. That bug was highlighted months possibly a year ago, and since then its been handled and its cropped up in other AIs since.
A few hypotheticals showing how ridiculous the point your making is:
*Spring doesnt let you use the right mouse button but you have to use it so its not an engine bug its your fault for not writting a lua script implementing right clicks to play the game*
*Its your fault maps dont work because spring reads the colours back to front and its your job as a mapper to invert all the colours in your textures*
At the veyr least the engine should have the sense to do proper pathfinding around a factory wall.