Page 1 of 1

AI Project

Posted: Sat Mar 03, 2012 9:16 am
by Spocks-cuddly-tribble
Altering the bugged AI behavior has been the goal of many mods, but foiled by the very intricate/inefficient implementation in trek.exe. Nevertheless, I've found a very useful piece to the jigsaw. :)

:arrow: AI Task Modifiers (ds:58AFEC)

Address of the two byte modifiers in trek.exe at 0x188DEC + (race ID * 144h) + (task ID * 12h) + (agenda ID * 2)

To get a better overview copy & paste the whole 0x144 byte tables into new hex-editor windows (one for each empire) and set them to 18 bytes per row. Each line represents a task and each two byte column an agenda.

Task IDs: (ship tasks according to sub_4E4218)
Explore (0)
Raid (1)
Colonize (2)
Tform (3)
Develop System (4)
Build Ship (5)
Buildbase (6)
Invade (7)
Accept Proposal (8) default modifier -1
Offer Proposal (9)
Attack (A)
Build Wonder (B)
Patrol (C)
Train (D)
Repair (E)
Harass (F)
There is space for two more tasks (IDs 0x10 & 0x11) but code seems to indicate they're not implemented. Also expect unused tasks (cf. tactical cloak) and maybe not all AI tasks use the modifiers.

Agenda IDs: (set by sub_406990)
DCER wrote:Normal Expansion (0)
Unopposed Expansion (1)
Normal Consolidation (2)
Defensive Consolidation (3)
Offensive Consolidation (4)
Cold War (5)
Defensive War (6)
Offensive War (7)
Jihad (8 )
Default range of the modifiers is between 0 and 10 resp -1 for task ID 8. Higher values are possible. I successfully tested colonization modifiers of 0x32 (for all 9 cardassian task 2 agendas), observing a more aggressive colonization behavior.

Re: AI Project

Posted: Sat Mar 03, 2012 9:39 am
by Flocke
cool stuff, am sure AI can be tweaked alot! :)

Re: AI Project

Posted: Sat Mar 03, 2012 3:27 pm
by thunderchero
Nice piece of the puzzle agreed, :wink:

I wonder if the table could be increased to include minors :D (I know I am just dreaming)


Re: AI Project

Posted: Sat Mar 03, 2012 5:58 pm
by Peter1981
Spocks-cuddly-tribble wrote:I successfully tested colonization modifiers of 0x32 (for all 9 cardassian task 2 agendas), observing a more aggressive colonization behavior.
This may hold the promise to solve one of the most obvious AI flaws. Good work SCT :D

Re: AI Project

Posted: Sat Mar 03, 2012 9:40 pm
by Tethys
Just some thoughts on the ones that are still unknown, hopefully some will be right :lol: :

Enter wormhole
Fleet (re)deployment

Re: AI Project

Posted: Tue Mar 06, 2012 3:30 pm
by Spocks-cuddly-tribble
The missing AI tasks are: (4, 5 & B system tasks)

Develop System 4
Build Ship 5
Accept Proposal 8 (default -1)
Offer Proposal 9
Build Wonder B

Expect unused tasks and/or modifiers. For instance proposal modifiers of 0 did not prevent the AI from accepting/offering non-aggression.

thunderchero wrote:I wonder if the table could be increased to include minors
We know the modifiers can inhibit some ship tasks but not set them. Maybe 10+ just means limit is disabled?

For minor race ship tasks see sub_414E50. There are references to Explore, Patrol, Raid and Harass (Harass = bomb systems?).

If you want to have a look, here is my IDA-database: (labeled on the fly, so expect errors) ... k.idb.html
The Raid / Harass random switch at asm-414C51 could be replaced with a minor race personality check. However, it's too soon to waste time with in-depth editings. We first need to understand the whole mechanics.

AI Buying Behavior

Posted: Thu Mar 15, 2012 4:10 pm
by Spocks-cuddly-tribble
Another step closer to controlling AI tasks. :)

Three categories of expenditures (ships, buildings and gifts) are sorted by priority 1-3 in two identical tables in trek.exe.

0x188DB0 (asm-58AFB0) -> credit allotments (aka budget limits)
0x18A048 (asm-58C248) -> chronology of purchase orders

Set to 12 bytes per row we see the default priorities 1-3 for AI empires card-rom:

Code: Select all

01 00 00 00 04 00 00 00 03 00 00 00
03 00 00 00 04 00 00 00 01 00 00 00
04 00 00 00 03 00 00 00 01 00 00 00
01 00 00 00 04 00 00 00 03 00 00 00
04 00 00 00 01 00 00 00 03 00 00 00
01 = Ships
03 = Gifts/Offers
04 = Buildings/Upgrades

