Git Product home page Git Product logo

circuitai's Introduction

Circuit AI

Spring RTS local native AI for Zero-K.

Requirements

  • gcc 5.4+
  • spring 104.0-dev
  • SDL2 (optional)

Compiling

Build process of native AI described in the wiki of Spring RTS engine. Required steps on linux:

$ git clone https://github.com/spring/spring.git
$ cd spring && git checkout maintenance
$ git clone https://github.com/rlcevg/CircuitAI.git AI/Skirmish/CircuitAI
$ cmake . && make CircuitAI

Installing

To install the AI, put files into proper directory, see CppTestAI or Shard for reference. An example location of libSkirmishAI.so on linux would be /home/<user>/.spring/engine/<engine version>/AI/Skirmish/CircuitAI/<AI version>/libSkirmishAI.so

Linux troubleshooting

Dead AI upon match start: ensure that libSkirmishAI.so is compatible with AI/Interfaces/C/0.1/libAIInterface.so (i.e. replace it with own build)

For those who lost all hope, behold: Vagrant. Just navigate to Vagrantfile and do "vagrant up". It will take some time to warm up, install all dependencies and compile Circuit for the first time. Subsequent builds should be done manually, see Vagrantfile for reference.

circuitai's People

Contributors

abma avatar amdmi3 avatar ashdnazg avatar gajop avatar lhog avatar rlcevg avatar rtri avatar sprunk avatar tomjn avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

circuitai's Issues

Circuit only obeys disabledunits modoption in singleplayer games.

Set disabledunits="turretlaser+turretmissile" in a singleplayer game and circuit will implement the option correctly. Note that I am talking about the modoption, not the AI option. The same setting in multiplayer does not work, circuit builds units that should be disabled. I have checked chobby and found no special handling for the disabledunits modoption.

As a stopgap I enforced disabledunits strictly here: ZeroK-RTS/Zero-K@bc1659a

SIGFPE in CDefendTask::CDefendTask

I suspect your intention is that powerMod should be <=1 since maxPower is set to std::numeric_limits::max() in CMilitaryManager::MakeTask.

Program terminated with signal SIGFPE, Arithmetic exception.
#0 0x00007fa697659c5b in circuit::CDefendTask::CDefendTask (this=0x302db600, mgr=0x33139ba8, position=..., radius=550, check=circuit::IFighterTask::FightType::ATTACK,
promote=circuit::IFighterTask::FightType::SUPPORT, maxPower=3.40282347e+38, powerMod=1.53846157)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/fighter/DefendTask.cpp:30
30 , maxPower(maxPower * powerMod)

(gdb) f 1
#1 0x00007fa697542475 in circuit::CMilitaryManager::EnqueueDefend (this=0x33139b90, check=circuit::IFighterTask::FightType::ATTACK,
promote=circuit::IFighterTask::FightType::SUPPORT, power=3.40282347e+38)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.cpp:398
398 check, promote, power, 1.0f / mod);
(gdb) p mod
$3 = 0.649999976
(gdb) p defenceMod
$4 = {
min = 0.649999976,
len = 0
}

