User Information |
|
|
|
Birth of the Federation: Forums |
| View previous topic :: View next topic |
| Author |
Message |
Gowron Code Master


Joined: Apr 26, 2008 Posts: 312 Location: 50° N, 11° E
|
Posted: Sun Aug 01, 2010 11:02 am Post subject: Ground Combat Calculation (success chance of invasion) |
|
|
Here's how the game determines the success chance for invasion attempts:
(1) Calculate the combined ground combat strengths of the attacking task force and multiply by the race-specific ground combat factor. Square the result.
(2) Multiply the result of (1) by the empire-wide bonus factor of the attacking empire.
(3) Calculate the ground defense value of the defending star system, including all bonuses. Square the result.
(4) Add the results of (2) and (3).
(5) Divide the result of (2) by the result of (4).
The result of (5) is then compared to a randomly generated value between 0 and 1. This comparison decides if the invasion succeeds.
So the success probability depends on the ratio of the squares of the ground combat values (of attackers and defenders), with the squared ground combat strength of the attackers being multiplied by their empire-wide bonus factor (if present).
It is a little bit odd that the empire-wide bonus of the attackers is included in the calculation although it does not affect the (displayed) ground combat values of troop transports.
--------------------------------------------------
link to ground combat strength explanation:
http://www.armadafleetcommand.com/botf/modules.php?name=Forums&file=viewtopic&t=56
link to ground combat tech level multiplier topic:
http://www.armadafleetcommand.com/botf/modules.php?name=Forums&file=viewtopic&t=67
--------------------------------------------------
The corresponding assembler code is part of subroutine 466CF0. Although that subroutine is quite huge, I think I've identified most of the relevant code sections for ground combat calculation.
Surprisingly there does not seem to be a loop over the attacking task forces (if more than one task force attacks). It seems that they are processed one by one.
Although it's quite obvious that var_10C contains the race-specific ground combat factor for the attacking task force, I've still added question marks for this variable because it does not seem to be assigned within subroutine 466CF0.
| Code: | AUTO:0046706E loc_46706E: ; CODE XREF: sub_466CF0+754j
AUTO:0046706E mov eax, [esp+420h+var_20] ; data offset for attacking task force
AUTO:00467075 xor ecx, ecx
AUTO:00467077 mov ebx, [eax+4] ; ship count of attacking task force
AUTO:0046707A mov [esp+420h+var_18], ecx ; 0
AUTO:00467081 test ebx, ebx
AUTO:00467083 jle short loc_4670EB ; jump if attacking task force is empty
AUTO:00467085 mov ebx, eax ; data offset for attacking task force
AUTO:00467087
AUTO:00467087 loc_467087: ; CODE XREF: sub_466CF0+3F9j
AUTO:00467087 mov eax, [ebx+6] ; start of loop over ships in attacking task force
AUTO:0046708A sar eax, 10h ; ship ID
AUTO:0046708D call sub_44A690 ; get data offset for current ship
AUTO:00467092 mov dl, [eax+58h]
AUTO:00467095 and dl, 0FEh
AUTO:00467098 mov esi, [eax+70h] ; base ground combat strength (= production value if TT) of current ship
AUTO:0046709B mov [eax+58h], dl
AUTO:0046709E test esi, esi
AUTO:004670A0 jbe loc_467449 ; jump if base ground combat strength is zero (not a TT)
AUTO:004670A6 xor ecx, ecx
AUTO:004670A8 mov dword ptr [esp+420h+var_B0], esi ; base ground combat strength of current ship
AUTO:004670AF mov dword ptr [esp+420h+var_B0+4], ecx ; 0
AUTO:004670B6 fild [esp+420h+var_B0] ; base ground combat strength of current ship
AUTO:004670BD fadd [esp+420h+var_100] ; add to base ground combat strength of task force
AUTO:004670C4 fstp [esp+420h+var_100] ; combined base ground combat strength of task force
AUTO:004670CB
AUTO:004670CB loc_4670CB: ; CODE XREF: sub_466CF0+75Dj
AUTO:004670CB ; sub_466CF0+7AFj ...
AUTO:004670CB mov esi, [esp+420h+var_18] ; loop counter
AUTO:004670D2 mov edx, [esp+420h+var_20] ; data offset for attacking task force
AUTO:004670D9 add ebx, 4 ; increase data offset to get next ship
AUTO:004670DC inc esi ; loop counter
AUTO:004670DD mov edi, [edx+4] ; ship count of attacking task force
AUTO:004670E0 mov [esp+420h+var_18], esi ; loop counter
AUTO:004670E7 cmp esi, edi
AUTO:004670E9 jl short loc_467087 ; loop over ships of attacking task force
-------------
AUTO:00467562 loc_467562: ; CODE XREF: sub_466CF0+58Fj
AUTO:00467562 mov edx, [esp+420h+var_28] ; data offset for defending system
AUTO:00467569 xor ah, ah
AUTO:0046756B mov al, [edx+4Ch] ; empire which controls defending system
AUTO:0046756E jmp loc_467289
-------------
AUTO:00467270 mov eax, [esp+420h+var_28] ; ID of defending system
AUTO:00467277 mov dh, [eax+4Ch] ; owner of defending system
AUTO:0046727A xor ebx, ebx
AUTO:0046727C cmp dh, 5 ; check if defending system belongs to a major empire
AUTO:0046727F jb loc_467562 ; use controlling race instead of inhabitant race if system belongs to an empire
AUTO:00467285 mov ax, [eax+44h] ; inhabitant race of defending system
AUTO:00467289
AUTO:00467289 loc_467289: ; CODE XREF: sub_466CF0+87Ej
AUTO:00467289 mov word ptr [esp+420h+var_8], ax ; defending race ID (empire resp. inhabitants)
AUTO:00467291 mov eax, [esp+420h+var_20] ; data offset for attacking task force
AUTO:00467298 mov cx, [eax+34h] ; race ID of attacking task force
AUTO:0046729C cmp cx, 5
AUTO:004672A0 jnb short loc_4672D4 ; jump if not a major empire
AUTO:004672A2 xor edx, edx
AUTO:004672A4 mov dx, cx
AUTO:004672A7 lea eax, ds:0[edx*8]
AUTO:004672AE add eax, edx
AUTO:004672B0 shl eax, 2
AUTO:004672B3 add eax, edx
AUTO:004672B5 shl eax, 2
AUTO:004672B8 mov edx, eax
AUTO:004672BA shl eax, 2
AUTO:004672BD sub eax, edx ; eax = 444 * (ID of attacking empire)
AUTO:004672BF add eax, offset st_empsInfo ; data offset for attacking empire
AUTO:004672C4 lea ebx, [eax+0F6h]
AUTO:004672CA mov bx, [ebx+18h] ; empire-wide ground combat bonus factor in percent
AUTO:004672CE and ebx, 0FFFFh
AUTO:004672D4
AUTO:004672D4 loc_4672D4: ; CODE XREF: sub_466CF0+5B0j
AUTO:004672D4 mov eax, [esp+420h+var_20] ; data offset for attacking task force
AUTO:004672DB xor ecx, ecx
AUTO:004672DD mov ax, [eax+34h] ; race ID of attacking task force
AUTO:004672E1 mov cx, ax ; race ID of attacking task force
AUTO:004672E4 lea esi, [esp+420h+var_174]
AUTO:004672EB mov eax, ecx ; race ID of attacking task force
AUTO:004672ED mov edx, 5 ; tech area "weapons"
AUTO:004672F2 call sub_4AED50
AUTO:004672F7 mov eax, ecx ; race ID of attacking task force
AUTO:004672F9 call GetTechLevel ; write weapon tech level of attackers to eax
AUTO:004672FE mov [esp+420h+var_10], eax ; weapon tech level of attackers
AUTO:00467305 fild [esp+420h+var_10] ; weapon tech level of attackers
AUTO:0046730C fmul ds:GrndCmbTechMul2 ; 0.1 (tech level bonus factor for attackers)
AUTO:00467312 fld1
AUTO:00467314 faddp st(1), st ; tech bonus = 1 + factor * (weapon tech level)
AUTO:00467316 fmul [esp+420h+var_10C] ; multiply by race-specific combat factor for attackers?
AUTO:0046731D fmul [esp+420h+var_100] ; multiply by combined base ground combat strength of attacking task force
AUTO:00467324 add ebx, 64h ; add 100 to empire-wide combat bonus
AUTO:00467327 fst [esp+420h+var_100] ; store result of multiplication
AUTO:0046732E fmul [esp+420h+var_100] ; square the above result
AUTO:00467335 mov [esp+420h+var_10], ebx ; 100 * (ground combat factor from empire-wide bonus) for attackers
AUTO:0046733C fstp [esp+420h+var_100]
AUTO:00467343 fild [esp+420h+var_10]
AUTO:0046734A fmul [esp+420h+var_100] ; apply empire-wide ground combat factor (not squared)
AUTO:00467351 mov eax, [esp+420h+var_28] ; ID of defending system
AUTO:00467358 fmul ds:dbl_57AC6C ; 0.01
AUTO:0046735E movsx eax, word ptr [eax] ; ID of defending system
AUTO:00467361 fstp [esp+420h+var_100]
AUTO:00467368 call GrndDefStrength ; get ground defense strength of defending system
AUTO:0046736D mov [esp+420h+var_10], eax ; ground defense strength of defending system
AUTO:00467374 fild [esp+420h+var_10] ; ground defense strength of defending system
AUTO:0046737B fmul st, st ; square ground defense strength of defending system
AUTO:0046737D fadd [esp+420h+var_100] ; calculate...
AUTO:00467384 fdivr [esp+420h+var_100] ; ... success chance of invasion
AUTO:0046738B mov edx, 1041h
AUTO:00467390 mov eax, offset a____SourceG_14 ; "..\\..\\source\\game\\military\\military.c"
AUTO:00467395 fstp [esp+420h+var_60] ; success chance of invasion
AUTO:0046739C call random2 ; loads a random value between 0 and 1 into the FPU
AUTO:004673A1 fld [esp+420h+var_60] ; success chance of invasion
AUTO:004673A8 fstp [esp+420h+var_C0] ; success chance of invasion
AUTO:004673AF fcomp [esp+420h+var_C0] ; check if invasion is successful (compare random value to success chance)
AUTO:004673B6 fnstsw ax
AUTO:004673B8 sahf
AUTO:004673B9 jnb loc_467573 ; jump if invasion is not successful
|
_________________ A discovery consists in seeing something everybody has seen and at the same time thinking something nobody has thought yet. |
|
| Back to top |
|
 |
