RSX / RCX & REX Files {Scripting}

Haven't written the code yet, but I'm planning to.

I'll probably start simple, then work my way up to tables and crv files.

Simplest string to read:
Code:
 0  5 10 15 20 23
This would go into an array with basically the points (0,0), (0.2, 5), (0.4, 10), (0.6, 15), (0.8, 20), (1.0, 23)
Then I'll write a lookup function, lookup(array data, float value) that uses the same array structure as above, where value is within [0, 1] and returns the lookup value, linearly interpolated.
Once that works to my satisfaction, I can implement the multi-line file stuff into another function, that outputs a similarly formatted array.
The lookup function for gear shifting would probably be something like lookupshift(array data, float throttle, float currentGear, float toGear)
This would return a speed. So the loop in the script itself would just be something like
Code:
float $shiftarray = readShiftTable("../../shift.tsv")
float $velocity = 0
... // other variables
while 1
{
  $velocity = get $car velocity
  $gear = get $car gear
  if $velocity > lookupShift($shiftarray, $throttle, $gear, $gear+1)
  {
    set $car gear ($gear + 1)
  }
  else if $velocity < lookupShift($shiftarray, $throttle, $gear, $gear-1)
  {
    set $car gear ($gear - 1)
  }
  // then include torque converter code here, other transmission function, etc.
  interrupt
}
Nice and easy to use for any car, just need to write out the table.

If you can see an easier way to make the functions work, or have a request for another type of lookup, now's the time to tell me :p Still need to work out the exact format of the stored shift tables, and the more I know what it'll be used for the better I can manage.

The most basic table would have 2 speeds per gear change (no throttle shift-up, full throttle shift-up) which you could approximate pretty quickly. Just make sure shift-up speed is higher than shift-down speed at the same throttle in the next gear, cause then it'll pop back and forth.
 
It is better not to pass arrays as function parameter, because it copys the entire array over ... i'm thinking about passing every parameter by reference instead
 
Hmm, so a better option would be to write a function that algorithmically figures out which array indices it needs (eg. #7 and #8), pluck those out, and apply the rest of the algorithm in a second function that only takes those parameters input?

Like going back to the 0, 0.2, 0.4, 0.6, 0.8, 1.0 interpolation example, where spacing is even, the function to find next/previous values is simple
Code:
lower($x,$len) 
{ 
  $r = floor($x*$len)
  if $r < 0
  {
    return 0
  }
  else
  {
    return $r
  }
}
upper($x,$len) 
{
  $r = ceil($x*$len)
  if $r > ($len-1)
  {
    return ($len - 1)
  }
  else
  {
    return $r
  }
}
linearinterpolate($x, $lower, $upper, $lval, $uval)
{
   float $weight = ($x-$lower)/($upper-$lower) 
   return ($weight*$uval + (1-$weight)*$lval)
}

Then call the functions, with array $array,
Code:
$l = lower($x,length($array))
$u = upper($x,length($array))
$value = linearinterpolate($x, $l, $u, $array[$l], $array[$u])
This only copies 2 values in the array instead of all of them.

Obviously with lower/upper functions as they are here, it's just as easy to write $l = floor($x * $len), but once they get more complicated, or if bounds checking is important (eg. if the array contains 6 different gear changes, and you want to look up a particular gear) then it's better to be using a consistent function for debugging.


Or I could just wait for arrays to be passed as references, and in the meantime have it run a little slower :p
 
Just bumping this to see if there are any more ideas out there. Love this thread...but it's been so quiet lately.
Stereo, did you end up writing out that script or are you waiting for the (I would assume) next version which will have referenced arrays?
 
Yeah, I decided to wait for it. My interest in Racer's kinda up and down, right now I'm mostly just catching up with the forums due to how my free time is structured.
 
Yeah, I decided to wait for it. My interest in Racer's kinda up and down, right now I'm mostly just catching up with the forums due to how my free time is structured.

By the way, your code works well for pop-up headlights too. :)

I would show you but apparently vbullitin has decided that actually beta testing their software is too much trouble. (posting images is broken) and before anyone suggests it I know I could post them elsewhere and link but I would rather wait for a fix.

