Jump to content

Formulas


NKF

Recommended Posts

At the moment, I think it may be stored in tactical.exe. There doesn't seem to be anything in unitref.dat and unitpos.dat that determines the resistance modifiers. At least, as far as I can tell. Try the skin swapping and find out.

 

- NKF

Link to comment
Share on other sites

  • Replies 92
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Posted Images

Everything would be so much easier with the source code. Although, that's not necessarily true, as source code can be very difficult to understand if it's not written by you. I find it difficult to understand my own code after I've left it for a few weeks. ;)

 

Most of it's just plain mathematics. You have your known values and unknown values. What you try to work out is what the unknowns are. It's just a matter of moving bits and pieces from the left hand side to the right hand side and banjo! An answer emerges.

 

For example, you know your firing accuracy is 96 and you have a weapon, but you don't know what is the accuracy modifier for the selected firing mode. You can work it out like so:

 

 

97 * X = 105

X = 105 / 97

X = 1.08

 

Therefore, firing mode X is 108% accurate.

 

Oh, and a mild sprinkling of basic statistics helps a lot too. Working out the damage resistance was done purely by statistics. You cannot image how many times I had to shoot a soldier, work out how much damage was done and then keep a record of it, then analayse all the data at the end. :)

 

Now, for the more complicated stuff, like looking for flags to determine what does what in the game datafiles, I suppose that could be considered reverse engineering.

 

- NKF

Link to comment
Share on other sites

  • 6 months later...

Well I am trying to figure out the formula that the game uses to calculate moral during combat on UFO to see if it can be used in UFO2000 since the current system is less than perfect.

 

I have posted what I have come up with here. My problem right now is figuring the modifiers for rank. The tables there apply to when there is only squaddies/rookies present and/or also 1 officer. But when I try to use them with higher ranks (like calculating the morale of a 60 bravery captain when a colonel dies) the values don't match exactly.

Anyone has any knowledge on the subject?

Link to comment
Share on other sites

  • 7 months later...

Humor me, as I bump this thread. :borg:

 

When I first became a member at the old tactical command forums (or XTC), this thread was the topic of interest. At the time, I neglected to read this topic much as I was busy collecting 1000 starting soldier stats. Whatever the case was, I never realized that the throwing formula had been figured out by JellyfishGreen.

 

So there I was, all ready to solve another unknown in X-COM. I hired tons of soldiers to get beginner strength ratings of 20, 30 and 40, and also spent some time improving the strength ratings of some vets to 50, 60 and 70. Then I sent these soldiers out to a mission to test how far they could throw a particular object. Since certain objects weigh more than others, I used the weight stats from the OSG to figure out what to bring along. The thing that took the most time was setting up a throwing "gallery" for those soldiers: flat, level ground, no hindrances above the soldiers, and a tile guide to make counting tiles easier (scorched into certain ground tiles with Laser Rifles). Collecting the data was easy.

 

As it came to pass, I filed that data away only to forget where it was located. While cleaning up my hard-drive the other day I "rediscovered" this data and attempted to formulate an equation to explain this info. Little did I realize that it had already been done. The equation I devised looked exactly like JFG's, right down to the "tilefactor" (which I called a constant). Zombie had just reinvented the wheel. How embarrassing. :confused:

 

I used a "Sandbox" formula of (Distance = Tilefactor * Strength / Weight) and got a pretty good fit to the Range data with a Tilefactor of 2.5, with a 1 or 2 tile error here or there.

The reason why I needed a constant was because the distance thrown did not equal the anticipated Strength/Weight ratio. It was off by a factor of 2.5. But why was this "fudge factor" or "magic tennis ball constant" (as we lovingly called unknowns in Physics class) needed?

 

Since decimals cannot be utilized by the game, the number 2.5 is obviously not used. All numbers are expressed as whole (integers) as opposed to reals (numbers containing a decimal point) to save space or to make the programming easier. What this means is that a factor of 5/2 is the "true" multiplier. What does it stand for though?

 

I thought about this for a bit and decided to solve the equation for the constant to see what was going on. Rearranged, the throwing distance equation looks like this: (Distance) / (Strength/Weight) = Constant