First the AI determines its budget limit by substracting a reserve fund of 5 times effective fleet support cost from the current total credits (if fleet cost is larger than pop support). Another unkown value gets substracted, but most likely it's zero due to broken code and meant to be treaty costs per turn.

This result gets compared with the nominal income and the greater value is used as budget limit for priority 1 tasks. After that, the budget limit for priorities 2 and 3 is obtained by successively substracting the lower values each i.e. by increasing the untouchable reserve fund.


Klingon AI; 12000 credits, 1000 income, 300 credits/turn effective fleet support cost

Budget limits for buying: (reduced after each purchase order)

12000 -1500(5*300) = 10500 (Ships 01) -> unusable reserve = 1500
10500 -1000 = 9500 (Buildings/Upgrades 04) -> unusable reserve = 2500
9500 -1000 = 8500 (Gifts/Offers 03) -> unusable reserve = 3500

The chronology of the purchase orders, i.e. the category priorities from table 0x18A048, is skipped if the AI loses all shipyards, refineries or the territory is threatened. In this case the chronology is: 1. Gifts/Offers, 2. Ships, 3. Buildings/Upgrades. It's the same check for triggering the emergency ship building agenda: viewtopic.php?p=34142&sid=2ecf63a015a38 ... 6e1#p34142

Every item gets purchased if not prevented by the corresponding budget limit. Unlike ships and buildings the AI just lowers the amount of Gifts/Offers if insufficient credits instead to skip them. viewtopic.php?p=24148&sid=2ecf63a015a38 ... 6e1#p24148

Displaying AI Datas on the Map

Posted: Mon Mar 26, 2012 6:34 am
by Spocks-cuddly-tribble
A diagnostic development feature enables viewing of 24 types of AI map data.

0x193674 (default 01) -> 0 = show AI data if "Build Tasks" are turned off
0x193678 (default 01) -> 0-17h = map ai data type
0xE6BC6 (default 30 D2) -> B2 0X = show data of AI empire ID X (next ID if player, default 0 card)

Hotkey control would be more comfortable, but seems to be not pre-installed.

Index code key of the "map ai data type" switch: (at asm-4E7430)

0 'Sector Density' (based on nearby map objects, own systems do not count)
1 'Current Build' (most trade goods, AI gives orders between turns)
2 'Current System Class' (property type)
3 'All System Classes' (property potential)
4 'Sectors Scanned'
5 'System Production' (output values)
6 'Ship Tasks' (token)
7 'Ship List (%s)' (detailed task list)
8 'Population Data' (laborer assignations)
9 'Territory' (sector claims)
A 'Border Influence' (claim predictors)
B 'System Colonization Value (%s)' (base layer)
C 'System Colonization Priority (%s)'
D 'Rights of Passage (%s)' (sectors not accessible)
E 'Task List (%s)' (agenda, production focus & planned tasks)
F 'Game Statistics' (economic & military power)
10 'Local Advantage (%s)' (range class of possible target systems)
11 'Staging Points (%s)' (mark closest opponent systems with XXX)
12 'Diplomatic Info'
13 'Threat Level (%s)' (depends on opponent systems in sector range)
14 'Base Placement (%s)' (sector density + own systems 100, with yard 110, anomaly = 0)
15 'Raiding Value (%s)' (nearby systems pop -system defenses)
16 'Sphere Of Influence' (purpose unknown, close to savegame file SphOfIn)
17 'Defense Patrol Points (%s)' (purpose unknown, based on own + ally territory)

Labels taken from asm-581450. 10h+ are out of sync, i.e. maybe some are wrong assigned.

Data types 7, E, F and 12h display a list instead of the map (navigation still via I, O and arrow keys).

Some datas depend on known opponents i.e. show nothing on turn 1 (e.g. 11h, 13h).

Some views are restricted to the AI's range other not (e.g. Colonization, Raiding).

When testing AI data E 'Task List (%s)', the AI's "master plan", watch for the "Build Wonder" task (still unknown).

Map datas 13h, 14h and C have a major importance and are loaded into the main AI-Agents every time a game is started or loaded.

13h View1 -> sub_419260
14h View2 -> sub_419B70 (cf. sub_41A580)
C View3 -> sub_41A6D0

'Unopposed' AI Agenda Fix

Posted: Wed Apr 20, 2016 4:55 pm
by Spocks-cuddly-tribble
DCER wrote:At the begining their agenda is Normal expansion. One would expect Unopposed expansion, but that is not the case.