Alex Forbin
 
KS95 said:
[OT]

I don't think there's going to be a fix, I think that RD no longer hosts images themselves because of the space/bandwith they must use. Sites like tinypic can be quite fast and easy :)

I was basing that post on this thread, it appears to be a bug in the forum software...
http://www.racedepartment.com/announcements-feedback/57937-posting-images.html

If the storage is an issue they could simply limit the size of the images to say 150k or so, but to cut out the ability to post ANY images would simply limit the functionality of the forum. I'm hoping that isn't the case.

Alex Forbin
 
[Off Topic]

How on earth did I miss that thread, I was looking in that section earlier today, lol! In which case you could just follow Bram's suggestion of using bbcode - but still the images would have to be hosted on a separate image host :)

I'll delete my previous message, it's just spam now! :tongue:
 
Here's my script to toggle open/shut the trunk on the Aronde. I put it in cars\simcaaronde90a\scripts\paint\trunk.rsx.
Code:
[color=green]func float rotateMovable(rcarmodel $targetObject, float $targetState, float $angle, float $posx, float $posy, float $posz, float $rotMaskx, float $rotMasky, float $rotMaskz, float $incRate, float $decRate, float $minAngle, float $maxAngle)
{
  // targetObject: the model to be moved.
  // targetState: usually 0 (closed) to 1 (open), where 0 represents the smaller angle.
  // angle: current angle of the object.  Should be a persistent variable.  New value will be returned.
  // posx, posy, posz: just move the object
  // rotMaskx,y,z: determine which axes to use by component-wise mult.  eg (0,1,0) * (x,x,x) = (0,x,0)
  // incRate: angular change (per ms) in radians when opening.
  // decRate: angular change (per ms) in radians when closing. note: both should be positive.
  // minAngle: min value for the angle
  // maxAngle: max value for the angle

  // return float: new angle
  
  // figure out where we want to go
  float $targetAngle = $targetState*($maxAngle-$minAngle) + $minAngle
  if $targetAngle > $angle
  {
    $angle = $angle + $incRate * interval
  }
  if $targetAngle < $angle
  {
    $angle = $angle - $decRate * interval
  }
  // now make sure it's within the valid range
  if $angle < $minAngle
  {
    $angle = $minAngle
  }
  if $angle > $maxAngle
  {
    $angle = $maxAngle
  }
  // display the object correctly
  set $targetObject position float[3]{$posx,$posy,$posz}
  set $targetObject rotation float[3]{$angle*$rotMaskx,$angle*$rotMasky,$angle*$rotMaskz}
  return $angle
}[/color]

[color=orange]rcar $car = get scriptowner car
rcar $localcar = get local car
rcarmodel $trunk = get generic model 8 of $car
set $trunk scriptcontrolled 1[/color]
float $trunkpos
int $trunkopen
int $keydown = 0
while 1
{
[color=blue]   if $car == $localcar
  { 
    if is key 84 pressed
    {
      if $keydown == 0 // toggle activation
      {
        $trunkopen = 1 - $trunkopen
        $keydown = 1
      }
    }
    else
    {
      $keydown = 0
    }
  }[/color]
 // paint $trunkpos at float[2]{30,10}
 // paint $trunkopen at float[2]{10,10}
[color=red]  $trunkpos = rotateMovable($trunk, $trunkopen, $trunkpos, 0, 0.35, -1.31, 0.0, 1.0, 0.0, 0.003, 0.003, 0.0, 1.2) [/color]
  interrupt
}
green: rotation function. 3 variables and a bunch of constants that determine the behaviour. I couldn't figure out how to initialize float[3] variables, it just gave me an error on "float[3] $x": variable name may not begin with [. So basically it's a few groups of values - (posx, posy, posz), (rotx, roty, rotz), (incRate, decRate), (min,max). The first is the position to put the object - second is the axes to rotate around, third is the speed of increasing + decreasing angles, fourth is the min/max angle limits.
orange: grab the desired movable. Since it's in the car folder it's loaded with the scriptowner being the car's driver, then I know the trunk is generic model #8 from car.ini, so I add that variable, and set it to script controlled.
blue: toggle code. In this case it checks key 84, 'T', and technically is a leading edge switch - whenever T goes from unpressed to pressed, it toggles one way and the other. It also checks whether the script owner is also the player's car, so that it'll only affect the current vehicle, since key presses are sent to all scripts
red: Calling the rotation function. $trunk is the object, $trunkopen is the toggle value, $trunkpos is the current angle. (0, 0.35, -1.31) is the point it rotates around - when exporting, that's (0,0,0) on the object. (0.0, 1.0, 0.0) tells it to rotate around the second axis, which is pitch, (0.003, 0.003) is the angular change per millisecond, and (0.0, 1.2) are the limits of angles it can present.
black: misc other code structure to glue it all together.