(gdb) bt
#0 0x00007fa697659c5b in circuit::CDefendTask::CDefendTask (this=0x302db600, mgr=0x33139ba8, position=..., radius=550, check=circuit::IFighterTask::FightType::ATTACK,
promote=circuit::IFighterTask::FightType::SUPPORT, maxPower=3.40282347e+38, powerMod=1.53846157)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/fighter/DefendTask.cpp:30
#1 0x00007fa697542475 in circuit::CMilitaryManager::EnqueueDefend (this=0x33139b90, check=circuit::IFighterTask::FightType::ATTACK,
promote=circuit::IFighterTask::FightType::SUPPORT, power=3.40282347e+38)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.cpp:398
#2 0x00007fa6975427c2 in circuit::CMilitaryManager::MakeTask (this=0x33139b90, unit=0x31bcf300)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.cpp:448
#3 0x00007fa69763c704 in circuit::ITaskManager::AssignTask (this=0x33139ba8, unit=0x31bcf300)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/TaskManager.cpp:37
#4 0x00007fa697638a44 in circuit::CIdleTask::Update (this=0x123779e0) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/IdleTask.cpp:64
#5 0x00007fa697547df3 in circuit::CMilitaryManager::UpdateIdle (this=0x33139b90)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.cpp:1210
#6 0x00007fa697561ba4 in std::__invoke_impl<void, void (circuit::CMilitaryManager::* const&)(), circuit::CMilitaryManager*>(std::__invoke_memfun_deref, void (circuit::CMilitaryManager::* const&)(), circuit::CMilitaryManager*&&) (
__f=@0x12384cf0: (void (circuit::CMilitaryManager::)(circuit::CMilitaryManager * const)) 0x7fa697547dc8 circuit::CMilitaryManager::UpdateIdle(),
__t=<unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.9.11/libSkirmishAI.so, CU 0x2aa28c, DIE 0x32c2a7>)
at /usr/include/c++/6.3.1/functional:227
#7 0x00007fa697561b31 in std::__invoke<void (circuit::CMilitaryManager::
const&)(), circuit::CMilitaryManager*>(void (circuit::CMilitaryManager::* const&)(), circuit::CMilitaryManager*&&) (__fn=@0x12384cf0: (void (circuit::CMilitaryManager::)(circuit::CMilitaryManager * const)) 0x7fa697547dc8 circuit::CMilitaryManager::UpdateIdle(),
__args#0=<unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.9.11/libSkirmishAI.so, CU 0x2aa28c, DIE 0x32c2a7>)
at /usr/include/c++/6.3.1/functional:251
#8 0x00007fa697561ae2 in std::_Mem_fn_base<void (circuit::CMilitaryManager::
)(), true>::operator()circuit::CMilitaryManager*(circuit::CMilitaryManager*&&) const (
this=0x12384cf0, __args#0=<unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.9.11/libSkirmishAI.so, CU 0x2aa28c, DIE 0x32c2a7>)
at /usr/include/c++/6.3.1/functional:604
#9 0x00007fa697561aad in std::_Bind_simple<std::_Mem_fn<void (circuit::CMilitaryManager::)()> (circuit::CMilitaryManager)>::_M_invoke<0ul>(std::_Index_tuple<0ul>) (
this=0x12384ce8) at /usr/include/c++/6.3.1/functional:1391
#10 0x00007fa6975619c7 in std::_Bind_simple<std::_Mem_fn<void (circuit::CMilitaryManager::)()> (circuit::CMilitaryManager)>::operator()() (this=0x12384ce8)
at /usr/include/c++/6.3.1/functional:1380
#11 0x00007fa697561966 in circuit::CGameTask::_Impl<std::_Bind_simple<std::_Mem_fn<void (circuit::CMilitaryManager::)()> (circuit::CMilitaryManager)> >::_M_run() (
this=0x12384cd0) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/util/GameTask.h:37
#12 0x00007fa6976e0cb3 in circuit::CGameTask::Run (this=0x3f2a0bb0) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/util/GameTask.cpp:26
#13 0x00007fa6976e2e76 in circuit::CScheduler::ProcessTasks (this=0x11faedd0, frame=2238)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/util/Scheduler.cpp:89
#14 0x00007fa6974bc6f7 in circuit::CCircuitAI::Update (this=0x30c61440, frame=2238) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:610
#15 0x00007fa6974b86cf in circuit::CCircuitAI::HandleGameEvent (this=0x30c61440, topic=3, data=0x7fffe960f230)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:155
#16 0x00007fa6974b834c in circuit::CCircuitAI::HandleEvent (this=0x30c61440, topic=3, data=0x7fffe960f230)
at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:113
#17 0x00007fa6974b3ab2 in handleEvent (skirmishAIId=2, topic=3, data=0x7fffe960f230) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/AIExport.cpp:75
#18 0x0000000000b10828 in CSkirmishAILibrary::HandleEvent (this=0x43743a0, skirmishAIId=2, topic=3, data=0x7fffe960f230)
at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAILibrary.cpp:94
#19 0x0000000000b1531b in CSkirmishAIWrapper::HandleEvent (this=0x11d87e40, topic=3, data=0x7fffe960f230)
at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:463
#20 0x0000000000b15092 in CSkirmishAIWrapper::Update (this=0x11d87e40, frame=2238) at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:410

Obey disabled units

Circuit ignores the removal or disabling of commands from units build menus. If the commanders are blocked in AllowCommand or AllowUnitCreation then the AI does not adapt, it just sits there and does nothing. I've implemented locks again, see: ZeroK-RTS/Zero-K@d3c3154

In case AIs cannot read the fact that commands are missing or disabled I added TeamRulesParam unlockedUnitCount. If unlockedUnitCount is set (non-nil) then there is a limited set of units unlocked. These units are by unit def name and are stored in the TeamRulesParams unlockedUnit1, unlockedUnit2, ..., unlockedUnit.

Check internal unit name rename compatibility

Many of the internal names of the ZK units have been changed for improved consistency. The branch is here: https://github.com/ZeroK-RTS/Zero-K/tree/internalrename

Here is a complete list of the changes: ZeroK-RTS/Zero-K#1596 (comment)

While doing the changes we included the circuit configs and changed the unit names with with the same find/replace. The modified configs are here: https://github.com/ZeroK-RTS/Zero-K/tree/internalrename/AI

I am going to update the configs in chobby manually, probably by next Tuesday looking at my schedule. Development circuit should use the new configs once they are tested. If circuit has hardcoded internal unit names anywhere then it is likely to require a release.

Add a factory grace time parameter