So 5 would stand for distance and 2 would stand for Strength/Weight. Therefore, Strength/Weight = 2, or rearranged, Weight = Strength/2. I can think of two possibilities what "2" could stand for:

1) 2 could be a factor between the minimum strength a soldier could have (20) and a arbitrary weight of 10 (like an empty Rocket Launcher). 20/10 = 2. Or,

2) Its just a factor the programmers cooked up to relate weight and strength.

Either are good possibilities in my book.

 

But what would the distance of 5 stand for? Is it just another arbitrary constant, or some scheme to confuse me even more? I'd like everyone's ideas on this, please. :grr:

 

- Zombie

Link to comment
Share on other sites

This forum in general seemed more active at XTC, but anyways, that's getting off-topic...

 

I loved this thread when it was active! I was always impressed by how smart you all are :grr:

 

I was smart back in high school, doing Maths and Physics and such, but I'm afraid it's mostly left me in the last 9 years :confused:

 

So anyway, Distance = 5 and Strength = Weight x 2?... Interesting... My guess is that they're just random numbers the programmers added in to make the game perform how they wanted it to.

Link to comment
Share on other sites

Don't sell yourself short, Danial. You are no slouch in the smart department either. :confused:

 

Anyhow, back to the Throwing formula. I uncovered some long-forgotten files on my computer and in it was of all things some game-tested numbers pertaining to strength and throwing distance. What a find.

 

The "tilefactor" of 2.5, which I calculated before, was with soldiers having various strength ratings and a constant item weight of 6 (equivalent to a High Explosive). However, when analyzing my new data with different item weights represented, the tilefactor changed. By "changed" I mean it varied between a low of 2.15 and a high of 3.3.

 

I'll try and explain this as best I can. Take one soldier having a strength rating of 20, and have him throw various item weights. The lowest weight items got a lower tilefactor number (roughly 2.2) and that number steadily increased to 3.3 as the weight increased. Now take a soldier having a strength of 40. It's the same deal as the 20 strength soldier: a lower tilefactor for a lower weight and a higher tilefactor for the higher weights.

 

This "ordering" leads me to believe that there isn't just one global constant of 2.5 (or 5/2) to link throwing distance to item weight and soldier strength like we initially thought. Something much more sinister is happening. What this unfortunately means is that our throwing distance formula is flawed in some respect. I guess we just don't fully comprehend the mechanics behind a throw yet.

 

Not to worry, I am collecting a comprehensive list of item weight, soldier strength and throwing distance. Hopefully more data will shed some light into what is happening. I'll keep you updated. Keep your fingers crossed everyone, as solving this problem may take a bit of luck! :grr:

 

- Zombie

Link to comment
Share on other sites

  • 1 year later...

Here we go again. Let's take another look at throwing distance when compared to the two variables: item weight and soldier strength. :drink:

 

From the numbers I gathered a while back, it quicky became apparent that there were not enough data points to formulate an opinion. Worse still, there were big gaps in my table as some weights cannot be tested with the original items. (For instance, item weights of 1 and 2 don't exist normally). Also, soldier strength has an in-game range of 20-71 which limits things even more. These two facts basically crippled my hope of understanding the properties of a simple throw.

 

There is always a work-around, though. Game file editing seemed to be the best shot, and after a quick crash-course by NKF (thanks again), I was on my way. For this to succeed, I needed to edit not only the weight of an item in obdata.dat, but also the strength rating of my test soldier in unitref.dat. After you throw the item and record the distance, one of the stats (in this case soldier strength) is increased and the item is thrown again. This continues until the strength variable is maxed out at 255. Then item weight is increased to the next number and the whole process starts all over again. Sounds tedious, doesn't it? You bet! But this method has the fortunate effect of having a continuous range of numbers to draw from which is necessary to form theories or (hopefully) an equation.

 

It took me a while, but I just completed the first milestone: item weights up to 10! (Lemme see, that's (10*255) = 2550 separate throwing distances. Granted, I didn't have to do quite that many edits as distances come in ranges, but there were enough). Preconditions: I performed these tests on a Supply Ship map which has a size of 50x50x4. Sure, an alien/X-COM base is 60x60 but the height is only 2 - that's way too low for throwing long distances. Also, all throws were made on flat, level ground and across the length - diagonal throws were not made. Doesn't matter really as I found that diagonals have the same distance for throwing).

 