To adapt it to something like a speed activated spoiler, the blue section would just have to grab the car's speed/braking, check for a threshold, and toggle it to 1 (for up) when desired braking is above whatever value, possibly with a 1-2 second timer before it can be toggled again. Since this operates separately from the raising/lowering rates it's gonna work consistently.


If you want it to follow some function other than constant speed opening/closing, you'd have to integrate that and replace $incRate * interval, which is the integral of $incRate from t_1 to t_2 where (t2-t1) = interval, with whatever other function. Nothing too challenging except figuring out how to express it in terms of dx and the current angle. I can explain further if someone actually wants to do this.
 
Thanks for the script Stereo...

I feel there is lots of power in these scripts to do some amazing stuff... I want to, somehow, make my Z4 soft-top fold up/down nicely... not sure how yet, but it'd be nice... scripts like this at least give me a starting point :D

Cheers

Dave
 
^ How do games like TDU2 do it? They look really good in it :)

No idea but I guess I'll have to learn :D

First thing is modelling a nice roof, and modelling it in a way that it can fold elegantly like the real one too!

Been having a play this weekend but even getting the shape right is hard work. I keep looking at the Fiat Barchetta on these forums and how good the roof looks, and won't be happy till mine looks like that!


I'll be sure to post up my process if I get it working any time soon :D



Cheers

Dave
 
Order of operations

I was trying to rotate a body part 60 degrees. So I had to calculate rads based on degrees. Easy, I said to myself, so I did:
Code:
float $pi = acos(-1)
float $rotation = 60.0

float $rads = $rotation / 180.0 * $pi
The result was the bonnet barely moved a single degree. I "painted" all the variables, did the calculation on a pocket calculator, nothing. As a temporary solution, I decided to multiply the result by a constant, just so I can see my bonnet rotating. It only made it worse! Instead of 10x larger, my rads where 10x smaller. Then it clicked - multiplications are done first, before divisions.
So, even though mathematically a/b*c=a*c/b, in Racer scripts you have to group all factors together or use parenthesis:
Code:
float $rads = ($rotation / 180.0) * $pi
 
Stereo:
Brake balace on the simca gives a Qlog error and there are a couple of other ones in the car.shd file. I know it's a work in process and just thought I'd mention it.
 
That new brake balance thing is annoying. I'm not sure exactly what we are meant to do with it...

From what I have done I've doubled the brake values at each wheel, but then put a balance value of 0.5 on each wheel...

The brake bias values all need to add up to 2 basically...

Hmmmm

Dave
 
Wrote a script for Carlswood_NT to let you do brake tests fairly easily on the straight track.

5oZZB.jpg

Drive onto the straight line, speed up to start speed, press 'b' to start, and the script gives you 0% throttle 100% brakes until you come to a stop. Also apparently kills the engine cause the clutch doesn't engage when you mess with the controls like this.

Currently it's ignoring ABS, so it'll always do a skid stop. I'm not sure if there's a way to have script controlled brakes include the ABS built in.

"Actual" numbers for the RX-7 should be 123 ft. 60-0, 220 ft. 80-0 mph. Whereas within the game it's getting 129 feet (above) and 216 feet (not pictured). Probably a sign the tires are too grippy, since Racer's doing a skid-stop.

rTRTM.jpg

Since it came up in that other thread.

The script's in two parts, and the /physics component doesn't load with the track, so you need to 'reload scripts'.


