Difference between revisions of "Car parameters"

From Stunts Wiki
(→‎Dashboard controls: 152h and 228h)
(Partial rewrite, quite a lot of stuff added.)
Line 3: Line 3:
 
==Preliminary notes==
 
==Preliminary notes==
  
* Byte offsets will always be referred to as hex-addresses. That is the normal behaviour for any usual hex-editor, but not that of [[Car Blaster]], where you must press "h" to display offsets in hexadecimal. More importantly, on this document bytes are classified as ''even'' or ''odd'' depending on the hex address, giving opposite results to what one gets with decimal counting (for the first byte of a file is offset 0h). Byte values may be quoted both ways for the sake of convenience; thus an "h" will be appended to any hex number on this article.
+
=== Hexadecimal numbers ===
  
* Several important parameters are expressed as 2-byte [http://en.wikipedia.org/wiki/Endianness little endian] integer numbers. On layman terms, we could say their value is defined by two consecutive bytes defining a four digit hexadecimal, ''xxyy''h. The first one of them sets the ''yy'' digits and the last one the ''xx'', so that a change of 1 in the first byte causes a change 1/256 (or 1/100h) smaller than a change of 1 in the second byte. Any mention to one byte doing the ''gross adjustment'' and another the ''fine tuning'' of a parameter implies such kind of control. Also, when quoting values that way, italics will be used for clarity.
+
In order to properly read and edit the parameter values, you will need to make decimal/hex conversions. Most familiar software calculators are able to perform the conversion as well as the basic operations on hex numbers, so that should not be a problem. If you wish to do the conversions by hand or mentally, remember that hex digits go from 0 to 15 (with letters A...E standing for 10...15), and that each digit to the left is one power of 16 higher (instead of a power of 10 as with decimal numbers). For instance, 17E9h = 1*16^3 + 7*16^2 + 12*16^1 + 1 = 6081 .
 +
 
 +
=== Car Blaster conventions ===
 +
 
 +
Unlike regular hex editors, [[Car Blaster]] defaults to displaying both byte addresses and byte values in decimal values. That can often be an inconvenience, so we will not stick to that convention. On this article, byte addresses will always be quoted as hexadecimal numbers. Byte and parameter values can be quoted both ways depending on the situation, so to make the writing clear an "h" will be appended to all hexadecimal numbers. It is simple to switch between hex and decimal display in Car Blaster - just press 'h' for switching the addresses or 'Shift+h' for switching the values.
 +
 
 +
=== Parameter types ===
 +
 
 +
Unlike Car Blaster interface suggets, the values of the parameters usually do not correspond to a single byte in the CAR*.RES. They may be stored in a few different ways, which we'll refer to as data types. Understanding them is often key to reading the values correctly. A description of them is provided below:
 +
 
 +
==== Integers ====
 +
 
 +
The most common and important data type. Integer parameters occupy ''two'' bytes in the file, and they should be read together to form the value in the following way:
 +
 
 +
* Pick the byte values ''in hexadecimal'' and append one to the other ''in inverted order'' (second byte comes first)'. Doing so will give you a four-digit hex number (the technical term for this representation is [http://en.wikipedia.org/wiki/Endianness little endian]).
 +
** If the number is 7FFFh (=32767) or smaller, it is the parameter value.
 +
** If it is larger than 7FFFh, however, the parameter is not really a very large integer number, but rather a ''negative'' integer stored at a particular way (called the [http://en.wikipedia.org/wiki/Two's_complement two's complement]). To recover the real value, subtract the value you read from the file from 10000h (=65536) and invert the sign of the result.
 +
* The value thus obtained is the actual parameter value, and can be used as you wish, either in hex or converted to decimal.
 +
* Two examples: Let's say an integer parameter has byte values of 18 and 2C. Grouping the values in inverted order gives 2C18h, which is smaller than 7FFFh. Therefore, the parameter value is 2C18h = 11288 . Now, another integer parameter might have values of 40 and FC. Grouping gives FC40h, which is larger than 7FFFh. Therefore, the real value is the two's complement, -(1000h - FC40h) = -03C0h = -960 .
 +
 
 +
From the above description, it can be inferred that an alternate way of reading the values is to sum, in decimal, the value of the first byte to the second one multiplied by 256 (and then taking the two's complement if the value is greater then 32767). Doing so avoids dealing with hexadecimals, but is far less convenient if you have an hex calculator available. A practical remark is that the second byte changes the parameter value at a rate 256 times faster than the first one. For some parameters, the second byte may thus be though of as the "main" one, and the second one as a "fine adjustment". For other parameters, though, the second parameter defaults to zero, and a change of 256 units may be exaggerate for most useful purposes, and therefore we will be most of the time interested on the first byte. A final remark is that negative integer parameters are usually easy to recognize in Car Blaster through the very large second byte values.
 +
 
 +
==== Unsigned integers ====
 +
 
 +
These are the same as integers, except they are always positive, and so you don't need to worry about taking the two's complement for large values. Else, all remarks made above still hold.
 +
 
 +
==== Bytes ====
 +
 
 +
While most parameters are 2-byte integers, some are nevertheless stored as single bytes. These are naturally a lot simpler to handle - just read the value directly, either in hex or in decimal. Single byte parameters are always unsigned.
 +
 
 +
==== Pairs and triplets ====
 +
 
 +
When there is need to represent the position of a point, pairs and triplets of values are employed. For 2D coordinates, defined over a bitmap, a pair of consecutive values is employed, standing for horizontal (x) and vertical (y) coordinates. For 3D coordinates on the "physical world", triplets are used instead, with values standing for x-y-z (width, height and length) coordinates in that order. The values themselves may be integers or single bytes, depending on each case. Pairs and triplets will be represented on this article by enclosing the values in brackets.  
  
 
==Engine and Transmission==
 
==Engine and Transmission==
Line 11: Line 43:
 
===Torque curve===
 
===Torque curve===
  
'' '''Address:''' 60h-C7h ''
+
'' '''Data type:''' [[#Bytes|Bytes]] ''
 +
 
 +
'' '''Address:''' 61h...C8h (104 bytes)''
  
Defining how much acceleration the engine can impart on a car at every given engine speed (rpm), the torque curve is naturally a very important factor in determining performance. Every byte navigated forward corresponds to increments of 125rpm. The curve works as expected: raising a byte increases linearly acceleration given by the engine at a given rpm. A more peaky torque curve means a narrower range of useful engine speeds - and thus, the driver will have to shift more often. Another important point is to remember adjusting offsets [[Car parameters#Maximum rpm|32h and 33h]] properly depending on where the torque curve is intended to end.
+
Defining how much acceleration the engine can impart on a car at every given engine speed (rpm), the torque curve is naturally a very important factor in determining performance. Every byte navigated forward corresponds to increments of 128rpm, so that byte 61h covers 0...127rpm; 62h, 128...255rpm and so on. There are 104 bytes in total, and so the engine can deliver power over a range of 13312rpm. The curve works as expected: raising a byte increases linearly acceleration given by the engine at a given rpm. A more peaky torque curve means a narrower range of useful engine speeds - and thus, the driver will have to shift more often.
  
===Number of gears===
+
===Idle rpm torque===
  
'' '''Address:''' 26h ''
+
'' '''Data type:''' [[#Bytes|Byte]] ''
  
Self-explanatory. Valid options go from 1 to 6 gears. Note that for a 6th gear the appropriate parameters will have to be defined elsewhere.
+
'' '''Address:''' 60h''
  
===Idle rpm===
+
This may be thought as a special point in the torque curve. It overrides a section of the curve at low rpms, in order to better represent the car launch from a standstill. The affected range is 0...2559rpm (the first 20 bytes of the curve) for the 1st gear, and 0...''value of idle rpm'' (described further down the article) for 2nd gear and above.
 +
 +
===Number of gears===
  
'' '''Address:''' 2Ch - fine tuning (1rpm units); 2Dh - gross adjustment (256rpm units).''
+
'' '''Data type:''' [[#Bytes|Byte]] ''
  
This parameter controls the minimum rpm value to be shown on the rev meter, supposedly while the car is stopped or starting to accelerate. Since engine speed and car speed are always linked in Stunts (in other words, the clutch is always engaged!), the parameter is purely cosmetic.
+
'' '''Address:''' 26h ''
  
'' '''Useful note on all rpm parameters:''' ''As raising a byte on the gross adjustment offset raises the value in rpm by about 250, it is reasonable to assume the variation is exactly 256rpm. That way, the ''xxyy''h value mentioned in the [[Car parameters#Preliminary notes|preliminary notes]] can be taken as the true rpm value in hexadecimals. For instance, 2Ch = F0h and 2Dh = 02h would give an idle rpm of 02F0h = 752rpm.
+
Self-explanatory. Acceptable values range from 1 to 6. If you plan to add a 6th gear to a car, remember to set all other gearing parameters described further on.
  
 
===Downshift rpm===
 
===Downshift rpm===
  
'' '''Address:''' 2Eh - fine tuning (1rpm units); 2Fh - gross adjustment (256rpm units).''
+
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 2Eh/2Fh ''
  
This is the downshift rpm point used by the automatic transmission. For optimal performance, it should match the rpm position of the torque curve's peak.
+
This is the downshift rpm point used by the automatic transmission. For optimal performance, it should match the rpm position of the torque curve's peak. ''Observation for all rpm parameters:'' the parameter values gives the actual number of rpm directly, so it does not make much sense to highlight a "main" adjustment byte in this case.  
  
 
===Upshift rpm===
 
===Upshift rpm===
  
'' '''Address:''' 30h - fine tuning (1rpm units); 31h - gross adjustment (256rpm units).''
+
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 30h/31h''
  
 
This is the upshift rpm point used by the automatic transmission. For optimal performance, it should match the rpm position of the power curve's peak - remember that, at any given rpm, power = torque * rpm; you may estimate a power curve in arbitrary units from the torque curve that way.
 
This is the upshift rpm point used by the automatic transmission. For optimal performance, it should match the rpm position of the power curve's peak - remember that, at any given rpm, power = torque * rpm; you may estimate a power curve in arbitrary units from the torque curve that way.
Line 43: Line 83:
 
===Maximum rpm===
 
===Maximum rpm===
  
'' '''Address:''' 32h - fine tuning (1rpm units); 33h - gross adjustment (256rpm units).''
+
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 32h/33h ''
 +
 
 +
This parameter is the maximum rpm (the "redline") of the engine. Whenever the engine goes beyond this value, the rpm value will be reduced at the next time step (1/20th of a second) so that it fits again within the limit (such behaviour explains why the rev meter oscillates when the maximum rpm is reached). Naturally, this value should be adjusted whenever the torque curve is extended to higher rpms. A maybe less obvious fact is that, as there is no other limitation to the maximum rpm, this parameter can be set to an arbitrary high value - well beyond the end of the torque curve or even the maximum size of the torque curve if you wish, and all engine speeds (and thus car speeds) made available can be reached by jumping, even if there is no torque available on the rpm range. As a very important consequence, the maximum rpm defines, together with the gear ratios, the overall top speed of the car.
 +
 
 +
===Idle rpm===
 +
 
 +
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 2Ch/2Dh''
 +
 
 +
The so-called "idle rpm" modulates the engine behaviour at low rpms. The main function of the parameter is to define up to which rpm value the "idle rpm torque" will be used instead of the regular torque curve for the second gear and above. In addition, the idle rpm sets the "sensory" indicators of the engine speed (rev meter position and engine sound pitch) to a fixed value from zero rpm to its value (since car speed and engine speed are always coupled, the ''actual'' rpm value is not fixed, however). If this value is set higher than the maximum rpm, the car will be unable to move. The values can be made equal, though - that is an useful trick to make a constant-torque engine over an arbitrary range of engine speeds if you don't mind having an useless rev meter and an annoying constant high-pitch engine sound buzzing.
  
This parameter is the maximum rpm (the "redline") of the engine. Unlike the [[Car parameters#Idle rpm|Idle rpm]] parameter, this one is ''not'' cosmetic - the torque curve will be cut off at the chose rpm, and thus the value should be adjusted whenever the torque curve is extended to higher rpms.
 
  
 
===Gear ratios===
 
===Gear ratios===
  
'' '''Address:''' 37h - 41h (odd addresses only)''
+
'' '''Data type:''' [[#Unsigned integers|Unsigned integer]]s ''
 +
 
 +
'' '''Address:''' 36h/37h...40h/41h (6 integers)''
  
These parameters set the gear ratios of the car, and are thus very important ones. 37h sets 1st gear, 39h the second one, and so on - unlike for the rpm parameters, the even addresses have no effect whatsoever. A higher value means a shorter ratio, and thus higher acceleration but less final car speed for that certain gear (at any rpm effective torque is proportional, but wheel speed is inversely proportional, to gear ratio). In fact, the exact relation which dictates how the gear ratios work is astonishingly simple: car speed (mph) = engine speed (rpm)/ gear ratio value. A realistic car need of course to have decreasing gear ratios, and for smoother engine operation a near-exponential decrease would be more adequate.
+
These parameters set the gear ratios of the car, and are therefore very important ones. 36/37h sets 1st gear, 38h/39h the second one, and so on. The gear ratios are overall values, representing the effects both the gearbox and the final drive gears as well as those of the wheel radius. As it could be expected, a higher value means a shorter ratio, and thus higher acceleration but less final car speed in a certain gear (at any rpm the torque delivered to the wheels is proportional to gear ratio, but wheel speed is inversely proportional). The exact interpretation of the value of is straightforward:
 +
car_speed_mph = 256*engine_speed_rpm/gear_ratio 
 +
This is by far the most useful equation to know when setting the parameters of a car, as it allows to predict car speeds in downshift/upshift points and real top speeds for each gear as well as finding the torque on each. A realistic car needs of course to have decreasing gear ratios, and for often desirable smoother engine operation a near-exponential decrease would be adequate.
  
 
==Physics parameters==
 
==Physics parameters==
Line 57: Line 112:
 
===Car mass===
 
===Car mass===
  
'' '''Address:''' 28h - fine tuning; 29h - gross adjustment (of little use).''
+
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 28h/29h''
  
This parameter has ben variously described over the years as "inverse power amplification" ([[Mark Nailwood]]) or "aerodynamic resistance" ([[Juha Liukkonen]] / [[Lukas Loehrer]]). A true aerodynamic coefficient effect, however, would affect car more strongly at high speeds. Raising this parameter causes a decrease in acceleration directly proportional to the increment, all gears being equally affected. Therefore, the parameter is best regarded as being the car mass. Clearly, it has crucial importance to the car performance, being the only non engine/transmission parameter to limit acceleration. An important observation is that raising 29h will cause a huge increase in the car mass, enough to make adjustment of that byte (changing it from zero) quite useless.
+
This parameter had been variously described over the years as "inverse power amplification" ([[Mark Nailwood]] in Car Blaster) or "aerodynamic resistance" ([[Juha Liukkonen]] / [[Lukas Loehrer]]). Were it an aerodynamic coefficient effect, however, it would affect car more strongly at high speeds. Raising the parameter causes a decrease in acceleration directly proportional to the increment, all gears being equally affected. Therefore, it is best understood as being the car mass. Clearly, it has crucial importance to the car performance. The original Stunts cars have masses ranging from 15 to 55 (in decimal); the second byte defaults to zero and increasing it raises the mass way too fast, so it is usually disregarded. Another very important fact about mass - almost as important as the regular physical effect - is that its value sets the kind of [[Power Gear]] or [[Anti-Power Gear]], if any, that the car will have (a complete explanation will be provided soon elsewhere in the Wiki; in the meantime check this [http://forum.stunts.hu/index.php?topic=2273.msg41881#msg41881 forum post]).
  
 
===Braking effectiveness===
 
===Braking effectiveness===
  
'' '''Address:''' 2Ah - fine tuning; 2Bh - gross adjustment.''
+
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 2Ah/2Bh''
  
As the name says, those addresses tell how powerful the car brakes will be. The relation is approximately linear, so ''0100''h will make a car go from 97mph to a full stop in ~4.6s, ''0200''h will halve that time and ''0000''h will require several minutes... Other parameters, such as mass or grip, have no effect on braking.
+
As the name says, those addresses tell how powerful the car brakes will be. The effect of the brakes is proportional to the value - any apparent slight deviations from the prediction are in fact effects of aerodynamic resistance. Typical values are close to 0100h (=256), except for racing cars, which may have significantly better brakes. Setting the parameter to ''0000''h will turn them off completely, and thus the car will only be stopped by aero drag and, eventually, grass slowdown. Other parameters, such as mass or grip, have no effect on braking.
  
 
===Aerodynamic resistance===
 
===Aerodynamic resistance===
  
'' '''Address:''' 5Eh - fine tuning; 5Fh - gross adjustment (of little use).''
+
'' '''Data type:''' [[#Integers|Integer]] ''
  
This elusive parameter controls aerodynamic resistance encountered by the car when thundering down a straight. Aerodynamic drag increases quadratically with speed (that is, proportional to the square of) up to the point the engine can't produce enough torque to overcome it and the car reaches its top speed. Therefore, increasing aeroydnamic resistance will lower the car top speed in a flat straight line (that is, no jumps or [[Power Gear]]), as well as significantly reduce acceleration at high speeds. One point to note about the parameter is that the "gross adjustment" of address 5Fh, like Car mass' 29h, is extremely brutal, to the point of making it nearly useless to raise it from zero - varying 5Eh is more than enough for any usual tuning needs.
+
'' '''Address:''' 5Eh /5Fh''
 +
 
 +
This elusive parameter controls aerodynamic resistance encountered by the car when accelerating down a straight. Aerodynamic drag force increases quadratically with speed (that is, proportional to the square of) up to the point the engine can't produce enough torque to overcome it and the car reaches its top speed. Therefore, increasing aerodynamic resistance will lower the car top speed in a flat straight line (that is, no jumps or [[Power Gear]]), as well as significantly reduce acceleration at high speeds. The parameter value is directly proportional to the drag force. It can be verified that for a given set of values for gear ratio, torque and aero coefficient, the maximum possible speed value will be given by:
 +
max_speed_mph = sqrt(2*torque*gear_ratio/aero_resistance)
 +
This relation allows to predict the flat track top speed of a car.
 +
 
 +
Aero drag also determines how fast the car will lose speed when the accelerator is not being held. It should, additionally, make the car slow down whenever it reached speeds higher than the flat-track top speed (when landing from a jump, for instance). Due to the same bug which originates powergear, however, this effect is not observed for any of the original Stunts cars (only those with multiple of 2 mass values work "properly"). This fact has very important consequences for the driving techniques of Stunts cars. Finally, usual values for the aero coefficient are similar in magnitude to those of mass, ranging from 20 to 52 for the original cars.
  
 
===Grip===
 
===Grip===
  
'' '''Address:''' CAh - fine tuning; CBh - gross adjustment.''
+
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' CAh/CBh''
 +
 
 +
This is the primary handling parameter. Higher values make it possible to take corners at higher speeds without skidding, and thus raise cornering speeds as well as lower the risk of loss of control (at the rather small cost of making controlled sliding harder, which sometimes can be an inconvenience in competition racing). A general idea of the magnitude of the parameter may be gained by attempting to drive snake lines on an asphalt track without skidding. With grip at 0100h, the car starts to skid at ~70mph. Raising to 0200h allows one to swerve without skidding almost up to 150mph. The default cars have values ranging from slightly lower than 0100h to slightly higher than 0200h.
 +
 
 +
===Surface grip modifiers===
 +
 
 +
'' '''Data type:''' [[#Integers|Integer]]s ''
 +
 
 +
'' '''Address:''' DCh/DDh...E2h/E3h (4 integers)''
 +
 
 +
These values are responsible for modifying the car grip according to the kind of surface it is on. The four integer values correspond to the four kinds of surface of Stunts - asphalt, dirt, ice and grass, in that order. Most cars have these set to 0100h, 0C00h, 0400h and 0800h, and thus asphalt grip = (4/3)*dirt grip = 4*ice grip = 2*grass grip. [[LM-002]], as an off-road car, is a notable exception.
 +
 
 +
===Sliding oversteer and air-sliding===
 +
 
 +
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' DAh/DBh''
 +
 
 +
This parameter is set to zero on all original cars. Raising it from the default value has two related effects. First, it will make the car rotate faster as it slides, roughly as if the grip was raised. The other effect is making the "air slides" (the mid-air spinning of car gone airborne) more pronounced - even if the car was not sliding before leaving the ground. Setting it at a too high value will make the car extremely sensitive to direction changes when it leaves the ground, and thus make it largely undriveable.
 +
 
 +
===Car dimensions===
 +
 
 +
'' '''Data type:''' [[#Pairs and triplets|Triplet]] of [[#Integers|integers]] ''
 +
 
 +
'' '''Address:''' (F8h...FDh)...(10Ah...10Fh) (4 triplets)''
 +
 
 +
These values set the width and length of the car, which are used mostly everywhere - collision detection for track objects, reorientation of the car when reaching a ramp or any kind of different surface, verification of whether the car is fully/partly on grass, etc. The size data is stored as a set of four point coordinates (thus, four triplets). Each point is a vertex of a four-sided polygon which represents the car. The first triplet corresponds to the front/left vertex; the other three stand for the remaining vertexes, ordered in clockwise order. As usual, the first value of the triplet is the x (left/right) coordinate, and the third one the z (back/front) one. The second value, which would seem to work as y (vertical) coordinate, has no effect over the car behaviour, and is always set to zero. The coordinate values are taken relative to the middle of the car, and both the sum of x coordinates and the sum of y coordinates must be zero - not following this recommendation will result in bugs such as the car moving forward or rotating on its own. Most reasonable cars will be a rectangle symmetrical about the centre of the car, and thus the values in the four triplets will be:
 +
(-half_width, 0, +half_length; -half_width, 0, +half_length; -half_width, 0, +half_length; -half_width, 0, +half_length)
 +
Taking the original cars as reference, the length and width values usually do not match the full length of the 3D shape ([[3D shapes (st*.p3s)|car1]] resource in ST*.3SH); the dimensions being often closer to wheel-to-wheel distances (as becomes clear when crashing a car at some obstacle - for most cars the actual crash only happens when the front wheels hit the obstacle). Based on this fact, the ratio between the physical coordinates and the 3D shape coordinates may be estimated as being 32:1.
 +
 
 +
====Influence of length on handling====
 +
 
 +
The car length, as defined by the z coordinates of the vertexes, has major effects over car behaviour. Shortening a car will make it change direction faster, as if the moment of inertia had been reduced. As a consequence, shorter cars will:
 +
* Have more nimble steering, a fact which not only makes them easier to drive but also allows for higher cornering speeds at the same grip levels - since less steering effort will be needed to turn the car, the risk of skidding will be significantly reduced.
 +
* Land at shorter distances from jumps, as the car will be pointing down earlier on the flight.
 +
* Be more sensitive to surface changes, and generally have more twitchy behaviour. A key consequence of that is causing effects such as [[Magic Carpet|magic carpet]]s more likely.
 +
The unique handling characteristics of [[Audi]] and [[Lancia]] are a consequence of their short length, which gives them much better handling than other slow cars and makes them more prone to random bugs.
 +
 
 +
===Dimensions for car-car collisions===
 +
 
 +
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' EEh/EFh, F0h/F1h and F2h/F3h ''  
  
This is the lone handling parameter. Higher values mean extra adhesion and thus less tendency of sliding and loss of control in corners. Since there is no reliable way of doing a corner at constant speed, this parameter is harder to quantify. A crude idea may be gained from attempting to do narrow snake lines around the central line in asphalt. With grip at ''0100''h, the car starts to skid at ~70mph. Raising to ''0200''h allows one to swerve without skidding almost up to 150mph.
+
These three integers set alternate half-width, height and half-length values for the car which are only used for the detection of car-car collisions. Unlike the main set of dimensions, these correspond roughly to the full length and width of the car as given by the car1 3D shape, and the units are the same as the ones on car1. If values are all set to zero, it becomes possible to drive straight through the opponent car, like in Trackmania for instance. Unfortunately, the AI won`t realize that and will still swerve to avoid your car even if it is not necessary to do so.
  
 
==Dashboard controls==
 
==Dashboard controls==
Line 85: Line 194:
 
===Shifting knob positions===
 
===Shifting knob positions===
  
'' '''Address:''' 46h - 5Ch (even addresses only) and 44h''
+
'' '''Data type:''' [[#Pairs and triplets|Pairs]] of [[#Integers|integers]] ''
 +
 
 +
'' '''Address:''' (46h/47h,48h/49h)...(5Ah/5Bh,5Ch/5Dh) (6 pairs)''
 +
 
 +
These parameters control where the knob will appear at each gear. The first integer of the pair sets the x coordinate, and the second one, the y coordinate. The reference frame for knob internal coordinates is the gbox bitmap at the stda* file (as the example image illustrates). When editing these values (as well as the centre position to be explained below) it is important to be realize that the distance between two gear positions and the number of direction changes while moving from one to another affects the time needed to engage the gear. Such variations can have very noticeable effects on straight-line acceleration. Therefore, car tuners should be wary when modifying knob positions of an existing car so as to not alter the car performance and thus compromise pre-existing replays.
 +
 
 +
===Shift pattern centre line===
 +
 
 +
'' '''Data type:''' [[#Integers|Integer]] ''
 +
 
 +
'' '''Address:''' 44h/45h ''
 +
 
 +
This is a complementary value to the shifting knob positions. It sets at which y coordinate value the knob will switch from one column to another on the shift pattern; and thus it will most likely it is to be set halfway between the upper and lower rows of gear positions. The coordinate frame is the same of the knob positions.
  
These parameters control where the knob will appear at each gear. Bytes 46h, 4Ah, etc. set horizontal positions of each gear, and their counterparts 48h, 4Ch, etc. set vertical positions. The reference frame for knob internal coordinates is the gbox bitmap at the stda* file (as the example image illustrates). Additionally, byte 44h is the vertical coordinate that sets the height at which the gear knob switches from one column to another on the shift pattern; most likely it is to be set halfway between the upper and lower rows of gear positions. It is important to notice the distance between two gear positions and the number of direction changes while moving from one to another affects the time needed to engage the gear. Such variations can have noticeable effects on straight-line acceleration; therefore car tuners should be wary when modifying knob positions of an existing car so as to not alter the car performance and thus compromise pre-existing replays.
+
===Apparent car height===
  
===Car height===
+
'' '''Data type:''' [[#Integers|Integer]] ''
  
'' '''Address:''' F6h - fine tuning ; F7h - gross adjustment''
+
'' '''Address:''' F6h/F7h ''
  
This sets the apparent height from the ground on cockpit (F1) view; F6h performs rather small increments and F7h truly massive ones. The parameter has no effect on the 3D model, so if you fancy setting this to a ridiculously high value the car won't crash into roofs - rather, you'd better worry with things ''below'' your eyes...
+
This sets the apparent height from the ground on the inside (F1) view. The units are the same than those of the car1 3D shape. The parameter has no effect on the physical characteristics of the car, so you do not need to worry about crashing at roofs if you set it way too high...  
  
 
===Steering wheel dot movement===
 
===Steering wheel dot movement===
  
'' '''Address:''' 110h - 14Dh ''
+
'' '''Data type:''' [[#Pairs and triplets|Pairs]] of [[#Bytes|Bytes]] ''
 +
 
 +
'' '''Address:''' (110h,111h)...(14Ch,14Dh) (1+33 pairs)''
  
Now those are quite capricious. The first pair of bytes control the dot position with the wheel centered. As for the other 33 pairs, each one controls dot position for a certain amount of steering applied ''both'' when turning to the right (actual coordinate value) and to the left (horizontal coordinate is mirrored relative to the central dot). This also means that displacing the center point without adjusting the other points will cause the left-side points do be displaced with the central, but not the right side points... Anyway, ''even'' bytes control horizontal position and ''odd'' bytes define vertical position. The reference frame for internal coordinates is stda* whl2 bitmap.
+
These pairs of bytes control the position of the steering wheel dot over its full range of movement. The first pair is the dot position with the wheel centered. As for the other 33 pairs, each one controls the dot position for a certain amount of steering applied ''both'' when turning to the right (actual coordinate value) and to the left (horizontal coordinate is mirrored relative to the central dot). This also means that displacing the center point without adjusting the other points will separate the right side points from the left side ones... Anyway, the reference frame for the internal coordinates is stda* whl2 bitmap.
  
 
===Speedometer needle movement===
 
===Speedometer needle movement===
  
'' '''Address:''' 14Eh - 223h ''
+
'' '''Data type:''' [[#Pairs and triplets|Pairs]] of [[#Bytes|Bytes]], plus one pair of [[#Integers|integers]] and a single byte ''
 +
 
 +
'' '''Address:''' (14Eh/14Fh,150h/151h), 152h, (154h/155h)...(222h,223h) (1 pair of integers, 1 integer and 104 pairs of bytes)''
  
Like the other meters, the movement is controlled by the position of individual points; each point being assigned a pair of bytes, the first byte setting horizontal position and the second setting vertical with reference to the coordinates of stda* ins2 bitmap. The pair 14Eh/150h defines the center point (horizontal and vertical, respectively). Byte 152h sets the number of needle positions to be displayed. The tip of the needle for each speed is controlled by consecutive pairs from 154h on, even bytes setting horizontal position and odd bytes vertical position. Each pair of bytes covers an interval of 2.5 mph, starting from zero. Finally, in case one needs to get rid of the needle altogether (like for IMSA dashboards), the easiest solution is to set 14Eh and 150h to FFh and 154h - 223h to zero - simply setting 152h to zero won't work as expected.
+
Like the other meters, the movement is controlled by pairs of values which set the position of individual points. In this case, the coordinate frame are the coordinates of stda* ins2 bitmap. The lone pair of integers starting at 14Eh defines the centre point for the needle. Byte 152h sets the maximum number of needle positions to be displayed. Finally, the position of the needle tip for each speed is controlled by the consecutive pairs from 154h on. Each pair of bytes covers an interval of 2.5 mph, starting from zero. Finally, in case one needs to get rid of the needle altogether (like for IMSA dashboards), the easiest solution is to set 14Eh and 150h to FFh and 154h - 223h to zero - simply setting 152h to zero won't work as expected.
  
 
===Digital speedometer===
 
===Digital speedometer===
  
'' '''Address:''' 150h - 159h ''
+
'' '''Data type:''' [[#Pairs and triplets|Pairs]] of [[#Bytes|bytes]]
 +
 
 +
'' '''Address:''' (154h,155h), (156h,157h) and (158h,159h) ''
  
This is a funny one. To have a digital speedometer first one needs to use the [[Corvette ZR1|Corvette]] moving dashboard elements file (that is, a copy of STDBVETT.PVS) or a custom stdb* containing the dig0...dig9 bitmaps of the individual digits. Also, a dashboard with proper contrast must be chosen (even if the game can switch number colours automatically depending on the background, some dashboards will still look awful). Then, byte 150h must be set to 0h. That will trigger the analog needle to disappear and be replaced by the set of digits, whose coordinates are controlled in the usual fashion by the pairs 154h/155h, 156h/157h and 158h/159h (first, second and third digits from left to right respectively). As for the coordinates' reference frame, it is stda* ins2 bitmap, just as for the analog speedometer.
+
This is a funny one. To have a digital speedometer first one needs to have a [[Car files#Dashboard moving parts (stdb*.pvs)|STDB*]] file containing the dig0...dig9 bitmaps used for the digits (the classic solution is to clone the [[Corvette ZR1|Corvette]] STDB*). Additionally, a dashboard with proper contrast must be chosen (even if the game can switch number colours automatically depending on the background, some dashboards will still look awful). Then, byte 150h must be set to 0h. That will trigger the analog needle to disappear and be replaced by the set of digits, whose coordinates are controlled in the usual fashion by the three pairs, which stand for the first, second and third digits from left to right respectively. As for the coordinates' reference frame, it is stda* ins2 bitmap, just as for the analog speedometer.
  
 
===Rev meter needle movement===
 
===Rev meter needle movement===
  
'' '''Address:''' 224h - 32Dh ''
+
'' '''Data type:''' [[#Pairs and triplets|Pairs]] of [[#Bytes|bytes]], plus one pair of [[#Integers|integers]] and a single byte ''
 +
 
 +
'' '''Address:''' (224h/225h,226h/227h), 228h, (22Ah/22Bh)...(32Bh,32Ch) (1 pair of integers, 1 integer and 130 pairs of bytes)''
  
The rev meter is completely analogous to the [[Car parameters#Speedometer needle movement|analog speedometer]]. The pair 224h/226h sets the center point, 228h sets the number of needle positions to be displayed and the pairs from 22Ah to 32Dh define the tip positions, totaling 130 positions available. Every pair of bytes covers 125rpm, and like for the speedometer there's an offset as well (second byte range is 250-375rpm, and so on). Else, the workings and details being the same as those discussed for the speedometer. Again, the reference frame is provided by stda* ins2 bitmap.
+
The rev meter is completely analogous to the speedometer. The pair of integers at 224h sets the centre point, 228h sets the number of needle positions to be displayed and the pairs from 22Ah to 32Dh define the tip positions, adding up to 130 available positions. Every pair of bytes covers 128rpm, starting from zero. Other details are just the same as those discussed for the speedometer. Again, the reference frame is provided by stda* ins2 bitmap.
  
 
==Text data==
 
==Text data==
  
 
===Car information===
 
===Car information===
 +
 +
'' '''Data type:''' Zero-terminated character strings''
  
 
'' '''Address:''' 32Eh - ???h ''
 
'' '''Address:''' 32Eh - ???h ''
Line 132: Line 263:
  
 
===Scoreboard car name===
 
===Scoreboard car name===
 +
 +
'' '''Data type:''' Zero-terminated character string''
  
 
'' '''Address:''' ???h - EOF ''
 
'' '''Address:''' ???h - EOF ''
Line 145: Line 278:
 
The initial bytes of CAR*.RES files consist of a file header, structured just like the ones found in uncompressed graphic files and elsewhere. Essentially, it stores file length, text IDs for different sections of the file and the associated byte offsets. Since that data is actually used by the engine to parse the car data, there is no reason to modify it unless one is hand-editing text data for the car and intends to modify string length - and even in that case, using [[Car Blaster]] and allowing it to perform any necessary adjustment is the recommended option.   
 
The initial bytes of CAR*.RES files consist of a file header, structured just like the ones found in uncompressed graphic files and elsewhere. Essentially, it stores file length, text IDs for different sections of the file and the associated byte offsets. Since that data is actually used by the engine to parse the car data, there is no reason to modify it unless one is hand-editing text data for the car and intends to modify string length - and even in that case, using [[Car Blaster]] and allowing it to perform any necessary adjustment is the recommended option.   
  
==="Graphical displacement ratio offset"===
+
===Unknown parameters===
  
'' '''Address:''' 10Fh''
+
Here is a list of the values on CAR*.RES which have unknown function. After somewhat extensive testing, they displayed no visible effect on the behaviour of the car in saved replays. Most of them are equal for all cars. 
  
This looks like some sort of Easter Egg... Default value for all cars is between F8h and FAh depending on the car (and is supposed to be kept as it is...). Now try lowering it by some 30 (1Eh) units and see what happens!
+
* 027h - single byte next to the number of gears, probably just a padding zero.
 +
* 034h/035h - strategically located next to the gear ratios. Unused space for a never-implemented reverse gear?
 +
* 0C9h - single byte between the torque curve and the grip parameter, probably just a padding zero.
 +
* 0CCh/0CDh - set to 00EEh for all cars.
 +
* 0CEh/0CFh - set to 00B8h for all cars.
 +
* 0D0h/0D1h - set to zero for all cars.
 +
* 0D2h/0D3h, 0D4h/0D5h, 0D6h/0D7h, 0D8h/0D9h - these form a suspicious-looking series with values 0020h, 0010h, 00C0h and 0008h, equal for all cars.
 +
* 0E4h/0E5h - set to zero for all cars.
 +
* 0E6h/0E7h, 0E8h/0E9h, 0EAh/0EBh, 0ECh/0EDh - another series of values, this time 0020h, 00C0h, 0080h and 0040h. The resemblance to the default values of the surface grip modifiers is uncanny.
 +
* 0F4h/0F5h - located just after the car-car bounding box. The value seems to grow with the half-length defined on the bounding box.
  
 
==See Also==
 
==See Also==

Revision as of 07:12, 30 April 2009

This article discuss how the car*.res parameters control the performance, handling, aesthetics and other aspects of a Stunts car. The parameters are grouped by function, in order to allow more fluent reading and discussion. A quick reference chart of byte addresses may be found at the Car files article. For a deeper discussion on the inner workings of physical parameters, refer to Car model physics .

Preliminary notes

Hexadecimal numbers

In order to properly read and edit the parameter values, you will need to make decimal/hex conversions. Most familiar software calculators are able to perform the conversion as well as the basic operations on hex numbers, so that should not be a problem. If you wish to do the conversions by hand or mentally, remember that hex digits go from 0 to 15 (with letters A...E standing for 10...15), and that each digit to the left is one power of 16 higher (instead of a power of 10 as with decimal numbers). For instance, 17E9h = 1*16^3 + 7*16^2 + 12*16^1 + 1 = 6081 .

Car Blaster conventions

Unlike regular hex editors, Car Blaster defaults to displaying both byte addresses and byte values in decimal values. That can often be an inconvenience, so we will not stick to that convention. On this article, byte addresses will always be quoted as hexadecimal numbers. Byte and parameter values can be quoted both ways depending on the situation, so to make the writing clear an "h" will be appended to all hexadecimal numbers. It is simple to switch between hex and decimal display in Car Blaster - just press 'h' for switching the addresses or 'Shift+h' for switching the values.

Parameter types

Unlike Car Blaster interface suggets, the values of the parameters usually do not correspond to a single byte in the CAR*.RES. They may be stored in a few different ways, which we'll refer to as data types. Understanding them is often key to reading the values correctly. A description of them is provided below:

Integers

The most common and important data type. Integer parameters occupy two bytes in the file, and they should be read together to form the value in the following way:

  • Pick the byte values in hexadecimal and append one to the other in inverted order (second byte comes first)'. Doing so will give you a four-digit hex number (the technical term for this representation is little endian).
    • If the number is 7FFFh (=32767) or smaller, it is the parameter value.
    • If it is larger than 7FFFh, however, the parameter is not really a very large integer number, but rather a negative integer stored at a particular way (called the two's complement). To recover the real value, subtract the value you read from the file from 10000h (=65536) and invert the sign of the result.
  • The value thus obtained is the actual parameter value, and can be used as you wish, either in hex or converted to decimal.
  • Two examples: Let's say an integer parameter has byte values of 18 and 2C. Grouping the values in inverted order gives 2C18h, which is smaller than 7FFFh. Therefore, the parameter value is 2C18h = 11288 . Now, another integer parameter might have values of 40 and FC. Grouping gives FC40h, which is larger than 7FFFh. Therefore, the real value is the two's complement, -(1000h - FC40h) = -03C0h = -960 .

From the above description, it can be inferred that an alternate way of reading the values is to sum, in decimal, the value of the first byte to the second one multiplied by 256 (and then taking the two's complement if the value is greater then 32767). Doing so avoids dealing with hexadecimals, but is far less convenient if you have an hex calculator available. A practical remark is that the second byte changes the parameter value at a rate 256 times faster than the first one. For some parameters, the second byte may thus be though of as the "main" one, and the second one as a "fine adjustment". For other parameters, though, the second parameter defaults to zero, and a change of 256 units may be exaggerate for most useful purposes, and therefore we will be most of the time interested on the first byte. A final remark is that negative integer parameters are usually easy to recognize in Car Blaster through the very large second byte values.

Unsigned integers

These are the same as integers, except they are always positive, and so you don't need to worry about taking the two's complement for large values. Else, all remarks made above still hold.

Bytes

While most parameters are 2-byte integers, some are nevertheless stored as single bytes. These are naturally a lot simpler to handle - just read the value directly, either in hex or in decimal. Single byte parameters are always unsigned.

Pairs and triplets

When there is need to represent the position of a point, pairs and triplets of values are employed. For 2D coordinates, defined over a bitmap, a pair of consecutive values is employed, standing for horizontal (x) and vertical (y) coordinates. For 3D coordinates on the "physical world", triplets are used instead, with values standing for x-y-z (width, height and length) coordinates in that order. The values themselves may be integers or single bytes, depending on each case. Pairs and triplets will be represented on this article by enclosing the values in brackets.

Engine and Transmission

Torque curve

Data type: Bytes

Address: 61h...C8h (104 bytes)

Defining how much acceleration the engine can impart on a car at every given engine speed (rpm), the torque curve is naturally a very important factor in determining performance. Every byte navigated forward corresponds to increments of 128rpm, so that byte 61h covers 0...127rpm; 62h, 128...255rpm and so on. There are 104 bytes in total, and so the engine can deliver power over a range of 13312rpm. The curve works as expected: raising a byte increases linearly acceleration given by the engine at a given rpm. A more peaky torque curve means a narrower range of useful engine speeds - and thus, the driver will have to shift more often.

Idle rpm torque

Data type: Byte

Address: 60h

This may be thought as a special point in the torque curve. It overrides a section of the curve at low rpms, in order to better represent the car launch from a standstill. The affected range is 0...2559rpm (the first 20 bytes of the curve) for the 1st gear, and 0...value of idle rpm (described further down the article) for 2nd gear and above.

Number of gears

Data type: Byte

Address: 26h

Self-explanatory. Acceptable values range from 1 to 6. If you plan to add a 6th gear to a car, remember to set all other gearing parameters described further on.

Downshift rpm

Data type: Integer

Address: 2Eh/2Fh

This is the downshift rpm point used by the automatic transmission. For optimal performance, it should match the rpm position of the torque curve's peak. Observation for all rpm parameters: the parameter values gives the actual number of rpm directly, so it does not make much sense to highlight a "main" adjustment byte in this case.

Upshift rpm

Data type: Integer

Address: 30h/31h

This is the upshift rpm point used by the automatic transmission. For optimal performance, it should match the rpm position of the power curve's peak - remember that, at any given rpm, power = torque * rpm; you may estimate a power curve in arbitrary units from the torque curve that way.

Maximum rpm

Data type: Integer

Address: 32h/33h

This parameter is the maximum rpm (the "redline") of the engine. Whenever the engine goes beyond this value, the rpm value will be reduced at the next time step (1/20th of a second) so that it fits again within the limit (such behaviour explains why the rev meter oscillates when the maximum rpm is reached). Naturally, this value should be adjusted whenever the torque curve is extended to higher rpms. A maybe less obvious fact is that, as there is no other limitation to the maximum rpm, this parameter can be set to an arbitrary high value - well beyond the end of the torque curve or even the maximum size of the torque curve if you wish, and all engine speeds (and thus car speeds) made available can be reached by jumping, even if there is no torque available on the rpm range. As a very important consequence, the maximum rpm defines, together with the gear ratios, the overall top speed of the car.

Idle rpm

Data type: Integer

Address: 2Ch/2Dh

The so-called "idle rpm" modulates the engine behaviour at low rpms. The main function of the parameter is to define up to which rpm value the "idle rpm torque" will be used instead of the regular torque curve for the second gear and above. In addition, the idle rpm sets the "sensory" indicators of the engine speed (rev meter position and engine sound pitch) to a fixed value from zero rpm to its value (since car speed and engine speed are always coupled, the actual rpm value is not fixed, however). If this value is set higher than the maximum rpm, the car will be unable to move. The values can be made equal, though - that is an useful trick to make a constant-torque engine over an arbitrary range of engine speeds if you don't mind having an useless rev meter and an annoying constant high-pitch engine sound buzzing.


Gear ratios

Data type: Unsigned integers

Address: 36h/37h...40h/41h (6 integers)

These parameters set the gear ratios of the car, and are therefore very important ones. 36/37h sets 1st gear, 38h/39h the second one, and so on. The gear ratios are overall values, representing the effects both the gearbox and the final drive gears as well as those of the wheel radius. As it could be expected, a higher value means a shorter ratio, and thus higher acceleration but less final car speed in a certain gear (at any rpm the torque delivered to the wheels is proportional to gear ratio, but wheel speed is inversely proportional). The exact interpretation of the value of is straightforward:

car_speed_mph = 256*engine_speed_rpm/gear_ratio  

This is by far the most useful equation to know when setting the parameters of a car, as it allows to predict car speeds in downshift/upshift points and real top speeds for each gear as well as finding the torque on each. A realistic car needs of course to have decreasing gear ratios, and for often desirable smoother engine operation a near-exponential decrease would be adequate.

Physics parameters

Car mass

Data type: Integer

Address: 28h/29h

This parameter had been variously described over the years as "inverse power amplification" (Mark Nailwood in Car Blaster) or "aerodynamic resistance" (Juha Liukkonen / Lukas Loehrer). Were it an aerodynamic coefficient effect, however, it would affect car more strongly at high speeds. Raising the parameter causes a decrease in acceleration directly proportional to the increment, all gears being equally affected. Therefore, it is best understood as being the car mass. Clearly, it has crucial importance to the car performance. The original Stunts cars have masses ranging from 15 to 55 (in decimal); the second byte defaults to zero and increasing it raises the mass way too fast, so it is usually disregarded. Another very important fact about mass - almost as important as the regular physical effect - is that its value sets the kind of Power Gear or Anti-Power Gear, if any, that the car will have (a complete explanation will be provided soon elsewhere in the Wiki; in the meantime check this forum post).

Braking effectiveness

Data type: Integer

Address: 2Ah/2Bh

As the name says, those addresses tell how powerful the car brakes will be. The effect of the brakes is proportional to the value - any apparent slight deviations from the prediction are in fact effects of aerodynamic resistance. Typical values are close to 0100h (=256), except for racing cars, which may have significantly better brakes. Setting the parameter to 0000h will turn them off completely, and thus the car will only be stopped by aero drag and, eventually, grass slowdown. Other parameters, such as mass or grip, have no effect on braking.

Aerodynamic resistance

Data type: Integer

Address: 5Eh /5Fh

This elusive parameter controls aerodynamic resistance encountered by the car when accelerating down a straight. Aerodynamic drag force increases quadratically with speed (that is, proportional to the square of) up to the point the engine can't produce enough torque to overcome it and the car reaches its top speed. Therefore, increasing aerodynamic resistance will lower the car top speed in a flat straight line (that is, no jumps or Power Gear), as well as significantly reduce acceleration at high speeds. The parameter value is directly proportional to the drag force. It can be verified that for a given set of values for gear ratio, torque and aero coefficient, the maximum possible speed value will be given by:

max_speed_mph = sqrt(2*torque*gear_ratio/aero_resistance)

This relation allows to predict the flat track top speed of a car.

Aero drag also determines how fast the car will lose speed when the accelerator is not being held. It should, additionally, make the car slow down whenever it reached speeds higher than the flat-track top speed (when landing from a jump, for instance). Due to the same bug which originates powergear, however, this effect is not observed for any of the original Stunts cars (only those with multiple of 2 mass values work "properly"). This fact has very important consequences for the driving techniques of Stunts cars. Finally, usual values for the aero coefficient are similar in magnitude to those of mass, ranging from 20 to 52 for the original cars.

Grip

Data type: Integer

Address: CAh/CBh

This is the primary handling parameter. Higher values make it possible to take corners at higher speeds without skidding, and thus raise cornering speeds as well as lower the risk of loss of control (at the rather small cost of making controlled sliding harder, which sometimes can be an inconvenience in competition racing). A general idea of the magnitude of the parameter may be gained by attempting to drive snake lines on an asphalt track without skidding. With grip at 0100h, the car starts to skid at ~70mph. Raising to 0200h allows one to swerve without skidding almost up to 150mph. The default cars have values ranging from slightly lower than 0100h to slightly higher than 0200h.

Surface grip modifiers

Data type: Integers

Address: DCh/DDh...E2h/E3h (4 integers)

These values are responsible for modifying the car grip according to the kind of surface it is on. The four integer values correspond to the four kinds of surface of Stunts - asphalt, dirt, ice and grass, in that order. Most cars have these set to 0100h, 0C00h, 0400h and 0800h, and thus asphalt grip = (4/3)*dirt grip = 4*ice grip = 2*grass grip. LM-002, as an off-road car, is a notable exception.

Sliding oversteer and air-sliding

Data type: Integer

Address: DAh/DBh

This parameter is set to zero on all original cars. Raising it from the default value has two related effects. First, it will make the car rotate faster as it slides, roughly as if the grip was raised. The other effect is making the "air slides" (the mid-air spinning of car gone airborne) more pronounced - even if the car was not sliding before leaving the ground. Setting it at a too high value will make the car extremely sensitive to direction changes when it leaves the ground, and thus make it largely undriveable.

Car dimensions

Data type: Triplet of integers

Address: (F8h...FDh)...(10Ah...10Fh) (4 triplets)

These values set the width and length of the car, which are used mostly everywhere - collision detection for track objects, reorientation of the car when reaching a ramp or any kind of different surface, verification of whether the car is fully/partly on grass, etc. The size data is stored as a set of four point coordinates (thus, four triplets). Each point is a vertex of a four-sided polygon which represents the car. The first triplet corresponds to the front/left vertex; the other three stand for the remaining vertexes, ordered in clockwise order. As usual, the first value of the triplet is the x (left/right) coordinate, and the third one the z (back/front) one. The second value, which would seem to work as y (vertical) coordinate, has no effect over the car behaviour, and is always set to zero. The coordinate values are taken relative to the middle of the car, and both the sum of x coordinates and the sum of y coordinates must be zero - not following this recommendation will result in bugs such as the car moving forward or rotating on its own. Most reasonable cars will be a rectangle symmetrical about the centre of the car, and thus the values in the four triplets will be:

(-half_width, 0, +half_length; -half_width, 0, +half_length; -half_width, 0, +half_length; -half_width, 0, +half_length) 

Taking the original cars as reference, the length and width values usually do not match the full length of the 3D shape (car1 resource in ST*.3SH); the dimensions being often closer to wheel-to-wheel distances (as becomes clear when crashing a car at some obstacle - for most cars the actual crash only happens when the front wheels hit the obstacle). Based on this fact, the ratio between the physical coordinates and the 3D shape coordinates may be estimated as being 32:1.

Influence of length on handling

The car length, as defined by the z coordinates of the vertexes, has major effects over car behaviour. Shortening a car will make it change direction faster, as if the moment of inertia had been reduced. As a consequence, shorter cars will:

  • Have more nimble steering, a fact which not only makes them easier to drive but also allows for higher cornering speeds at the same grip levels - since less steering effort will be needed to turn the car, the risk of skidding will be significantly reduced.
  • Land at shorter distances from jumps, as the car will be pointing down earlier on the flight.
  • Be more sensitive to surface changes, and generally have more twitchy behaviour. A key consequence of that is causing effects such as magic carpets more likely.

The unique handling characteristics of Audi and Lancia are a consequence of their short length, which gives them much better handling than other slow cars and makes them more prone to random bugs.

Dimensions for car-car collisions

Data type: Integer

Address: EEh/EFh, F0h/F1h and F2h/F3h

These three integers set alternate half-width, height and half-length values for the car which are only used for the detection of car-car collisions. Unlike the main set of dimensions, these correspond roughly to the full length and width of the car as given by the car1 3D shape, and the units are the same as the ones on car1. If values are all set to zero, it becomes possible to drive straight through the opponent car, like in Trackmania for instance. Unfortunately, the AI won`t realize that and will still swerve to avoid your car even if it is not necessary to do so.

Dashboard controls

The internal coordinate system for Lancia gearbox (image upscaled 2:1)

In addition to physical data, car*.res parameters are responsible for controlling the displacement of mobile elements of the dashboard, that is, bitmaps from stdb*.pvs, speedometer and tachometer needles. Those parameters, alongside with a few related ones, are described below. Positions of moving dashboard elements (such as the shifting knob) are defined using a set of internal coordinates relative to some fixed position bitmap in stda*.pvs. According to those, the (0,0) point corresponds to the top left pixel of the reference bitmap; thus horizontal coordinates raises when moving rightwards and vertical coordinates raise when moving downwards. An illustration of this scheme is presented on the image beside for the 48x52 pixels bitmap of Lancia's gearbox - the essentials presented apply to other instruments as well. Some of the discussions on this subsection refer to the structure of bitmap resource files (stda* and stdb*). In case of doubts about such issues, check the Car files and Resource file format articles.

Shifting knob positions

Data type: Pairs of integers

Address: (46h/47h,48h/49h)...(5Ah/5Bh,5Ch/5Dh) (6 pairs)

These parameters control where the knob will appear at each gear. The first integer of the pair sets the x coordinate, and the second one, the y coordinate. The reference frame for knob internal coordinates is the gbox bitmap at the stda* file (as the example image illustrates). When editing these values (as well as the centre position to be explained below) it is important to be realize that the distance between two gear positions and the number of direction changes while moving from one to another affects the time needed to engage the gear. Such variations can have very noticeable effects on straight-line acceleration. Therefore, car tuners should be wary when modifying knob positions of an existing car so as to not alter the car performance and thus compromise pre-existing replays.

Shift pattern centre line

Data type: Integer

Address: 44h/45h

This is a complementary value to the shifting knob positions. It sets at which y coordinate value the knob will switch from one column to another on the shift pattern; and thus it will most likely it is to be set halfway between the upper and lower rows of gear positions. The coordinate frame is the same of the knob positions.

Apparent car height

Data type: Integer

Address: F6h/F7h

This sets the apparent height from the ground on the inside (F1) view. The units are the same than those of the car1 3D shape. The parameter has no effect on the physical characteristics of the car, so you do not need to worry about crashing at roofs if you set it way too high...

Steering wheel dot movement

Data type: Pairs of Bytes

Address: (110h,111h)...(14Ch,14Dh) (1+33 pairs)

These pairs of bytes control the position of the steering wheel dot over its full range of movement. The first pair is the dot position with the wheel centered. As for the other 33 pairs, each one controls the dot position for a certain amount of steering applied both when turning to the right (actual coordinate value) and to the left (horizontal coordinate is mirrored relative to the central dot). This also means that displacing the center point without adjusting the other points will separate the right side points from the left side ones... Anyway, the reference frame for the internal coordinates is stda* whl2 bitmap.

Speedometer needle movement

Data type: Pairs of Bytes, plus one pair of integers and a single byte

Address: (14Eh/14Fh,150h/151h), 152h, (154h/155h)...(222h,223h) (1 pair of integers, 1 integer and 104 pairs of bytes)

Like the other meters, the movement is controlled by pairs of values which set the position of individual points. In this case, the coordinate frame are the coordinates of stda* ins2 bitmap. The lone pair of integers starting at 14Eh defines the centre point for the needle. Byte 152h sets the maximum number of needle positions to be displayed. Finally, the position of the needle tip for each speed is controlled by the consecutive pairs from 154h on. Each pair of bytes covers an interval of 2.5 mph, starting from zero. Finally, in case one needs to get rid of the needle altogether (like for IMSA dashboards), the easiest solution is to set 14Eh and 150h to FFh and 154h - 223h to zero - simply setting 152h to zero won't work as expected.

Digital speedometer

Data type: Pairs of bytes

Address: (154h,155h), (156h,157h) and (158h,159h)

This is a funny one. To have a digital speedometer first one needs to have a STDB* file containing the dig0...dig9 bitmaps used for the digits (the classic solution is to clone the Corvette STDB*). Additionally, a dashboard with proper contrast must be chosen (even if the game can switch number colours automatically depending on the background, some dashboards will still look awful). Then, byte 150h must be set to 0h. That will trigger the analog needle to disappear and be replaced by the set of digits, whose coordinates are controlled in the usual fashion by the three pairs, which stand for the first, second and third digits from left to right respectively. As for the coordinates' reference frame, it is stda* ins2 bitmap, just as for the analog speedometer.

Rev meter needle movement

Data type: Pairs of bytes, plus one pair of integers and a single byte

Address: (224h/225h,226h/227h), 228h, (22Ah/22Bh)...(32Bh,32Ch) (1 pair of integers, 1 integer and 130 pairs of bytes)

The rev meter is completely analogous to the speedometer. The pair of integers at 224h sets the centre point, 228h sets the number of needle positions to be displayed and the pairs from 22Ah to 32Dh define the tip positions, adding up to 130 available positions. Every pair of bytes covers 128rpm, starting from zero. Other details are just the same as those discussed for the speedometer. Again, the reference frame is provided by stda* ins2 bitmap.

Text data

Car information

Data type: Zero-terminated character strings

Address: 32Eh - ???h

Quoting Lukas Loehrer directly:

Car information displayed on the 'choose your car' screen. Use ] (5Dh) for linebreaks. The end of this block can not be given by an absolute address. Look for a byte with the value 00h. It is followed by a 4 byte long car id which is again terminated by a 00h.

The "4 byte long car id" mentioned above is the abbreviation displayed alongside opponent name in the scoreboard. Car information is most conveniently edited via Car Blaster, which has a specific WYSIWYG interface for dealing with it.

Scoreboard car name

Data type: Zero-terminated character string

Address: ???h - EOF

The final bytes of the file (after the terminating 00h mentioned above) make up the scoreboard designation of the car. It can be edited via Car Blaster like the other text pieces as well.

Miscellaneous

File header

Address: 00h - 25h

The initial bytes of CAR*.RES files consist of a file header, structured just like the ones found in uncompressed graphic files and elsewhere. Essentially, it stores file length, text IDs for different sections of the file and the associated byte offsets. Since that data is actually used by the engine to parse the car data, there is no reason to modify it unless one is hand-editing text data for the car and intends to modify string length - and even in that case, using Car Blaster and allowing it to perform any necessary adjustment is the recommended option.

Unknown parameters

Here is a list of the values on CAR*.RES which have unknown function. After somewhat extensive testing, they displayed no visible effect on the behaviour of the car in saved replays. Most of them are equal for all cars.

  • 027h - single byte next to the number of gears, probably just a padding zero.
  • 034h/035h - strategically located next to the gear ratios. Unused space for a never-implemented reverse gear?
  • 0C9h - single byte between the torque curve and the grip parameter, probably just a padding zero.
  • 0CCh/0CDh - set to 00EEh for all cars.
  • 0CEh/0CFh - set to 00B8h for all cars.
  • 0D0h/0D1h - set to zero for all cars.
  • 0D2h/0D3h, 0D4h/0D5h, 0D6h/0D7h, 0D8h/0D9h - these form a suspicious-looking series with values 0020h, 0010h, 00C0h and 0008h, equal for all cars.
  • 0E4h/0E5h - set to zero for all cars.
  • 0E6h/0E7h, 0E8h/0E9h, 0EAh/0EBh, 0ECh/0EDh - another series of values, this time 0020h, 00C0h, 0080h and 0040h. The resemblance to the default values of the surface grip modifiers is uncanny.
  • 0F4h/0F5h - located just after the car-car bounding box. The value seems to grow with the half-length defined on the bounding box.

See Also