Scripting questions

The forum is in reduced operation. The Addon and Support forums remain open.
Please note that OMSI is no longer under development. Some of the developers are now working on a new simulator. Further information concerning the LOTUS-Simulator can be found here.
A community-lead successor to the OMSI forum will be linked here as soon as it is founded and ready.
  • Not to pollute my other question topic, I decided to ask some script-related questions here.


    I have a rev counter (I believe it is called "drehzahlwinkel" in German) whose needle I want to go up to 2300-2400 rot/min. However, when I rev the engine at maximum, it only goes to ~1600 rot/min. Now, I know (sort of...) about the cockpit_constfile and the [newcurve] entries, but in the case of rev counters, these seem counter-intuitive (no pun intended :) ). Instead of some function relating the rpm-s and the needle angle with respect to rest position, I have some pairs that I don't grasp the meaning of (they don't look either like rpm values or needle angle).

    Another issue is the fuel level gauge. There is no entry for it in the constfile, and I want to reduce the area "swept" by the needle (this gauge is different from the usual ones found in OMSI buses, and the ticks for "full", "half-empty" and "empty" levels are a bit closer to each other).


    Also, I would appreciate if anyone lets me know what "maxspeed" and "delay" tags in animations mean.

  • Hello,


    It's hard to answer those questions without having concrete code to look at. Are you using the same scripts as the standard buses (MAN SD/NL/NG)? If not, would you mind attaching/uploading, or at least pointing out which scripts and accompanying const-files you're using for all the involved components (cockpit, engine, gearbox/transmission (a.k.a. "Antrieb" in German))? The relevant model.cfg entries might be helpful as well.


    With regards to the maxspeed and delay animation attributes, I am unfortunately unaware of a normative documentation reference on them. Empirically I would like to believe that they are intended for providing convenient animation actualization inertia, in those cases where the script only specifies the target/final position/angle of the animation, without bothering to implement intermediate update logic. This, for example, tends to be the case with analogue thermometers, or rev counters, or sometimes even plain dashboard switches, where the script performs the measurement or other update action instantly, but we would still like the instrument or controller to be able to exhibit some actualization inertia, as it would in the real world. On the other hand, these attributes are e.g. usually not employed with doors, whose animations are more complex, with variable acceleration and blocking conditions, and thus necessitating a 100% programmatic implementation. As for the concrete meaning behind maxspeed and delay, my arbitrary guess is that the former translates to a maximum actualization rate (% change per unit of time, perhaps seconds or millis, I have honestly no idea), whereas the latter translates to the time necessary for the effective actualization rate to reach that maximum. OMSI might then internally create some sort of curve, expressing the effective actualization rate as a function of maxspeed and delay. Again, this is all just speculation, and may be totally wrong. Because of this ambiguity, I personally prefer to implement animations purely programmatically, even if it requires a bit more effort; then I at least know exactly why/how the animation works, and what to troubleshoot when it doesn't.

  • Thank you! For some so-called speculations, they do have logic.


    My engine and antrieb scripts and constfiles are the same as the M&R NL202 ones. As of the cockpit.osc, it started off as a basic NL202 script as well, but I made various modifications according to my bus' real-life specifications. I attach some extracts from it:



    ...as I do with the constfile. It's a bit weird that, in the constfile, the rev counter is named "tacholinie", whereas in the .osc, "tachowinkel" is the name of the speedometer needle. I got tricked a few times in the beginning.




    I forgot something: can I make a [light_enh_2] source visible by a script? To be more precise, in real life, some examples of the same bus model had a type of position light, while other ones had a different type. It all depends on the fleet number of said bus.

  • Hello,


    The cockpit_tacholinie curve is responsible of the speedometer, it takes the velocity as input, see in cockpit.osc :

    Code
    1. {macro:tacho_frame}
    2. (L.L.Velocity) (F.L.cockpit_tacholinie) (S.L.cockpit_tachowinkel)
    3. {end}

    Rev counter is this macro :

    Code
    1. {macro:drehzahlmesser_frame}
    2. (L.L.engine_n) 3000 270 / / (S.L.cockpit_drehzahlwinkel)
    3. {end}

    So the needle should be cockpit_drezahlwinkel. It takes the actual RPM (engine_n) as input, and the division is for the angle of the needle, you can always modify this behavior. There is no rev counter on the original MAN NL but this macro is present.


    For example, I would do something like that. Let's say when the RPM is at 2700, your needle needs to be at 150° and when the RPM is at 0, your needle needs to be at 20°. I would rotate the model of the needle to 20° by default, so the max angle of the needle would be 130° for 2700 RPM.


    If you want to keep it a bit like the original, you could do something like :

    Code
    1. (L.L.engine_n) 130 2700 / * (S.L.cockpit_drehzahlwinkel)

    Or you could optimize it a bit :

    Code
    1. (L.L.engine_n) 0.048 * (S.L.cockpit_drehzahlwinkel)

    Or even in the animation :

    Code
    1. [newanim]
    2. ...
    3. engine_n
    4. 0.048
    5. ...
  • Thanks! Now it's not weird anymore.

    I see that in this line:

    Code
    1. (L.L.engine_n) 2700 130 / * (S.L.cockpit_drehzahlwinkel)

    you put an asterisk instead of a slash. Wouldn't one be the opposite operation of the other?

  • It is possible to do RPM * (130/2700) or RPM / (2700/130), but multiplication is better for performance than division, so I changed it but I made a mistake because I forgot to inverse 130 and 2700. I edited it, it should be :

    Code
    1. (L.L.engine_n) 130 2700 / * (S.L.cockpit_drehzahlwinkel)

    Where :

    2700 = max RPM

    130 = max needle angle

  • I forgot something: can I make a [light_enh_2] source visible by a script? To be more precise, in real life, some examples of the same bus model had a type of position light, while other ones had a different type. It all depends on the fleet number of said bus.

    Yes, you can, but it would only make sense to do so if the lighting effects themselves ought to differ (and not merely the corresponding objects).


    Each [light_enh_2] references a so-called fading variable, valued between 0 (off) and 2 (double intensity). For standstill lights, that variable is typically lights_stand (some sources modeled as independent meshes get to use their own dedicated variable, like lights_edge_front_bulb_[l|r] for the top head position lights -- but let's disregard these for simplicity's sake for the time being).


    In the lighting script, you would then introduce two additional variables, say lights_stand_type_a_active and lights_stand_type_b_active, that derive their state from the base lights_stand variable, under the additional constraint that a certain configuration variable (as discussed in your prior thread) has a certain value; e.g.:

    Code
    1. (L.L.lights_stand_type) 0 =
    2. {if}
    3. (L.L.lights_stand) (S.L.lights_stand_type_a_active)
    4. 0 (S.L.lights_stand_type_b_active)
    5. {else}
    6. 0 (S.L.lights_stand_type_a_active)
    7. (L.L.lights_stand) (S.L.lights_stand_type_b_active)
    8. {endif}

    You would append that fragment right before the closing {end} of the {macro:lights_frame}-block (while not neglecting to also declare lights_stand_type, lights_stand_type_a_active, and lights_stand_type_b_active in a varlist), such that the derived variables always reflect the latest state of the lights_stand variable.


    Next, in your model.cfg, you would have one group of [light_enh_2] entries for the first type of position lights, each of which referencing lights_stand_type_a_active as its fading variable, and another group of [light_enh_2] entries for the second type, each of which referencing lights_stand_type_b_active as its fading variable. And of course the [visible] flag of the corresponding [mesh] entries would reference lights_stand_type accordingly (if equal to 0, then first type visible; if equal to 1, then second type visible).


    Of course, if the two types of lights exhibit different electrical properties (e.g. different minimum voltage below which bulbs/units will go off; or radically different power consumption per unit; or perhaps different mapping between cockpit state and light circuit state), then more complexity will have to be introduced to account for these as well.

  • Unorthodox Paradox: many thanks!


    Florito: as I fiddled with the scripts, I noticed that, for the needle angle kept constant, there is an inverse proportionality between the rpm value written in the cockpit.osc and the actual value shown on the dial. Nothing to scoffle at, but I want to emphasize this for fellows who might find this thread useful.

  • I made some good progress with my project, but I encountered an issue that bothers the hell out of me...

    So I was fiddling with the heating scripts to make this process closer to reality (different from SD/NL buses). Apparently, everything goes well, I can load the bus and drive it almost as usual. I say "almost" because all the switches (kippschalter), handbrake, horn, brake pedal and the column levers are mute. I open up the logfile and there is a surprise in it for me:

    Code
    1. 313 11:57:16 PM - - Error: ''cabinheater_RPM'' ist kein gültiger Integer-Wert: CV.Calculate - I (vehicles\Rocar De Simon\U412-260.bus)
    2. 314 11:57:16 PM - - Information: Menu pos set
    3. 315 11:57:17 PM - - Error: Zugriffsverletzung bei Adresse 007F02C1 in Modul 'Omsi.exe'. Lesen von Adresse 00000004: CMO.UserVehSetSounds
    4. (...)

    ... and so on until I delete the bus or close the game.


    Now, this cabinheater_RPM doesn't appear in any scripts or constfiles (it does appear in cockpit_varlist, but this shouldn't affect anything), but it used to appear in cockpit.osc and heizung.osc, so I tried removing it from all possible instances (although some other buses, including the one whose heating script I used for mine, keep this line and don't have any issue).

    If needed, I will attach some extracts from the relevant script entries.

  • How can I "center" the line number on a vollmatrix, such that it mimicks the behaviour of an Annax matrix?


    Also, is there a way to display an abbreviated destination and the line number on the same side matrix box (unlike some other buses that have separate boxes for the line number and the destination on the right-hand side.


    And door-related: this one's a bit tricky: when I press the stop request button, I have to manually open said door once the station brake is active (which does well for me). I also want some external door buttons for passengers to use, such that when they are pressed, the doors will open automatically once the station brake is activated. These external buttons have a switch on the dashboard that (de)activates them (i.e. when it's off, the buttons won't work at all, so the entire [withbutton] thing in thr script is rendered useless). Regarding this on/off switch, I was thinking to assign a [visible] command to it, so the "off" position will "replace" the functioning buttons with a set of identical but static ones. Is it a good idea, or the passengers will still "recognize" the buttons? As of the automatic door opening caused by these buttons, I have no idea how to script it.