'Unopposed' requires:
  • all empires unknown
  • a minimum distance of 6+ sectors between the own and all other empire home systems
However, sub_4068D0 is bizarrely flawed, even by BotF standards. It loads instead of the other empire's StarIDs always the own one for comparison.

'Unopposed' AI Agenda Fix (helps AI in the beginning of large map games)

Code: Select all

trek.exe at 0x5D05 change 0x15 bytes to

33 DB E8 A4 03 04 00 8B 04 5D 5E 23 5B 00 3A 5F 08 75 42 90 90

00406905   33DB              XOR EBX,EBX              // prepare empire ID for loop

0040690C   8B045D 5E235B00   MOV EAX, [EBX*2+5B235E]  // prepare starID from RToSInfo
00406913   3A5F 08           CMP BL, [EDI+8]          // own empire?
00406916   75 42             JNZ 40695A               // if not check distance
00406918   90 90             NOP
The minimum distance to all other home systems must be greater than: ds:576810 (default 5.0) 8 byte float

Federation AI code for Minor Races (no attacks & liberation) + Fix

Posted: Sun Dec 08, 2019 8:31 am
by Spocks-cuddly-tribble
suggestions for Terran Empire mod wrote:Here is the Federation AI special code for not attacking & liberating Minor Races. So you could switch the feature to empire ID 2 ferengi or disable via ID 5+.

Code: Select all

federation prefer to attack subjugated systems
40E958                 cmp     cx, 1 // 0xDD6E

federation don't invade free minors
40EA8E                 cmp     word ptr [ebx+8], 1 // 0xDE92

federation free subjugated minors
41E758                 cmp     word ptr [eax+8], 1 // 0x1DB5C

Federation minor race gift/traderoute bonus code

Code: Select all

-amounts- (gifts)
40780D                 cmp     ah, 1 // 0x6C0F
-effects- (gifts & traderoutes)
407B91                 cmp     ah, 1 // 0x6F93
Instead disabling/changing the empire ID, you could inverse the corresponding multipliers:

fed1 (1.5 -> 0.666)
fed2 (0.5 -> 2.0)

See Gowron 'Gifts to Minor Races' Fed1 / Fed2 values.

AI federation declares war at liberated minor races issue: viewtopic.php?f=4&t=3714#p49144

Keep AI Federation from declaring War on Minor Races (Fix)

Code: Select all

0x137FD change (0xF bytes) -> 8B 50 3C 85 D2 0F 85 5B FF FF FF 66 8B 56 08 -> 83 78 3C 00 75 25 0F B6 56 08 80 FA 01 74 05

004143FD   8378 3C 00    CMP DWORD [EAX+3C], 0    // if not a free minor...
00414401   75 25         JNZ SHORT 414428         // ...exit check next
00414403   0FB656 08     MOVZX EDX, BYTE [ESI+8]   // AI empire ID
00414407   80FA 01       CMP DL, 1                // if Federation...
0041440A   74 05         JE SHORT 414411          // ...exit check next


Here are some remaining codes for AI empire behavior. I did not analyze/manipulate them further cause it think the results will be more or less disappointing. I didn't even expect to find such codes, since the 'experienced' AI behavior appears to be allways the same (IIRC).

Code: Select all

AUTO:0041428C                 cmp     word ptr [esi+8], 1 ; Federation  0x13690 // negative diplomatic shift vs. empires with subjugated system in range of federation
AUTO:0043110E                 cmp     dx, 1               ; Federation  0x30511 // same as above but only if no score or tech deviation issue resp SphOfIn issue

AUTO:0043031A                 cmp     word ptr [ebx+8], 1 ; Federation  0x2F71E // skip Harass ship tasks when Cold War

AUTO:00422FE5                 cmp     word ptr [esi+8], 1 ; Federation  0x223E9 // some minor race attitude bonus +50

AUTO:00422FF8                 cmp     word ptr [esi+8], 0 ; Cardassians 0x223FC // some minor race attitude penalty -50

-> lower 4-byte float value seems to indicate more warlike behavior?:

58F84C AI_fleet_deviation_floats_1_2__1_3__1_3__1_1__1_25 (card-rom)
58F860 AI_mil_4_sector_distance_floats_1_35__1_5__1_7__1_2__1_5 (card-rom)

sub_430F40 for set war type, AI to AI gifts, Treaty Offers sizes & Turn lenghts
58F874 AI_fleet_values_0_5__0_9__1_75__0_5__0_5 (card-rom) -> Ferengi peak value?

sub_432390 Treaty Offers sizes & Turn lenghts (card-rom deviations)