Anyhow, I'm going to include an Excel table and an Adobe pdf of the data so far. (In Adobe Acrobat, you need to click "View" and then "Fit Visible" to make things easier to read). I also color-coded the whole table accordingly. Why? Well, I grouped throws into 7 categories depending on message. As we know, sometimes a message comes up regarding a throw you want to make. Most of the time it's because of obstructions. Since I didn't have any (besides map height), grouping them seemed to be a good idea. A color of green designates that the throw is completed without any messages (trying to throw further than the distance brings up an "Out Of Range" [herein known as "OOR"] message). The colors of yellow to red indicate that the throw is completed normally at that distance, but if you try and throw one tile farther the "Unable to throw here" message shows up. (I guess this is because of the limited map height or something). This message might continue for a while as distance is incresed, but after a while the OOR message comes up again. The color of black with OOR in it means that object cannot be thrown no matter the distance.

 

Here are the ranges for each category:

 

Clean	   Unable to		  Out of
Throw	   throw here		 Range
 21			 22			  23+
 23		   24-27			 28+
 27		   28-35			 36+
 33		   34-49+			NA
 46		   47-49+			NA

I did a little bit of crunching and came up with a theoretical range for the 33 and 46 categories. Don't know if it's right, but it may model the numbers.

 

Clean	   Unable to		  Out of
Throw	   throw here		 Range
 21			 22			  23+
 23		   24-27			 28+
 27		   28-35			 36+
 33		   34-49			 50+  *Theoretical
 46		   47-78			 79+  *Theoretical

As a final thought (at least for now), the tilefactor idea is wrong. Period. See, like I mentioned before, the tile factor increases as the strength of the soldier increases. In fact, it can go as low as nearly 0 and as high as 7.5! That's not good. Maybe soldier strength is "weighted" so to speak, or perhaps the tilefactor is a variable. In any event, more crunching is necessary to see what's going on. BTW: any of you are free to use my data to formulate an equation. :drink:

 

Excel: Strength_vs._Throwing_Distance.zip

Adobe pdf: Throwing_Distances_based_on_Str_and_Wei.zip

 

- Zombie

Link to comment
Share on other sites

All I know of throwing anything is that after a certain point, I've had occasions where the throw couldn't go through because the game I would suppose, want a large arc for throwing. The soldiers I've been training up in a recent game, I've found the sweet spot to be somewhere between 40-50 strength with a throwing accuracy in the low 80's.
Link to comment
Share on other sites

According to the data, with the minimum item weight in the game set at 3 and the strength range of a soldier is 20-71, you should be able to throw almost anywhere on the map (barring obstructions of course). Well, not anywhere, 33 tiles is the maximum distance possible. That leaves 17 tiles which you can't throw to (at least on a 50x50 map). The smaller ship maps have a 40x40 area so you would be short by 7 for them. Still, these restrictions aren't all that bad. I mean, how often do you need to throw an item completely across the map? That's what the grenade relay is for. :drink:

 

- Zombie

Link to comment
Share on other sites

Lessee now... Weight is a divisor of some sort. Minimum distance appears to be 2. Strength is a factor which seems to be doubled, an operation that must be performed before rounding.

 

Hence the formula is something like this:

 

int(2 * strength / weight) + 2

 

And that's all I have time for at the moment.

 

Zombie, I don't suppose it's too much to ask that you test weight/strength with values of 0? That'd make things much, much easier.

 

For now, it can safely be assumed that "unable to throw here" messages have nothing to do with the distance an object can be thrown, but rather mean that the items arc is obstructed. That is to say, a ceiling of some sort blocks the way - the item can't travel high enough. It seems likely to me that the game first calculates that distance, and then uses a seperate formula to work out whether the arc is valid or not, so stick with recording the highest distance possible before you get the "out of range" message just for now.

 