There is a remaining minor issue with the very easy config: circuit can send scouts at the player within the first few minutes of the game. I do not want to disable scouting or raiding because it is good to poke the player with lone cheap units once they have a bit of defense. The only issue is that the units appear too early, they can disrupt the players attempt to figure things out.

The simplest way to fix this would be with a parameter that prevents factory production for the first X seconds. I would probably set it at around 6 minutes to ensure that the player first encounters opposition at around 8-10 minutes unto the game.

`disableduntis` modoption: handle regular names

The disabledunits modoption handles both internal (eg. cloakraid) and regular (eg. Glaive) names but Circuit only works with the internal name.

std::regex patternDisabled("disabledunits=(.*);", std::regex::ECMAScript | std::regex::icase);

Some regular names may map to multiple internal ones (eg Assault Commander -> dynassault1, dynassault2...) in which case they are all supposed to be disabled. I think no such unit is buildable though.

Feature: Ignoring certain units

I would like to be able to disable/enable AI control of particular units with a gadget. I would set a UnitRulesParam on the unit and give it orders directly with the gadget. When the unit is back to being controlled by the AI the UnitRulesParam would be removed.

crash (SIGFPE) in IFighterTask::OnUnitDamaged

spring 100.0.1-1191-gc91bcd6 debug
CircuitAI v0.8.1-3-g36a6b99

I suspect IFighterTask::target points to something that has been deleted.
It looks like you only delete CEnemyUnit in CCircuitAI::UnregisterEnemyUnit and CCircuitAI::UpdateEnemyUnits(), perhaps you don't set IFighterTask::target to nullptr properly when a CEnemyUnit is deleted.