Peter1981 Commodore


Joined: May 06, 2008 Posts: 934
|
Posted: Sun Aug 15, 2010 5:09 am Post subject: |
|
|
this code suggest that if a non-tt ship is given a production value or a colony ship attacks a planet in a task-force with a tt then the ground combat values (production values) are all used?
So there would be a use for giving all ships a production value?
I the above questions are rigth then this is an amazing find -- ALL HAIL THE EMPEROR!! |
|
| Back to top |
|
 |
Spocks-cuddly-tribble Code Master


Joined: Apr 27, 2008 Posts: 569
|
Posted: Sun Nov 28, 2010 6:02 am Post subject: |
|
|
| Gowron wrote: | | It is a little bit odd that the empire-wide bonus of the attackers is included in the calculation although it does not affect the (displayed) ground combat values of troop transports. |
Well, so at least this statement isn't untruth:
| BotF Patch Version 1.0.1 Changes wrote: | | Ground combat bonuses from structures such as the Angosian Super Soldier Academy are now applied to troop transports and ground forces. |
But the code disproves a random bonus for attackers when freeing systems as false evidence by the game manual.
However, probability calculation doesn't need any tweak IMO.
So for example (barring the the display omision / not squared attacker disadvantage w.r.t. the global building bonus):
~ 80% success probability for superior number 2:1
~ 20% if outnumbered 2:1
| Gowron wrote: | | Surprisingly there does not seem to be a loop over the attacking task forces (if more than one task force attacks). It seems that they are processed one by one. |
The lack of global task force handling is an overall issue in BotF.
I remember simultaneous conquests (i.e. message "invasion successful" & "system conquered /lost" afterwards). I'd be funny to see what happens if BotF sorts many taskforces in alternating series. Should result in a lot of messages (and a very shell-shocked population, of course ^^).
| Gowron wrote: | | Although it's quite obvious that var_10C contains the race-specific ground combat factor for the attacking task force, I've still added question marks for this variable because it does not seem to be assigned within subroutine 466CF0. |
4672F2 call sub_4AED50 (write race.rst entry for race Id (eax) to [esi])
Since esi =[esp+2ACh] +68h(ground combat position race.rst) =[esp+314h] (var_10C) = race ground combat value
| Peter1981 wrote: | | this code suggest that if a non-tt ship is given a production value or a colony ship attacks a planet in a task-force with a tt then the ground combat values (production values) are all used? |
No, “base ground combat strength (= production value if TT)” is just an unfortunate choice of words. TT production value /10 (unmodded) is stored at [GShipList+70h] as ground combat value - only for TT’s (see 2nd link above).
The production value itself is only used for construction of stations (also only TT - this time due to trek.exe check). _________________ On the verge of a nervous breakdown? Try the relaxing tribble sounds. |
|
| Back to top |
|
 |
