Capping mechanics... [Spoilers and even some disassembled code inside]

General discussions about the games by Egosoft including X-BTF, XT, X², X³: Reunion, X³: Terran Conflict and X³: Albion Prelude.

Moderator: Moderators for English X Forum

User avatar
fiksal
Posts: 16988
Joined: Tue, 2. May 06, 17:05
x4

Post by fiksal »

Carlo the Curious wrote:Maybe it's starting from when the hull hits 87%, with a check at that point, then 30s, etc.
that's what I'd guess


eldarmark wrote:
pjknibbs wrote:Something is wrong with that analysis somewhere--it's easily possible to capture a ship without having to blast away at it for 30 seconds, which you seem to think is the case.
The impression I got from the summary was that you have a certain % chance to cap at 87%, then another, slightly smaller chance to cap when you next hit them for hull damage after 30 seconds, then 60, then...
that's what the IF statements seem to imply... hm... I admit it does sound weird. I'll go through the code and comments again (they arent exactly clear)


eldarmark wrote: Wonder what affects morale. I would assume that hurting them a LOT really quickly would affect it. Perhaps that offsets the IonDs adjustment -- since they hurt shields a LOT, really quickly, the adjustment is there to offset the huge morale penalty that they take?
Seems to me the moral remains unchanged, so it's probably set on ship's creation.
Certain ships, like Xenon tend to have morale in 20s and higher. At least I havent seen one lower yet. (not that I checked that too often).



EDIT
the IF statement that checks the time intervals wraps through the whole capture probability logic,

Code: Select all

if (ga_Player.GetAge() > sh_NextTakeoverChanceTime) {
Assuming that logic above is correct, can anyone say that they captured a ship in less than 30 seconds with more than one shot?

I cant say for sure one way or another.
It's possible that the number "30" is not in seconds... if only we knew what that GetAge returns... on the other hand, there might be a similar function in script editor, ... wonder what that returns
(thinking outloud now)

END OF EDIT
Gimli wrote:Let the Orcs come as thick as summer-moths round a candle!
User avatar
Sandalpocalypse
Posts: 4447
Joined: Tue, 2. Dec 03, 22:28
x4

Post by Sandalpocalypse »

It can't work like that. If it took 30 seconds until you get another cap chance, I would never cap a ship at anything other than 87%.

I think the delay between captures probably affects the next ship instead.

(it sounds like a streakbreaker mechanic imo)
User avatar
fiksal
Posts: 16988
Joined: Tue, 2. May 06, 17:05
x4

Post by fiksal »

Sandalpocalypse wrote:It can't work like that. If it took 30 seconds until you get another cap chance, I would never cap a ship at anything other than 87%.
how do you figure that?

tik 1: damaged hull at 87%, cap probability calculated but didnt succeed
tik 2: ship keeps taking damage
...
tik N: (at 30seconds): damaged hull at X %, cap probability calculated again and either successful or not.

unless you are implying that every cap you got it took you less than 30 seconds, which is what I was asking - did it?
Carlo the Curious wrote: I'm guessing rank 6 is Battlemaster and 30 Harmless. I'm sure there's a list I've seen, but I can't find it.
looks like "30" rank is in that code better/higher than 6, so perhaps other way around
Gimli wrote:Let the Orcs come as thick as summer-moths round a candle!
TBV
Posts: 2260
Joined: Sun, 3. Apr 05, 01:58
x3tc

Post by TBV »

Conditions seem to be checked in this order:-
Spoiler
Show

1/ The attacker must be the player ship using weapons not collision.

Code: Select all

if (AttackerEv == ga_PlayerShip) && arg2 {
2/ The taget must not be an Earth ship or a Player ship or something else I can't figure out.

Code: Select all

if !(TCLIENT.GetClientState() & 0200h) &&
(sh_Owner <> ga_Player) && (sh_Owner <> ga_Races[18]){ // sh_Owner != Earth
3/ If the shot came from an Ion D you only get a 3% chance to continue.

Code: Select all

if ((SE_Random(100) < 4) || (SA_GetType(arg2) <> 17){ //Ion Distructor
4/ If the ship is not indestructible (guesswork. No point going further if it is)

Code: Select all

if (SA_GetShipTypeCockpitBody(sh_SubType) && !(sh_Flags & 0100b)){
5/ The shield must be below 1%, the hull must be non-zero and the remaining hull must be less than 87.5%.

Code: Select all

if (Shield <= LimShield) && (Hull > 0) && (Hull < SE_Random(8) * MaxHull / 8) {
6/ The player must be due another shot at capturing.

Code: Select all

if (ga_Player.GetAge() > sh_NextTakeoverChanceTime) {
7/ The final hurdle is the random number generator as follows. Morale value, relative strength, Targets hull being as low as possible, a takeover delay time, target
being of races (7) and finally combat rank, all add up to give a variable called ProbabilityCapture a value between one and one hundred.
If this beats a random number between 1 and 100, the pilot bails.

Code: Select all

if (ProbabilityCapture > SE_Random(100){

That seems to be it. All the other code seems to deal with general combat and damge and the like.


It is a while since I looked at any code, so I appologise if I've interpreted
it incorrectly. But that's how it appears to me.
edit spoiler
Last edited by TBV on Fri, 11. Jan 08, 20:21, edited 1 time in total.
User avatar
Sandalpocalypse
Posts: 4447
Joined: Tue, 2. Dec 03, 22:28
x4

Post by Sandalpocalypse »

unless you are implying that every cap you got it took you less than 30 seconds, which is what I was asking - did it?
30 seconds is an eternity in a dogfight. No cappable ship (read: fighter) is going to last 30 seconds after its shields are stripped and its hull is reduced to 87%. And I have my AHEPTs modded to do significantly less hull damage.

although it's theoretically possible that the comms messages are distorting the matter and 95% of my caps are technically at 87%.

also, reading TBV's post, the 'takeover delay time' sounds like it could be distorting things.
TBV
Posts: 2260
Joined: Sun, 3. Apr 05, 01:58
x3tc

Post by TBV »

Spoiler
Show
Right, I've had time to look at the code a bit more. This is what I've come up
with. If you can find holes in my reasoning, please point them out.


It seems to go like this:-

The random number generator is going to pick a number from 1 to 100.
I'm going to call this a potential 100 "points".

You have to beat this with a number of points you can aquire, but they may not go as high as 100.



1. First you get given 30 points.

2. Then you are penalized every point of the targets morale. If it's as high as 30, you get a big fat zero.

3. You are then penalized a further 5 points if your ship is weaker than the target's ship. (A score of -5 is possible at this point. Doing well then...)

4. If the targets hull is below 25%, you can get up to 25 points. But you only get 1 point if it is exactly 25%. If it is higher than 25%, you get penalized by having
up to 71% of your existing score taken away. Gulp! What's 29% of -5?

5. If that's not enough, you then suffer a random penalty of either 1, 2, 4 or 8 points. (This is the delay timer and this is all it does)

6. Then, if the target's ship is of ga_Races[7] (whatever that means), you then get guess what? Another penalty by subtracting a percentage
of your score based on your fight rank up to a maximum of 84% if you are Harmless and a minimum of 0% if you are X-Treme.


So to summarise; If the target's morale is 5, your ship is superior, the targets hull is at 1% and you are X-Treme (and a little lucky, see point 5),
you have a 49% chance of a bail. If you can stop firing in time obviously.

Realistically you'll never get near this so the 10% rate most people seem to experience seems pretty good to me.


It should be noted that you only get to the code that I have described above, if you have fulfilled all the other
criteria (if statements) that I mentioned in my previous post.


If anyone is interested in how I arrived at these conclusions from the code, please say.
edit spoiler
Last edited by TBV on Fri, 11. Jan 08, 20:22, edited 1 time in total.
User avatar
kotekzot
Posts: 615
Joined: Sun, 10. Sep 06, 07:36

Post by kotekzot »

TBV wrote:6. Then, if the target's ship is of ga_Races[7] (whatever that means), you then get guess what? Another penalty by subtracting a percentage
of your score based on your fight rank up to a maximum of 84% if you are Harmless and a minimum of 0% if you are X-Treme.
that's kha'ak. that's why they only become cap-able after you hit combat level 5.

nice work on reading the code, btw.
User avatar
fiksal
Posts: 16988
Joined: Tue, 2. May 06, 17:05
x4

Post by fiksal »

TBV wrote: 5. If that's not enough, you then suffer a random penalty of either 1, 2, 4 or 8 points. (This is the delay timer and this is all it does)
not so, the IF statement prevents execution of the block if age is not greater than time interval

Code: Select all

if (ga_Player.GetAge() > sh_NextTakeoverChanceTime)
{ 


if ((sh_TakeoverDelayTime > 300) && 
(ga_Player.GetAge() > (sh_NextTakeoverChanceTime + sh_TakeoverDelayTime))
{ 
 sh_TakeoverDelayTime = 30; //Установить задержку в 30 секунд 

}
else { 
 sh_TakeoverDelayTime += sh_TakeoverDelayTime; //иначе, удвоить задержку 
} 


sh_NextTakeoverChanceTime = ga_Player.GetAge() + sh_TakeoverDelayTime; 


ProbabilityCapture = 30 - this.GetPilotMorale(); 

...
}
6. Then, if the target's ship is of ga_Races[7] (whatever that means),
"Khaak" according to the comments in Russian.


There's apparently still more code, and summary notes from the original poster, which I'll look over when I have time.
Gimli wrote:Let the Orcs come as thick as summer-moths round a candle!
TBV
Posts: 2260
Joined: Sun, 3. Apr 05, 01:58
x3tc

Post by TBV »

Spoiler
Show
fiksal wrote:
TBV wrote:5. If that's not enough, you then suffer a random penalty of either 1, 2, 4 or 8 points. (This is the delay timer and this is all it does)
not so, the IF statement prevents execution of the block if age is not greater than time interval
last time through the statement, the takeover chance time was derived mostly
from player age, partly by the delay time. So player age equals (player age minus delay time of 30, 60, 120 or 240). So the only difference will be the delay time, plus a hundredth of a second or so that player age has increased.
(assuming the same battle with the same ship)

So I stand by what I put for now.


EDIT: In fact, as far as I can tell, the only event where that if statement
can be false are the immediately following 3 shots fired by the player.
In this case ga_Player.GetAge() could be less than sh_NextTakeoverChanceTime.

Or am I going mad from looking at this too long?
edit spoiler
Last edited by TBV on Fri, 11. Jan 08, 20:23, edited 2 times in total.
User avatar
fiksal
Posts: 16988
Joined: Tue, 2. May 06, 17:05
x4

Post by fiksal »

TBV wrote:
fiksal wrote:
TBV wrote:5. If that's not enough, you then suffer a random penalty of either 1, 2, 4 or 8 points. (This is the delay timer and this is all it does)
not so, the IF statement prevents execution of the block if age is not greater than time interval
last time through the statement, the takeover chance time was derived mostly
from player age, partly by the delay time. So player age equals (player age minus delay time of 30, 60, 120 or 240). So the only difference will be the delay time, plus a hundredth of a second or so that player age has increased.
(assuming the same battle with the same ship)

So I stand by what I put for now.

last time, really? :)
I am not following you about Player's Age.

the pickle is that you enter this code first,
assuming Age is > NextTakeover
if (ga_Player.GetAge() > sh_NextTakeoverChanceTime)
{

then it does this little check, which would probably take us to Else leg, at first
if ((sh_TakeoverDelayTime > 300) &&
(ga_Player.GetAge() > (sh_NextTakeoverChanceTime + sh_TakeoverDelayTime))
{
sh_TakeoverDelayTime = 30; //Установить задержку в 30 секунд

}
else {
sh_TakeoverDelayTime += sh_TakeoverDelayTime; //иначе, удвоить задержку
}
and then the NextTakeover is reset as Age+ delay

sh_NextTakeoverChanceTime = ga_Player.GetAge() + sh_TakeoverDelayTime;

ProbabilityCapture = 30 - this.GetPilotMorale();

...
}
Next time around though, unless "30" is not in seconds, the very first IF will be false, and probability is not going to be counted at all.

Unless I am missing something.
Gimli wrote:Let the Orcs come as thick as summer-moths round a candle!
TBV
Posts: 2260
Joined: Sun, 3. Apr 05, 01:58
x3tc

Post by TBV »

Spoiler
Show
sh_TakeoverDelayTime is just a counter that can have five possible values,
based on the number of times this bit of code has been executed.
It starts at 30 and keeps doubling until the statment is false at 480 and
so gets assigned 30 again.

This counter value is added to the age of the player when the last relevant shot
was fired and then compared to the players age when the current relevant shot is fired.

I don't know how player age is actually counted, but during a continuous burst of fire the age can't have changed hugely between shots.
The sh_TakeoverDelayTime climbing faster than the player ages is the
only way to fail the initial if statement in your last post. Er, I think.


(Btw, my conclusions are based on old coding experience about when java 2 first came out, plus a tiny smidge of maths knowledge. Plus a great deal
of guesswork, hopefully as a result of reasonably logical thought processes.
But please do not think I am saying that "I am right and you are wrong", and continue to pick holes. I would love to get to the bottom of this).
edit spoiler
Last edited by TBV on Fri, 11. Jan 08, 20:24, edited 1 time in total.
User avatar
fiksal
Posts: 16988
Joined: Tue, 2. May 06, 17:05
x4

Post by fiksal »

One of us might be missfiring neurons,
dont get me wrong too, ... it can be me :)
TBV wrote:sh_TakeoverDelayTime is just a counter that can have five possible values,
based on the number of times this bit of code has been executed.
It starts at 30 and keeps doubling until the statment is false at 480 and
so gets assigned 30 again.
right... and only if Player Age is actually larger than the Delay (second part of AND logic)
TBV wrote: This counter value is added to the age of the player when the last relevant shot
not "to", but "with". The result is assigned to NextTimeout value

TBV wrote:I don't know how player age is actually counted, but during a continuous burst of fire the age can't have changed hugely between shots.
One would assume it's actual seconds... but that yet to be confirmed.
TBV wrote: The sh_TakeoverDelayTime climbing faster than the player ages is the
only way to fail the initial if statement in your last post. Er, I think.
um... sort of...

1st Age is compared to NextTakeover
if Age is > NextTakeover
then we proceed

if Delay > 300 AND etc
...
else
Delay = Delay + Delay


NextTakeover = Age + Delay // <- this is always executed if Age > NextTakeover is TRUE

else if Age is NOT > NextTakeover
we do not do anything


So what that code (without digging into other procedures) tells me, that after the very first calculation (of probability), you cant capture anything for another 30 units of time, then after 30 you can do again, but then have to wait another 60 and so on.
The author noted (in Russian) that 30 is "seconds".... Which sounds a bit much. Thus it's possible it's not in "seconds".


do you follow what I am getting to?
Gimli wrote:Let the Orcs come as thick as summer-moths round a candle!
User avatar
ivak
Posts: 759
Joined: Sun, 19. Aug 07, 17:48
x3tc

Post by ivak »

Probably it's in microseconds or jiffies. Microsecond timers are widely used in the gaming environments (i've done some game programming myself; it was for slot machines, but the principles are the same).
User avatar
Carlo the Curious
Posts: 16999
Joined: Mon, 5. Mar 07, 22:03
x4

Post by Carlo the Curious »

Galaxy flight timestep is measured in microseconds, so probably.
TBV
Posts: 2260
Joined: Sun, 3. Apr 05, 01:58
x3tc

Post by TBV »

Spoiler
Show
This bit really is making my head hurt.


Assume sh_TakeoverDelayTime starts with the value 30, because we know that at some point it is assigned this value.

After the hull is below 87%, the fifth shot that triggers execution of this bit bit of code, will make (sh_TakeoverDelayTime > 300) true.

Continuing firing after this is pointless, because sh_TakeoverDelayTime is doubling in size with every shot and ga_Player.GetAge() will
only be increasing by a fraction of a second in comparison.

Could I conclude then that the first 5 shots on a hull below 87.5% are all you should fire. And the more you keep firing, the longer
the delay before you can cap again?
edit spoiler
Last edited by TBV on Fri, 11. Jan 08, 20:25, edited 1 time in total.
User avatar
Sandalpocalypse
Posts: 4447
Joined: Tue, 2. Dec 03, 22:28
x4

Post by Sandalpocalypse »

I know that bullet lifetimes are measured in milliseconds. Could be milliseconds.
User avatar
juanitierno
Posts: 451
Joined: Fri, 28. Dec 07, 17:06
xrvr

Post by juanitierno »

from reading the code i believe i have a somewhat decent theory:

i will assume numers are in hundreths of a second (ill call it ticks).

You get a capping chance at 30 ticks, then another at 60, then another at 120, etc, if you keep firing you make the counter increase, so the more you fire at it continuously, the less chances you get.

This code:

if ((sh_TakeoverDelayTime > 300) &&
(ga_Player.GetAge() > (sh_NextTakeoverChanceTime + sh_TakeoverDelayTime))
{
sh_TakeoverDelayTime = 30;
}
else
{
sh_TakeoverDelayTime += sh_TakeoverDelayTime;
}

Should be read as: If you hit the pirate constantly you get a chance at 30 ticks, then at 60, then at 120, etc, doubling each time, UNLESS:

If you break your attack, and wait double the last timer, the timer gets reset.
Example: you shoot at it for 210 ticks (30t+60t+120t), and then break off for 420t (2x120t) then the timer is reset. If you dont wait the 420t, then your next chance is at tick 420, and in order to reset the timer you will need to wait for 840 ticks.

With just that, one could assume that the capping secret would be to fire a single shot, let it cool down, then fire another shot, then wait again. This will not work as well as expected simply because if the timer is not allowed to grow to 420 ticks, it will never reset.


So, the secret for getting the greatest chances at capping (not considering morale, types of ships, etc) would seem to be:

* Fire at it for a little more than 210 ticks (so the timer becomes 420, and has a chance to cool down).
* WAIT 840 ticks
* Repeat

Assuming 1 tick = 1 hundreth of a sec then:
Fire for 2.5 seconds, and wait 9 seconds, then repeat.
If you dont wait 9 seconds then you will get geometrically growing delays that will make the ship virtually uncappable after a few seconds. Firing continuously you get chances at 0.3 secs, 0.9 secs, 2.4 secs, 8.4 secs, secs, etc.


Anyways, its just my understanding of the code.

// edit, seconds in the last line where wrong.
Last edited by juanitierno on Fri, 11. Jan 08, 10:35, edited 1 time in total.
Fallen Haven
Posts: 33
Joined: Sun, 6. Jan 08, 07:51

Post by Fallen Haven »

I've read several times on this forum that the difficulty of the game is just the starting money. But i played Normal for a while and restarted a new game at quickstart... Well i could see the difference, and it was not just having a better equiped ship and some extra money. I noticed capping was far more common than in my normal game... Heck, i about an hour of play, i had captured 3 ships while i usually took 1-2 hours to get one in my previous game despite trying hard to not vaporise the opposition outright...
User avatar
Carlo the Curious
Posts: 16999
Joined: Mon, 5. Mar 07, 22:03
x4

Post by Carlo the Curious »

Fallen Haven wrote:I've read several times on this forum that the difficulty of the game is just the starting money.
And ship, etc.

But that's what the devs say, and one assumes they know what they're talking about.
Fallen Haven
Posts: 33
Joined: Sun, 6. Jan 08, 07:51

Post by Fallen Haven »

Carlo the Curious wrote:
Fallen Haven wrote:I've read several times on this forum that the difficulty of the game is just the starting money.
And ship, etc.

But that's what the devs say, and one assumes they know what they're talking about.
Then it must be the ship's loadout that made a difference...

Return to “X Trilogy Universe”