`
(gdb) bt
#0 0x00007f8e0834c3ce in float3::SqDistance2D (this=0x7f8e05d43450, f=...) at /home/johanr/my_projects/spring/rts/System/float3.h:630
#1 0x00007f8e084b2a69 in circuit::IFighterTask::OnUnitDamaged (this=0x7f8e1de17680, unit=0x7f8e0c7bcf70, attacker=0x0)

at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/fighter/FighterTask.cpp:101

#2 0x00007f8e08371291 in circuit::CMilitaryManager::CMilitaryManager(circuit::CCircuitAI_)::{lambda(circuit::CCircuitUnit_, circuit::CEnemyUnit_)#6}::operator()(circuit::CCircuitUnit_, circuit::CEnemyUnit*) const () at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.cpp:114
#3 0x00007f8e0837655c in std::_Function_handler<void(circuit::CCircuitUnit*, circuit::CEnemyUnit*), circuit::CMilitaryManager::CMilitaryManager(circuit::CCircuitAI*)::<lambda(circuit::CCircuitUnit*, circuit::CEnemyUnit*)> >::_M_invoke(const std::_Any_data &, <unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.8.1/libSkirmishAI.so, CU 0xabc2d, DIE 0x1292fc>, <unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.8.1/libSkirmishAI.so, CU 0xabc2d, DIE 0x129301>) (__functor=...,

__args#0=<unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.8.1/libSkirmishAI.so, CU 0xabc2d, DIE 0x1292fc>, 
__args#1=<unknown type in /home/johanr/spring_develop_debug/share/games/spring/AI/Skirmish/CircuitAI/0.8.1/libSkirmishAI.so, CU 0xabc2d, DIE 0x129301>)
at /usr/include/c++/5.3.0/functional:1871

#4 0x00007f8e0834faa1 in std::function<void (circuit::CCircuitUnit*, circuit::CEnemyUnit*)>::operator()(circuit::CCircuitUnit_, circuit::CEnemyUnit_) const (

this=0x7f8e04f23d60, __args#0=0x7f8e0c7bcf70, __args#1=0x0) at /usr/include/c++/5.3.0/functional:2267

#5 0x00007f8e08372497 in circuit::CMilitaryManager::UnitDamaged (this=0x7f8e050830d0, unit=0x7f8e0c7bcf70, attacker=0x0)

at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.cpp:262

#6 0x00007f8e084097e6 in circuit::CCircuitAI::UnitDamaged (this=0x7f8e1dda3cc0, unit=0x7f8e0c7bcf70, attacker=0x0)

at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:662

#7 0x00007f8e08405637 in circuit::CCircuitAI::HandleGameEvent (this=0x7f8e1dda3cc0, topic=9, data=0x7fff84f1b1a0)

at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:174

#8 0x00007f8e08404cc8 in circuit::CCircuitAI::HandleEvent (this=0x7f8e1dda3cc0, topic=9, data=0x7fff84f1b1a0)

at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:100

#9 0x00007f8e0854eb28 in handleEvent (skirmishAIId=1, topic=9, data=0x7fff84f1b1a0) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/AIExport.cpp:75
#10 0x0000000000bcfa4a in CSkirmishAILibrary::HandleEvent (this=0x42757a0, skirmishAIId=1, topic=9, data=0x7fff84f1b1a0)

at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAILibrary.cpp:94

#11 0x0000000000bd470f in CSkirmishAIWrapper::HandleEvent (this=0x7f8e1b898a00, topic=9, data=0x7fff84f1b1a0)

at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:471

#12 0x0000000000bd41dd in CSkirmishAIWrapper::UnitDamaged (this=0x7f8e1b898a00, unitId=5244, attackerUnitId=-1, damage=11.2414055, dir=..., weaponDefId=1081, paralyzer=false)

at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:348

#13 0x0000000000b9fa4d in CEngineOutHandler::UnitDamaged (this=0x26c3480, damaged=..., attacker=0x0, damage=11.2414055, weaponDefID=1081, projectileID=-1, paralyzer=false)

at /home/johanr/my_projects/spring/rts/ExternalAI/EngineOutHandler.cpp:456

#14 0x0000000000f03d0b in CUnit::DoDamage (this=0x7f8e1a038000, damages=..., impulse=..., attacker=0x0, weaponDefID=1081, projectileID=-1)

at /home/johanr/my_projects/spring/rts/Sim/Units/Unit.cpp:1386

`
(gdb) p target->pos
$13 = {
= {
static CMP_EPS = 9.99999975e-05,
static NORMALIZE_EPS = 9.99999996e-13,
static maxxpos = 10239,
static maxzpos = 5119,
{
{
x = 2.01941671e-19,
y = 2.90873529e+32,
z = 2.47243338e+32
},

(gdb) p target->unit
$14 = (springai::Unit *) 0x57

(gdb) p target->unit->GetDef()
Cannot access memory at address 0x57

Windows gcc 5.3.0, memory corruption

Circuit compiled with gcc 5.3.0 on windows runs with memory corruption.
Crash appears after UnitDef::GetCustomParams call inside CCircuitDef constructor.

Official spring and AI interface compiled with 4.8.1 (windows), 4.8.5 (linux)

4.9.3 works fine.

std::thread fail

linux gcc4.9.4 fails to create std::thread from static member function.

#0  0x000000000103f77e in std::__shared_count<(__gnu_cxx::_Lock_policy)2>::operator=(std::__shared_count<(__gnu_cxx::_Lock_policy)2> const&) ()
#1  0x000000000103fa5b in std::thread::_M_start_thread(std::shared_ptr<std::thread::_Impl_base>) ()
#2  0x00007fffb3083860 in std::thread::thread<void (*)()> (__f=<optimized out>, this=0x7fffffffd5f0) at /usr/include/c++/4.9/thread:138
#3  circuit::CScheduler::RunParallelTask (this=0x8a26bb0, task=std::shared_ptr (count 1, weak 0) 0x3b333af0, onComplete=std::shared_ptr (count 1, weak 0) 0x8a23580)
    at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/circuit/util/Scheduler.cpp:117
#4  0x00007fffb3032695 in circuit::CTerrainData::CheckHeightMap (this=0x8a491e8)
    at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/circuit/terrain/TerrainData.cpp:628
#5  0x00007fffb3087e2a in circuit::CGameTask::Run (this=<optimized out>) at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/circuit/util/GameTask.cpp:26
#6  0x00007fffb3081abb in circuit::CScheduler::ProcessTasks (this=0x8a26bb0, frame=frame@entry=599)
    at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/circuit/util/Scheduler.cpp:89
#7  0x00007fffb308b1ee in circuit::CCircuitAI::Update (this=0x8a20a20, frame=599) at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:561
#8  0x00007fffb308d29f in circuit::CCircuitAI::HandleGameEvent (this=0x8a20a20, topic=3, data=0x7fffffffd9c0)
    at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:137
#9  0x00007fffb30d0353 in handleEvent (skirmishAIId=0, topic=3, data=0x7fffffffd9c0) at /home/bob/devel/games/spring/AI/Skirmish/CircuitAI/src/AIExport.cpp:75
...
#21 0x00007ffff6609291 in __libc_start_main () from /usr/lib/libc.so.6
#22 0x00000000005194a9 in _start ()

Bug appeared after great boost exodus:
103.0.1-208-g01263c9 - works
103.0.1-212-gb3053a0 - fails

Workaround: ae1ff03

Anti Nuke and screamer

hi, i dont know if i am at the good place but the AI need made Anti nuke when he see a Silencer or a nuke and perhaps protect his singu with screamer, its easy to raid it with bomber

make it work with latest develop

Even if latest spring/develop is a bit of a mess atm it would be nice if you could make it work with it.

[f=-000001] Loading Skirmish AIs
[SharedLibrary.c::sharedLib_load(/home/johanr/spring_develop/share/games/spring/AI/Skirmish/CircuitAI/0.9.10/libSkirmishAI.so)] dlopen() error /home/johanr/spring_develop/share/games/spring/AI/Skirmish/CircuitAI/0.9.10/libSkirmishAI.so: undefined symbol: _ZN12spring_futexD1Ev
[f=-000001] [C Interface] Error: Failed loading shared library: /home/johanr/spring_develop/share/games/spring/AI/Skirmish/CircuitAI/0.9.10/libSkirmishAI.so
[f=-000001] Error: Skirmish AI CircuitAI-0.9.10 not found!
The game will go on without it.
This usually indicates a problem in the used AI Interface library (-),
or the Skirmish AI library is not in the same place as its AIInfo.lua.

Actual very easy mode

How hard is it to implement something like ZeroK-RTS/Zero-K#2179 in Circuit? Would it be a lot of work? It would involve disabling most clever things Circuit does, like porc avoidance, retreat to repair, not excessing all of your metal, and I don't know how deeply those are wired in.

possible problem with dev vs stable version strings

When I start a debug spring running circuit the assert at rts/ExternalAI/SkirmishAIHandler.cpp:238 fails.
I see that spring code expect version to be "stable" but it is "dev".
When/if you reproduce this make sure you have a "clean" share/games/spring/AI/Skirmish/CircuitAI/.

Circuit AI limited units issue

A circuit AI with these units unlocked plops a factory and never builds anything with it:

  • "factorycloak",
  • "corllt",
  • "cormex",
  • "armsolar",
  • "armwar",

set_erase -> spring::map_erase_if

Not really a bug but my patch for late changes to spring/develop may save you some time:

@@ -52,16 +52,11 @@ bool TdfParser::TdfSection::remove(const std::string& key, bool caseSensitive)
        }
    } else {
        // don't assume <key> is already in lowercase
        const std::string lowerKey = StringToLower(key);
-       for (valueMap_t::iterator it = values.begin(); it != values.end(); ) {
-           if (StringToLower(it->first) == lowerKey) {
-               it = set_erase(values, it);
-               ret = true;
-           } else {
-               ++it;
-           }
-       }
+       spring::map_erase_if(values, [lowerKey](const decltype(values)::value_type& p) {
+           return StringToLower(p.first) == lowerKey;
+       });

two SIGFPE found when testing with Debug spring

Spring 103.0.1-519-g91b0000b2 develop (Debug Signal-NaNs)

SIGFPE in CThreatMap::GetUnitThreat, sqrtf dislikes negative values.

(gdb) bt
#0  0x00007f150c7db2b9 in sqrtf () from /usr/lib/libm.so.6
#1  0x00007f14e9b7b6f6 in circuit::CThreatMap::GetUnitThreat (this=0x336fd510, unit=0x30468700)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/terrain/ThreatMap.cpp:391
#2  0x00007f14e9b00653 in circuit::CRetreatTask::Execute (this=0x30be0bc0, unit=0x30468700)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/RetreatTask.cpp:124
#3  0x00007f14e9b029e6 in circuit::ITaskManager::AssignTask (this=0x372c9828, unit=0x30468700, task=0x30be0bc0)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/TaskManager.cpp:32
#4  0x00007f14e9b21f47 in circuit::IFighterTask::OnUnitDamaged (this=0x3310e60, unit=0x30468700, attacker=0x31318960)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/fighter/FighterTask.cpp:115

(gdb) f 1
#1  0x00007f14e9b7b6f6 in circuit::CThreatMap::GetUnitThreat (this=0x336fd510, unit=0x30468700)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/terrain/ThreatMap.cpp:391
391		return unit->GetDamage() * sqrtf(health);  // / unit->GetUnit()->GetMaxHealth();

(gdb) p health 
$1 = -88

(gdb) p unit->shield
$3 = (springai::Weapon *) 0x0

SGIFPE in CSetupData::ParseSetupScript (engine way) due to CAllyTeam::SBox not initialised.
I have no startrect in my start script so startbox.right *= width; caused SIGFPE.

Here are my quick fix for these two SIGFPE:

CircuitAI]$ git diff
diff --git a/src/circuit/terrain/ThreatMap.cpp b/src/circuit/terrain/ThreatMap.cpp
index 5d061d7..0306c67 100644
--- a/src/circuit/terrain/ThreatMap.cpp
+++ b/src/circuit/terrain/ThreatMap.cpp
@@ -388,7 +388,7 @@ float CThreatMap::GetThreatAt(CCircuitUnit* unit, const AIFloat3& position) cons
 float CThreatMap::GetUnitThreat(CCircuitUnit* unit) const
 {
        float health = unit->GetUnit()->GetHealth() + unit->GetShieldPower() * 2.0f;
-       return unit->GetDamage() * sqrtf(health);  // / unit->GetUnit()->GetMaxHealth();
+       return unit->GetDamage() * sqrtf(std::max(health, 0.f));  // / unit->GetUnit()->GetMaxHealth();
 }
 
 void CThreatMap::AddEnemyUnit(const CEnemyUnit* e)
diff --git a/src/circuit/unit/AllyTeam.h b/src/circuit/unit/AllyTeam.h
index 864b995..ee78bd2 100644
--- a/src/circuit/unit/AllyTeam.h
+++ b/src/circuit/unit/AllyTeam.h
@@ -33,6 +33,7 @@ public:
        using Units = std::map<CCircuitUnit::Id, CCircuitUnit*>;
        using TeamIds = std::unordered_set<Id>;
        union SBox {
+               SBox(): edge{0.f,0.f,0.f,0.f} {}
                struct {
                        float bottom;
                        float left;

compile error

AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.h:124:104: error: array must be initialized with a brace-enclosed initializer
std::array<float, static_castCCircuitDef::RoleT(CCircuitDef::RoleType::TOTAL_COUNT)> enemyMetals{0.f};
^
AI/Skirmish/CircuitAI/src/circuit/module/MilitaryManager.h:129:104: error: array must be initialized with a brace-enclosed initializer
std::array<float, static_castCCircuitDef::RoleT(CCircuitDef::RoleType::TOTAL_COUNT)> roleMetals{0.f};

More handling for load game

Circuit probably needs a lot of work to handle loaded games well. One think I noticed that is if it is building a Dante then the Striderhub will not correctly repair the nanoframe after the game is loaded. Taking advantage of half complete striders with striderhubs would solve this.

make it build and run with latest spring and gcc (arch 7.1.1)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index eea89b1..1944a7f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@
 #
 
 set(mySourceDirRel         "src/") # Common values are "" or "src"
-set(additionalSources      ${CMAKE_SOURCE_DIR}/rts/System/Util.cpp)
+set(additionalSources      ${CMAKE_SOURCE_DIR}/rts/System/StringUtil.cpp)
 set(additionalSources      ${additionalSources} ${CMAKE_SOURCE_DIR}/rts/System/Misc/SpringTime.cpp)
 if (WIN32)  # spring::condition_variable_any requirement
 	set(additionalSources  ${additionalSources} ${CMAKE_SOURCE_DIR}/rts/System/Platform/Win/CriticalSection.cpp)
diff --git a/src/circuit/CircuitAI.cpp b/src/circuit/CircuitAI.cpp
index 612a497..b23c01b 100644
--- a/src/circuit/CircuitAI.cpp
+++ b/src/circuit/CircuitAI.cpp
@@ -24,7 +24,7 @@
 #include "resource/EnergyGrid.h"
 #endif
 
-#include "System/Util.h"
+#include "System/StringUtil.h"
 #include "AISEvents.h"
 #include "AISCommands.h"
 #include "SSkirmishAICallback.h"	// "direct" C API
diff --git a/src/circuit/setup/SetupManager.h b/src/circuit/setup/SetupManager.h
index daa7aaa..2cd0d28 100644
--- a/src/circuit/setup/SetupManager.h
+++ b/src/circuit/setup/SetupManager.h
@@ -10,8 +10,8 @@
 
 #include "unit/CircuitDef.h"
 #include "json/json-forwards.h"
-
 #include "AIFloat3.h"
+#include <functional>
 
 namespace circuit {
 
diff --git a/src/circuit/util/GameTask.h b/src/circuit/util/GameTask.h
index 76ddb04..1f11d91 100644
--- a/src/circuit/util/GameTask.h
+++ b/src/circuit/util/GameTask.h
@@ -10,6 +10,7 @@
 #define SRC_CIRCUIT_UTIL_GAMETASK_H_
 
 #include <memory>
+#include <functional>
 
 namespace circuit {
 
@@ -17,7 +18,7 @@ class CGameTask {
 public:
 	template<typename _Callable, typename... _Args>
 		explicit CGameTask(_Callable&& __f, _Args&&... __args) {
-			__b = _M_make_routine(std::__bind_simple(std::forward<_Callable>(__f), std::forward<_Args>(__args)...));
+			__b = _M_make_routine(std::bind(std::forward<_Callable>(__f), std::forward<_Args>(__args)...));
 		}
 	virtual ~CGameTask();
 
diff --git a/src/circuit/util/utils.h b/src/circuit/util/utils.h
index 9cf5b47..e929d7d 100644
--- a/src/circuit/util/utils.h
+++ b/src/circuit/util/utils.h
@@ -10,7 +10,7 @@
 
 #include "util/Defines.h"
 
-#include "System/Util.h"
+#include "System/StringUtil.h"
 #include "System/Threading/SpringThreading.h"
 #include <chrono>

There is a SIGSEGV at game end but it may be a spring (103.0.1-1017-gfe0d9ebd8) issue:

#0  0x000000003fa37e00 in ?? ()
#1  0x00007f7501e63b48 in circuit::CTerrainManager::MarkBlockerByMask (this=this@entry=0x113f8d10, building=..., block=<optimized out>, mask=0x3fa57a48)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/terrain/TerrainManager.cpp:924
#2  0x00007f7501e64860 in circuit::CTerrainManager::MarkBlocker (this=this@entry=0x113f8d10, building=..., block=block@entry=false)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/terrain/TerrainManager.cpp:993
#3  0x00007f7501e64bbc in circuit::CTerrainManager::DelBlocker (this=0x113f8d10, cdef=<optimized out>, pos=..., facing=3)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/terrain/TerrainManager.cpp:335
#4  0x00007f7501e37299 in circuit::IUnitTask::Close (this=this@entry=0x2b393960, done=<optimized out>)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/UnitTask.cpp:66
#5  0x00007f7501e3a1fd in circuit::IBuilderTask::Close (this=0x2b393960, done=<optimized out>)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/task/builder/BuilderTask.cpp:231
#6  0x00007f7501dc34e5 in circuit::CBuilderManager::DequeueTask (this=<optimized out>, task=0x2b393960, done=<optimized out>)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/BuilderManager.cpp:606
#7  0x00007f7501dc2a90 in circuit::CBuilderManager::Release (this=0x376f7b90)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/module/BuilderManager.cpp:828
#8  0x00007f7501da7dd8 in circuit::CCircuitAI::Release (this=0x37db1000, reason=-1) at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:635
#9  0x00007f7501dac679 in circuit::CCircuitAI::HandleGameEvent (this=0x37db1000, topic=2, data=0x7ffe65329880)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/circuit/CircuitAI.cpp:205
#10 0x00007f7501da4af0 in handleEvent (skirmishAIId=<optimized out>, topic=2, data=0x7ffe65329880)
    at /home/johanr/my_projects/spring/AI/Skirmish/CircuitAI/src/AIExport.cpp:75
#11 0x0000000000934deb in CSkirmishAILibrary::HandleEvent (this=0x65d90e0, skirmishAIId=2, topic=topic@entry=2, data=data@entry=0x7ffe65329880)
    at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAILibrary.cpp:94
#12 0x00000000009380c8 in CSkirmishAIWrapper::HandleEvent (this=this@entry=0x118c84e0, topic=topic@entry=2, data=data@entry=0x7ffe65329880)
    at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:467
#13 0x00000000009382a3 in CSkirmishAIWrapper::Release (reason=<optimized out>, this=0x118c84e0) at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:238
#14 CSkirmishAIWrapper::~CSkirmishAIWrapper (this=0x118c84e0, __in_chrg=<optimized out>) at /home/johanr/my_projects/spring/rts/ExternalAI/SkirmishAIWrapper.cpp:117
#15 0x00000000009116a6 in std::default_delete<CSkirmishAIWrapper>::operator() (this=<optimized out>, __ptr=0x118c84e0) at /usr/include/c++/7.1.1/bits/unique_ptr.h:78
#16 std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> >::~unique_ptr (this=<optimized out>, __in_chrg=<optimized out>)
    at /usr/include/c++/7.1.1/bits/unique_ptr.h:268
#17 std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >::~pair (this=<optimized out>, __in_chrg=<optimized out>)
    at /usr/include/c++/7.1.1/bits/stl_pair.h:198
#18 __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::destroy<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > (this=<optimized out>, __p=<optimized out>)
    at /usr/include/c++/7.1.1/ext/new_allocator.h:140
#19 std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > > >::destroy<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > (__a=..., __p=<optimized out>)
    at /usr/include/c++/7.1.1/bits/alloc_traits.h:487
#20 std::_Rb_tree<unsigned char, std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >, std::_Select1st<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::_M_destroy_node (this=0x64c8900, __p=0x3d494810)
    at /usr/include/c++/7.1.1/bits/stl_tree.h:650
#21 std::_Rb_tree<unsigned char, std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >, std::_Select1st<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::_M_drop_node (this=0x64c8900, __p=0x3d494810) at /usr/include/c++/7.1.1/bits/stl_tree.h:658
#22 std::_Rb_tree<unsigned char, std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >, std::_Select1st<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::_M_erase (this=this@entry=0x64c8900, __x=0x3d494810)
    at /usr/include/c++/7.1.1/bits/stl_tree.h:1858
#23 0x0000000000911756 in std::_Rb_tree<unsigned char, std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >, std::_Select1st<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::clear (this=0x64c8900) at /usr/include/c++/7.1.1/bits/stl_tree.h:1171
#24 std::_Rb_tree<unsigned char, std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >, std::_Select1st<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::_M_erase_aux (__last={
  first = 1 '\001', 
  second = std::unique_ptr<CSkirmishAIWrapper> containing 0x0
}, __first=..., this=0x64c8900) at /usr/include/c++/7.1.1/bits/stl_tree.h:2488
#25 std::_Rb_tree<unsigned char, std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > >, std::_Select1st<std::pair<unsi---Type <return> to continue, or q <return> to quit---
gned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::erase (this=this@entry=0x64c8900, __x=@0x7ffe6532996c: 2 '\002')
    at /usr/include/c++/7.1.1/bits/stl_tree.h:2502
#26 0x00000000009106c1 in std::map<unsigned char, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> >, std::less<unsigned char>, std::allocator<std::pair<unsigned char const, std::unique_ptr<CSkirmishAIWrapper, std::default_delete<CSkirmishAIWrapper> > > > >::erase (__x=@0x7ffe6532996c: 2 '\002', this=0x64c8900)
    at /usr/include/c++/7.1.1/bits/stl_map.h:1048
#27 CEngineOutHandler::DestroySkirmishAI (this=this@entry=0x64c8900, skirmishAIId=<optimized out>) at /home/johanr/my_projects/spring/rts/ExternalAI/EngineOutHandler.cpp:621
#28 0x00000000009108d0 in CEngineOutHandler::~CEngineOutHandler (this=0x64c8900, __in_chrg=<optimized out>)
    at /home/johanr/my_projects/spring/rts/ExternalAI/EngineOutHandler.cpp:83
#29 0x0000000000910941 in spring::SafeDelete<CEngineOutHandler*> (p=@0xeaf0a0: 0x0) at /home/johanr/my_projects/spring/rts/System/SafeUtil.h:22
#30 CEngineOutHandler::Destroy () at /home/johanr/my_projects/spring/rts/ExternalAI/EngineOutHandler.cpp:71
#31 0x0000000000499f91 in CGame::KillMisc (this=this@entry=0x3f6bc00) at /home/johanr/my_projects/spring/rts/Game/Game.cpp:825
#32 0x00000000004a555e in CGame::~CGame (this=0x3f6bc00, __in_chrg=<optimized out>) at /home/johanr/my_projects/spring/rts/Game/Game.cpp:321
#33 0x00000000004a5729 in CGame::~CGame (this=0x3f6bc00, __in_chrg=<optimized out>) at /home/johanr/my_projects/spring/rts/Game/Game.cpp:335
#34 0x0000000000896588 in spring::SafeDelete<CGame*> (p=<optimized out>) at /home/johanr/my_projects/spring/rts/System/SafeUtil.h:22
#35 SpringApp::ShutDown (fromRun=fromRun@entry=true) at /home/johanr/my_projects/spring/rts/System/SpringApp.cpp:878
#36 0x00000000008988e2 in SpringApp::ShutDown (fromRun=true) at /home/johanr/my_projects/spring/rts/System/SpringApp.cpp:820
#37 SpringApp::Run (this=this@entry=0x7ffe65329b20) at /home/johanr/my_projects/spring/rts/System/SpringApp.cpp:835
#38 0x000000000087ee29 in Run (argc=argc@entry=2, argv=argv@entry=0x7ffe65329cc8) at /home/johanr/my_projects/spring/rts/System/Main.cpp:43
#39 0x000000000045d655 in main (argc=2, argv=0x7ffe65329cc8) at /home/johanr/my_projects/spring/rts/System/Main.cpp:92

0.9.11 odd behaviour

Using this bug report as feedback. Take a good look at the following replays to see a bunch of bad stuff:
http://zero-k.info/Battles/Detail/441874
http://zero-k.info/Battles/Detail/441878
http://zero-k.info/Battles/Detail/441882

A few things i think can be improved:

  • bomb firewalkers, they are often ignored by bombers
  • push front harder, e.g. units are often going back for no apparent reason and i think circuit should build more cheap units to push front mid/late game
  • use snipers at front, also a bunch of other units just stay at a rear bases
  • not suicide so many Wyverns bombing e.g. Stingers under shields, prio e.g. long range units and unit blobs

CircuitAI looks like a passive porc AI after early game.
You can close this issue after you have watched the replays :).

Consider CMD_RAW_MOVE

Players barely give CMD.MOVE commands anymore in ZK since it has been replaced with CMD_RAW_MOVE. This replacement move command causes units to move directly in a direction, without invoking the pathfinder, if the direct path is free.

I have noticed that circuit games have high sim::path in profiling, around 9%. Circuit seems to primarily issue very short move orders and implement its own pathfinding so perhaps it would run smoother with CMD_RAW_MOVE.

can't be run when started via ./spring

compile latest spring develop + circuitai, start ./spring
select zero-k 1.5.5.1 + some map + CircuitAI

->
[f=-000001] Skirmish AI : Missing config file! (LuaRules/Configs/CircuitAI/stable/DeltaSiegeDry.json)
[f=-000001] Skirmish AI : Missing config file! (LuaRules/Configs/CircuitAI/stable/Default/circuit.json)
[f=-000001] Skirmish AI : Config file is missing! (circuit.json)
Execute: int circuit::CCircuitAI::Release(int)
[f=-000001] Warning: AI for team 1 (ID: 0) failed handling event with topic 1, error: 201
[f=-000001] Error: Failed to handle init event: AI for team 1, error 201

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.