Stick this in data/tracks/carslwood_nt/scripts/paint/brake_test.rsx
Code:
// for the purpose of testing the active car's brakes.  On Carlswood.
// rectangle of influence: 0 < x < 12, -1200 < z < -180 - any y.

rcar $car = get local car
float $pos[3] = get $car pos
float $vel[3] = get $car velocity
float $startpos[3] = get $car pos
float $startvel[3] = get $car velocity
float $rpos[3] = get $car pos
shared int $testactive = 0
int $keydown = 0
float $displayvel = 0.0
float $altdisplayvel = 0.0
float $displaydist = 0.0
float $unitconversion = 3600.0/1000.0 // from m/s to km/h = *3600s/h*(1/1000)km/m
string $speedunit = "km/h"

while 1
{
  $pos = get $car pos
  $vel = get $car velocity
  if $pos[0] > 1.0
  {
    if $pos[0] < 14.0
    {
      if $testactive == 0
      {
       paint "Braking test available: Press 'b' to begin." at float[2]{300,300}
       if is key 66 pressed
       {
        if $keydown == 0
        {
         $testactive = 1
         $startpos = $pos
         $startvel = $vel
         $altdisplayvel = (get $car tachovelocity) * $unitconversion
         $displayvel = $altdisplayvel
        }
       }
       else
       {
         $keydown = 0
       }
      } 
      else if $testactive == 1
      { 
        paint "Braking test in progress." at float[2]{300,300}
        $rpos = $pos - $startpos
        $displaydist = sqrt ((pow $rpos[0] to 2) + (pow $rpos[1] to 2) + (pow $rpos[2] to 2))
        string $disp = "Distance traveled " + $displaydist
        $disp = $disp + " meters."
        paint $disp at float[2]{300,280}
        float $curvel = (pow $vel[0] to 2) + (pow $vel[1] to 2) + (pow $vel[2] to 2)
        if $curvel < 0.01
        {
          // move to the next part
          $testactive = 2
          set $car gear 2
        }
      }
      else if $testactive == 2
      {
        paint "Braking test complete.  Press 'b' to reset." at float[2]{300,300}
        string $disp = "Start speed " 
        string $dispval = $displayvel
        $dispval = " " + $dispval
        $dispval = substring $dispval from 1 to 4
        $disp = $disp + $dispval
        $disp = $disp + $speedunit + ".  Distance traveled "
        $dispval = $displaydist
        $dispval = " " + $dispval
        $dispval = substring $dispval from 1 to 4
        $disp = $disp + $dispval
        $disp = $disp + " metres. ("
        $dispval = (3.28*$displaydist)
        $dispval = " " + $dispval
        $dispval = substring $dispval from 1 to 4
        $disp = $disp + $dispval
        $disp = $disp + " feet)"
        paint $disp at float[2]{300, 280}
        if is key 66 pressed
        {
          $testactive = 0
          $displayvel = 0.0
          $altdisplayvel = 0.0
          $displaydist = 0.0
          $keydown = 1
        }
      }
    }
  }


  
  interrupt
}
Format conversion (from float to string) is not great atm thus all the $disp/$dispvals in the last bit.

And, in data/tracks/carlswood_nt/scripts/physics/brake_test_autobrake.rsx
Code:
rcar $car = get local car
shared int $testactive
while 1
{
  if $testactive == 1
  {
    set $car throttle 0
    set $car brake 1
  }
  interrupt
}
As I said before you'll need to 'reload scripts' on the console to get this one running.
 

Latest News

How long have you been simracing

  • < 1 year

    Votes: 352 15.6%
  • < 2 years

    Votes: 247 10.9%
  • < 3 years

    Votes: 243 10.7%
  • < 4 years

    Votes: 177 7.8%
  • < 5 years

    Votes: 301 13.3%
  • < 10 years

    Votes: 259 11.5%
  • < 15 years

    Votes: 166 7.3%
  • < 20 years

    Votes: 126 5.6%
  • < 25 years

    Votes: 99 4.4%
  • Ok, I am a dinosaur

    Votes: 291 12.9%
Back
Top