AI Colonize, Tform & Buildbase Tasks

Posted: Sun Dec 15, 2019 4:11 pm
by Spocks-cuddly-tribble
These AI tasks are partly controlled by four subroutines which are closely related to some of the above listed map ai data types.

1.) Sub_410070 (Colonize + prior Tform if required) -> 'System Colonization Priority (%s)'

Cf. the AI minimum terraform threshold: viewtopic.php?f=222&t=1131#p16638 -> M-Class fix (410134 = nop // 0xF534 -> 75 0D to 90 90)
NOTE: If a new Task gets added (or colonize order executed?) next code 2# is skipped that turn!

2.) Sub_40FF40 (Colonize + prior Tform if required + Build Outpost) -> 'Base Placement (%s)' also influenced by 'Threat Level (%s)'

Here a build outpost task is set for the same sector, maybe to secure the location if no colony ship is available (or too far away).
Skip build outpost at the same sector ? - experimental option - (410018 = JMP 41003B // 0xF418 -> 8B 44 24 14 to EB 21 90 90)
-> M-Class fix 2 ? (40FFF8 = nop // 0xF3F8 -> 75 1E to 90 90)

3.) Sub_40F810 (Tform improve own systems) -> ... 3458f42384

Crap code in sufficient quantity to gazette this masterpiece as an undoubtful favorite for the ultimate MCA hardcore Pakled award gold.

4.) Sub_40F1B0 (Build Outpost or Starbase) -> if no Buildbase 2# since AI cannot perform more than one Buildbase task at the same time

4a - First the AI checks its own star systems whether it wants to build an outpost somewhere

4b - If not it can build an outpost outside its territory when in 'Offensive Consolidation'(sub_42A890) -> missing range check Bug

4c - If not 4a or 4b it checks again its own star systems for Outposts whether it wants to upgrade one to a Starbase

Remeber an exception for outposts outside of the AI's territory is 'Base Placement' 2#.

And now let's try to give that lazy AI some bashes: :wink:

Force AI to Tform improve all its systems (Workaround)

Code: Select all

0xEC67 change 74 26 -> EB 35
0xED24 change 75 30 -> 90 90
0xED64 change 83 3C 24 00 -> 85 FF 90 90

0040F867   EB 35            JMP 40F89E

0040F924   90 90            NOP

0040F964   85FF             TEST EDI,EDI
0040F966   90 90            NOP

Keep AI in the beginning from wasting a TT for home system outpost

Code: Select all

0xE9A6 change 0F 85 -> 90 E9

AUTO:0040F5A6   jnz -> jmp nop

AI Build Starbase Task-freeze Fix (upgrade task in sector without outpost)

Code: Select all

0xE8E1 change 8B 40 06 C1 F8 10 83 F8 FF 0F 85 (0xB bytes) -> 0F BF 40 08 83 F8 FF 74 2F 90 E9
0xE93E change 75 08 -> 90 90

0040F4E1   0FBF40 08     MOVSX EAX,WORD[EAX+8] // station Id sectorlist
0040F4E5   83F8 FF       CMP EAX,-1
0040F4E8   74 2F         JE SHORT 40F519    // no station check next system
0040F4EA   90            NOP
0040F4EB   E9 B3020000   JMP 40F7A3      // goto check starbase or outpost

0040F53E   90 90         NOP             // remove build starbase at phantom position glitch

ds:57AC44 // 0x17A844 (8 byte float) -> 0.25 = default percent done when building a Starbase