Spocks-cuddly-tribble Code Master


Joined: Apr 27, 2008 Posts: 569
|
Posted: Sat Feb 26, 2011 4:27 am Post subject: |
|
|
In response to a very interesting suggestion by Callahan (see below), I continued the code analysis by Gowron. Additionally, I added a tweak option for the ground combat strength of AI troop transports.
Number of lost Troop Transports (limited by the number of attacking TTs of course)
Nominal loss by success = [ecx * failing chance] + 0.5 (rounded down)
ecx = 1 +[1 for each iteration of loop: failing chance vs. random value between 0 and 1]
Minimum loss = 1 TT (at 0x669D0 & 0x669D8)
Nominal loss when invasion fails = up to 1000 TTs (at 0x669FC)
| Code: | 4673BF fld1 // load 1 into FPU
4673C1 fsub qword ptr [esp+360h] // 1 - success chance of invasion
4673C8 xor esi, esi // esi = 0 (=invasion successful)
4673CA fstp qword ptr [esp+398h] // store reversed success (i.e. failing) chance
4673D1 mov ecx, 1
4673E4 call 507E50 // load random value between 0 and 1 into FPU
4673E9 fcomp qword ptr [esp+398h] // compare random value to failing chance
4673F0 fnstsw ax
4673F2 sahf
4673F3 jnb 467599 // exit loop if failing chance is lower
4673F9 inc ecx // ecx + 1
4673FA jmp short loc_4673E0 // iterate random loop
467599 mov [esp+410h], ecx // result of above loop
4675A0 fild dword ptr [esp+410h] // load in FPU
4675A7 fmul qword ptr [esp+398h] // ecx * failing chance
4675AE fst qword ptr [esp+398h]
4675B5 fadd ds:57AC74 (0.5 shared vulue) // (ecx * failing chance) + 0.5
4675BB call 51D6D4 // round down
4675C0 fistp dword ptr [esp+3C8h] // store result as integer
4675C7 mov edi, [esp+3C8h] // number of lost TTs when invasion successful
4675CE cmp edi, 1 // minimum number of lost TTs when invasion successful
4675D1 jge 467A58
4675D7 mov edx, 1 // minimum number of lost TTs when invasion successful
4675F7 test esi, esi // if invasion successful…
4675F9 jz short 467600 // …skip next
4675FB mov edx, 3E8h // number of lost TTs when invasion fails |
Result and calculation of ecx is shared for various purposes, so modding this part probably won't be very practical.
However, we can skip this part:
[ecx * failing chance] + 0.5 (rounded down)
| Code: | trek exe at 0x669C7
8B BC 24 C8 03 00 00 -> 8B F9 90 90 90 90 90
4675C7 mov edi, ecx // number of lost TTs |
This increases the (by default too low) chance to lose additional TTs by success.
| Callahan wrote: | Use up all involved transports on invasion.
I do not like the current way of being overrun by the enemy as he only has to build 1 new TRN after capturing even a strong system.
Using em up all would make it more difficult to decide on how many to be used, and would slow down any war as one will have to build more TRNs in order to proceed. |
Minimum loss of TTs by success is at 0x669D0 & 0x669D8. The first value is a 1 byte signed, but 0x64 at both locations should do fine.
This, indeed, could make the game more pretentious and also redress some bizarre strategies from low tech games (i.e. build tons of TTs, conquer a superior system, scrap TTs & from money build warships to destroy the next enemy’s fleet or bribe the next minor).
Modifying the AI's offensive ground combat strength
Due to the AI's inefficient system attack assessment (apparently sub_479AD0), it tends to bring too less TTs, resulting in a fatal waste of resources. In later stages of game, this oftentimes leads to destroyed instead of conquered systems, in earlier stages to crippled AI fleets due to the repeated failures.
As a workaround we can enhance the base ground combat strength of AI TTs. This of course works not only against minor and player systems, but also against other AI majors (so the dominat AI retains more of its resources).
The following code example gives the AI a bonus of 50% per difficulty level above “simple”.
| Code: | Trek.exe at 0x49C35
replace: (74 bytes)
31 D2 8A 94 24 2A 01 00 00 8D 04 95 00 00 00 00 29 D0 C1 E0 03 01 D0 01 C0 31 D2 89 41 6C 66 8B 94 24 16 01 00 00 BB 0A 00 00 00 89 D0 C1 FA 1F F7 FB 89 41 70 81 C4 3C 01 00 00 59 5B C3 00 00 00 00 00 00 00 00 00 00 00 00
with:
8A 9C 24 2A 01 00 00 6B DB 32 89 59 6C 0F B7 94 24 16 01 00 00 8B D9 8A 49 28 B5 01 D2 E5 84 2D 28 2B 5A 00 75 0D A0 44 2B 5A 00 04 01 0F AF D0 C1 EA 01 33 C9 B1 0A 8B C2 C1 FA 1F F7 F9 89 43 70 81 C4 3C 01 00 00 59 5B C3
44A835 8A9C24 2A010000 MOV BL, [ESP+12A] // construction tech from shiptech.sst
44A83C 6BDB 32 IMUL EBX, EBX, 32 // *50
44A83F 8959 6C MOV [ECX+6C], EBX // store in GShipList
44A842 0FB79424 16010000 MOVZX EDX, WORD [ESP+116] // TT production value from shiplist.sst
44A84A 8BD9 MOV EBX, ECX // GShipList entry
0044A84C 8A49 28 MOV CL, [ECX+28] // race ID
44A84F B5 01 MOV CH, 1
44A851 D2E5 SHL CH, CL
44A853 842D 282B5A00 TEST [5A2B28], CH // if not AI…
44A859 75 0D JNZ SHORT 44A868 // …skip AI bonus
44A85B A0 442B5A00 MOV AL, [5A2B44] // difficulty level
44A860 04 01 ADD AL, 1 // difficulty level + 1 -> factor A
44A862 0FAFD0 IMUL EDX, EAX // production value * (difficulty level +A)
44A865 C1EA 01 SHR EDX, 1 // divide by 2^1 -> factor B
44A868 33C9 XOR ECX, ECX
44A86A B1 0A MOV CL, 0A // default ground combat divisor 10
44A86C 8BC2 MOV EAX, EDX
44A86E C1FA 1F SAR EDX, 1F
44A871 F7F9 IDIV ECX
44A873 8943 70 MOV [EBX+70], EAX // store TT ground combat value in GShipList
44A876 81C4 3C010000 ADD ESP, 13C
44A87C 59 POP ECX
44A87D 5B POP EBX
44A87E C3 RETN |
Thanks to an inspiration from Peter1981 the bonus can be adapted according to:
[ground combat strength] * [difficulty level +A] / 2^B
Factor A at 0x49C61 (default 1)
Factor B at 0x49C67 (default 1)
Hence for the factors A / B the bonuses per difficulty level above “simple” are:
0/0 = +100%
1/1 = +50%
3/2 = +25%
7/3 = +12.5%
This is performed before the default integer division, so the AI gets a bit more than expected.
Note: Since the ground combat value of TTs is stored at [GShipList+70h] i.e. the savegame, this modification won’t work for present TTs if applied afterwards, and also the AI bonus will be not removed from existing TTs when switching player race via savegame editing (see changing AI controling race of a savegame)! _________________ On the verge of a nervous breakdown? Try the relaxing tribble sounds. |
|
| Back to top |
|
 |
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001-2008 phpBB Group
|
|