I'll rig up a new logger that automates the strength/weight edits and auto-records the distances achieved. I also have an idea how to best collect data for the arc height, but it involves a heck of a lot more throws and lots of different map configurations, so I'll make a map generator for that purpose. It'll be interesting to see if the game supports maps of more then four levels, too. It wouldn't surprise me if it does, the engine is very dynamic.

Link to comment
Share on other sites

Empirical thresholds:

 

Range	STR/WGT		
2	0.83	5/6 (old version was refuted; at weight 255, STR 212 is range 2, STR 213 is range 3)
3	1.16	50/43	
4	1.47	50/34	
5	1.85	50/27	
6	2.38	50/21	
7	2.78	50/18	
8	3.33	50/15	
9	3.85	50/13	
10	4.17	50/12	
11	4.55	50/11	
12	5	50/10	
13	5.56	50/9	
14	6.25	50/8	
16	7.14	50/7	
18	8.33	50/6	
21	10	50/5	
23	12.5	50/4	Except weight 7 (retest STR 86, 87)
27	16.67	50/3	
33	25	50/2	
46	50	50/1	
OOR

Instant OOR appears to be a bypass of a division by 0.

 

Some of these may need adjusting as the dataset enlarges.

Link to comment
Share on other sites

Testing in that Floater Terrorship map again, 50x50 (this is a 4-cell high map)....

 

Retesting STR 86,87 against weight 7 came up with range 23, not range 27. 27 was too much for the cutoffs I proposed.

 

STR 1, weight 255 is throwing range 2.

 

I'm not sure what the "fastest" testing sequence is. I'll leave the brute force verification to Zombie.

 

"fastest" means quickest verification/refutation, assuming that Zombie has found all possible throwing ranges, and that the throwing ranges are monotone non-decreasing in strength and monotone non-increasing in weight.

Link to comment
Share on other sites

Ooh, I have no idea what an empirical threshold is, but I reckon if I stared at that list long enough I could make something of it. :)

 

Dunno how much you've messed with X-Com formulas, but a rule to keep in mind is this: Any division always rounds down. For example, under normal math:

 

6 / ( 3 / 2 )

= 6 / 1.5

= 4

 

But with UFO integral math:

6 / ( 3 / 2 )

= 6 / 1

= 6

 

This can make results a little irregular, and probably explains why number ranges such as 15 get skipped. It's highely unlikely that a table system is used as many of the values Zombie tested aren't actually used in the game.

Link to comment
Share on other sites

Ooh, I have no idea what an empirical threshold is, but I reckon if I stared at that list long enough I could make something of it. :)
I hope so, because that's all I did to Zombie's table to get my initial estimates. Which bungled the initial threshold between range 2 and range 3.

 

Not only don't I have a formula that explains the table yet. I suspect that what's going on is a lookup table rather than a formula.

 

What I do know is that (within the test space), the table is "homogeneous" in strength and weight. (Regrettably, there are several mutually irrelevant definitions. I'm using the algebraic one, rather than the differential equation one that actually gets taught in undergraduate mathematics.)

 

Look at the entries for weight 1. E.g., weight 1, strength 1 has range 3 -- and if you multiply both sides by any of 2 through 10, it is also range 3.

 

And exactly the same for strength 2 through 25. If we exclude scalings whose needed strength exceeds 255, everything works. [The values I retested are missed by this mesh.] So the failure of intermediate ranges to appear is important: a simple formula should have generated a range of 15 somewhere before or in weight 10 in the exhaustive listing. The choice of far cutoffs looks like it's from whatever source Steve Jackson's GURPS used (table lookup, extreme examples are strength 25x weight and strength 50x weight).

 

This suggests the the ratio of strength to weight is being tested precisely, so it is possible that the actual comparison is of two integers being multiplied. (Cast to unsigned short from unsigned char to prevent overflow).

 

(fudge factor)*strength <= 50*weight

 

One way to do this would be to loop down through a lookup table until the condition goes off, with a failsafe of OOR should no range trigger. I haven't checked whether a simple integer math algorithm exists that gives range 46 for 1, range 33 for 2, and so on through range 2 for 20. [That would go a long way towards removing the lookup table.]

Link to comment
Share on other sites

It's highely unlikely that a table system is used as many of the values Zombie tested aren't actually used in the game.
V1.0 had uncapped strength, and the Battlescape display goes to 150.

 

That throwing range goes automatic OOR at strength 151 for a weight 3 object suggests that whatever algorithm was used, was calibrated to not fail for any intended-displayable strength and any weight used in V1.0.

 

I'm thinking that if a formula exists, it's going to be taking a scaled integer quotient of something that itself was from a scaled integer quotient. I just don't immediately see how you're going to relate the long stretches of 33 and 46.

Link to comment
Share on other sites

I think zaimoni has put us on the right track. Those long stretches of the same values only make sense when you reverse Zombie's data & make a table of weight vs distance, and fill it with strength breakpoint values, like this:

 

 Dist	@ S (W=10)	W=9	W=5	5	9	10	(S/W)
2	0	0	0	0	0.0	0	
3	8	7	4	0.8	0.8	0.8	
4	11	10	5	1	1.1	1.1	
5	16	13	7	1.4	1.4	1.6	
6	18	16	9	1.8	1.8	1.8	
7	23	21	11	2.2	2.3	2.3	
8	27	25	13	2.6	2.8	2.7	
9	33	30	16	3.2	3.3	3.3	
10	38	34	19	3.8	3.8	3.8	
11	41	37	20	4	4.1	4.1	
12	47	40	22	4.4	4.4	4.7	
13	52	45	25	5	5.0	5.2	
14	57	50	27	5.4	5.6	5.7	
16	64	56	31	6.2	6.2	6.4	
18	73	64	35	7	7.1	7.3	
21	84	75	41	8.2	8.3	8.4	S/W > 8.3
23	101	90	50	10	10.0	10.1	S/W > 10
27	126	112	62	12.4	12.4	12.6	S/W > 12.5
33	167	150	83	16.6	16.7	16.7	S/W > 16.6
46	251	225	125	25	25.0	25.1	S/W > 25
OOR			250	50			S/W > 50

 

So I agree there is a lookup table algorithm. Except for minor tweaking (and again I blame integer rounding, because it's handy), the below values can be used to make Zombie's table. (In Excel, replace the TRUE/FALSE cells with the formula "= ((Wgt*D7) < (Str*10))" where D is the "Look10" column. (Lookup value for a given distance scaled by 10 for integer math.) Then the first cell to come up TRUE will be the distance XCOM assigns a given weight and strength throw.)

 

Str	8			
Wgt	2	

Dist	Lookup	Look10	First TRUE is the gimmie	
OOR	50	500	FALSE	= ((Wgt*D7) < (Str*10))
46	25	250	FALSE	
33	16.6	166	FALSE	
27	12.5	125	FALSE	
23	10	100	FALSE	
21	8.3	83	FALSE	
18	7.3	73	FALSE	
16	6.4	64	FALSE	
14	5.7	57	FALSE	
13	5.2	52	FALSE	
12	4.7	47	FALSE
11	4.1	41	FALSE
10	3.8	38	TRUE
9	3.3	33	TRUE
8	2.7	27	TRUE
7	2.3	23	TRUE
6	1.8	18	TRUE
5	1.6	16	TRUE
4	1.1	11	TRUE
3	0.8	8	TRUE
2	0.1	1	TRUE

 

Sorry about the length... I could attach an XLS sheet, I suppose... and we still have the arc height algorithm to nail down.

Link to comment
Share on other sites

Just completed some spot checks on my end. The revised ratios I posted above allowed modifying Zombie's spreadsheet to include a "maximum strength for range for given weight" calculator, and a "minimum weight for range for given strength calculator". I think the game must do the calculations like the first, since it uses the floor function (so the test values could be obtained by integer math).

* All meaningful thresholds checked: STR 255/ all range transitions except 2/3, weight 255/ range transition 2/3.

* After using the rechecked values for STR 86,87/weight 7 (23 rather than 27), exactly replicates weight columns 1-10.

Link to comment
Share on other sites

Did I make a mistake gathering numbers? Darn it! I was pretty careful, but it's bound to happen on a scale this large. Sorry about that. :)

 

If anyone needs to attach something (spreadsheet), please email me and I'll add it in. Right now we don't allow members to add attachments.

 

Oh, yeah. Some shortcuts can be made to get a more diverse table. When a throwing distance of 2 is reached for a certain strength, 2 will continue to be the distance as weight is increased to 255. That's a fact. And I didn't include throwing distances when weight is 0. The result was always OOR or something so it didn't make sense to have this listed. :)

 

- Zombie

Link to comment
Share on other sites

Knowing weight of 0 always gives OOR is still something - It suggests a division by 0, which confirms that weight is indeed a divisor.

 

I still don't like the idea of a table lookup system, quite simply because I don't see any good reason to use one. What's the point in writing a table when a simple formula would suffice? I highely doubt that they cared about defining throwing distances enough to put that much work into it. Remember, the ranges we see are defined by humans.

 

Furthermore, even though v1.0 allows the full range of strength values (even those below minimum recruitment level, due to the overflow bug), it does not allow the full range of item weights. No items below weight of three appear in game. The heaviest weigh in at 50 units, though admittidly can't be carried.

 

I'm also still against the idea of treating UTTH as the same as OOR. If it turns out that UTTH messages are influenced by the dimensions of the map, as I strongly suspect they are, then of course the results are going to be too abstract to reveal a formula based on strength and weight.

 

Yeah, I know I sound like a naysayer, but I don't have time to do anything but whinge at the moment. :) Gimme a few days and I should be able to come up with something more concrete.

Link to comment
Share on other sites

I feel the same way, BB. It's doubtful that there is a lookup table as some weights and strengths aren't normally possible and programming a whole slug of numbers into the executable is so much harder than plopping in an equation of some sort. :)

 

I'm also still against the idea of treating UTTH as the same as OOR. If it turns out that UTTH messages are influenced by the dimensions of the map, as I strongly suspect they are, then of course the results are going to be too abstract to reveal a formula based on strength and weight.

Well, the "Unable to throw here" message may indeed be based on map size. As I said, my tests were performed on a 50x50 map. I think the Small Scout map is 40x40, no? I'll run some tests on that landscape to see if that has an effect on UTTH/OOR. If it does, then I'm still convinced that a universal equation can be formulated to tie map size, strength and weight into a simple throwing distance. If the programmers programmed an equation in, then we can get it out... somehow. :)

 

- Zombie

Link to comment
Share on other sites

The UTTH message is also influenced by stance. I decided to check the range difference between crouching and standing for weight 11, STR 184 (while doing the range 27/33 cutpoint checks by weight...proposed ratio passes). Standing is range 33 before UTTH, crouching is range 34 before UTTH

 

No boost for standing range 27. But when the standing range is 46, the crouching range is 47.

 

IIRC, the small scout map has the same height as the map you're testing on (four cells), so the ceiling chop should behave the same.

Link to comment
Share on other sites

So crouching extends the range by 1? Interesting.

 

Ok, so if map height is going to affect things perhaps a nuked out alien storage facility or a couple X-COM hangars with the walls removed will do the trick. I'll have my work cut out for me. :)

 

- Zombie

Link to comment
Share on other sites

So crouching extends the range by 1? Interesting.

 

Ok, so if map height is going to affect things perhaps a nuked out alien storage facility or a couple X-COM hangars with the walls removed will do the trick. I'll have my work cut out for me. :)

 

- Zombie

Well....not sure if it does so reliably. [it certainly didn't help the 27-range any.] An exhaustive pass at weight 10 would be an informative sample.

 

Crouching certainly would "lower" the computed trajectory slightly (in the 16x16x12 detailed space model). If the arc-breaker was the virtual ceiling (trying to go to machine cell height -1), then lowering the trajectory could make the difference between UTTH and throwing in borderline cases.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
  • Create New...