ds:576E44 Buildbase threshold 20.0 (8 byte float) at 0x174C44 (shared for all outposts & starbases @ code 4#)

Build Outpost 'offensive consolidation' missing range check fix (can also cause Build Starbase Task-freeze)

Invalid task destinations in long range, or even out of range, can spam/freeze these AI ship tasks. Note that the below fix uses a medium range limit for task coordinates i.e. works only for 'vanillaish' mods.

Also note that any kind of range loss (terminated treaty, destruction of space stations/ shipyards, energy loss of shipyards...) might stall AI ship tasks as well, especially the building of outposts & starbases within own territory!

Code: Select all

Old/default 0xE7C9 -0xE7FB (0x33 bytes)
8B 84 24 94 01 00 00 89 84 24 28 01 00 00 8B 84 24 9C 01 00 00 50 89 84 24 30 01 00 00 8B 84 24 2C 01 00 00 50 8B 84 24 A0 01 00 00 E8 56 0F 02 00 85 C0
New code:
8D 94 24 28 01 00 00 8B 4A 6C 89 0A 8B 5A 74 89 5A 04 8B 43 70 53 51 E8 6B 0F 02 00 85 C0 74 19 8A 45 08 E8 3F CA 06 00 83 F8 FF 74 0C 83 F8 02 90 90 90

0040F3C9   8D9424 28010000   LEA EDX, [ESP+128] // prepare adr coordinates
0040F3D0   8B4A 6C           MOV ECX, [EDX+6C]  // vertical Y
0040F3D3   890A              MOV [EDX], ECX
0040F3D5   8B5A 74           MOV EBX, [EDX+74]  // horizontal X
0040F3D8   895A 04           MOV [EDX+4], EBX
0040F3DB   8B43 70           MOV EAX, [EBX+70]
0040F3DE   53                PUSH EBX
0040F3DF   51                PUSH ECX
0040F3E0   E8 6B0F0200       CALL 430350      // sector available or claim issue
0040F3E5   85C0              TEST EAX, EAX
0040F3E7   74 19             JE 40F402        // next_horizontal_sector
0040F3E9   8A45 08           MOV AL, [EBP+8]  // race ID
0040F3EC   E8 3FCA0600       CALL 47BE30      // GetSectorRangeClass
0040F3F1   83F8 FF           CMP EAX, -1      // out of range
0040F3F4   74 0C             JE 40F402        // next_horizontal_sector
0040F3F6   83F8 02           CMP EAX, 2       // long range
0040F3F9   90 90 90          NOP
Note this patch is a beta version :!: Here is a patch file for testing:

AI 'Explore' Taskforce range cheats:

Code: Select all

AUTO:00417790                 cmp     eax, 0FFFFFFFFh ; if not  range -1
AUTO:00417793                 jnz     short loc_41779D
AUTO:00417795                 mov     dword ptr [esp+34h], 2 ; set long range

AUTO:004175A1                 cmp     eax, 0FFFFFFFFh ; if not  range -1
AUTO:004175A4                 jnz     short loc_4175AE
AUTO:004175A6                 mov     dword ptr [esp+38h], 2 ; set long range

Unlocking the AI Ram Command

Posted: Sat Dec 21, 2019 5:57 pm
by Spocks-cuddly-tribble
The AI's ability to use the 'ram' command in tactical combat depends on a 'pugnacity' value of 5+ against the opponent. If the value is lower 5 and it wants to use 'ram' the AI is forced to use retreat instead. :shock: - On the other hand pugnacity 5+ does not force the AI to ram if it doesn't see an opportunity to do so.

Pugnacity (sub_478108) vs players is the sum of 'hostility' (0 - 4 neutral to enraged) and 'war type' (0 - 3 peace/cold war/war/jihad) i.e. with a value range of 0 - 7.

The problem is that the pugnacity code is throttled to a max value of 4 unless jihad and even then to a maximum of 5. :dwn:

So let's get rid of that embarrassing child safety device: :wink:

To unlock most comprehensive options from the 'pugnacity' range the ram commands become available successively:

Combat-group / Pugnacity-threshold for Ram (cf. viewtopic.php?f=209&t=1998&start=15#p48958)

War ships : 5+
non-combat armed 6+
non-combat unarmed 7+

AI 'Pugnacity' value-range / Ram Bug-fixes

Code: Select all

0x774F4 change 20 83 47 00 19 -> 19 83 47 00 20

0x776E3 change 89 D9 83 F8 02 -> 03 C3 EB 1F 90

0x777C8 change 85 -> 8C

0x77907 change 75 -> 7E

0x7787F change 05 -> 07


hostility jump table error (loc_478319)

pugnacity value range fix 'hostility' + 'war type'

004782E3   03C3     ADD EAX, EBX
004782E5   EB 1F    JMP SHORT 478306
004782E7   90       NOP

war ships
4783C0                 cmp     ds:AI_Combat_Pugnacity_0_5, 5
4783C7                 jnz     478590 -> jl

non-combat armed
478500                 cmp     ds:AI_Combat_Pugnacity_0_5, 5
478507                 jnz     478563 -> jng

non-combat unarmed
478479                 cmp     ds:AI_Combat_Pugnacity_0_5, 5 -> 7
478480                 jge     4784E4
Note the war type jihad (vs other empire) is not the same as the AI agenda jihad (global setting).

Agenda task 'Offer Proposal' (AI task 9) might influence AI gifts to other AI empires resp to minor races. Accept Proposal (8) seems to have no impact at all.

Another funny AI empire value is the score deviation tolerance (default: 1.2 - double float 577DFC). So the AI majors sometimes get kind of 'pissed off' if other empire's score exceed theirs by more than 20%.... :evil: