playing with the engine and wagon scripts to enable MU sound & smoke, one side-effect was an EngineScript.lua with improved smoke generation.
specifically, the script now considers loco load (as seen by the prime mover, ammeter reading in effect) into smoke calculations and offers the
possibility of individualised smoke per locomotive.
looking at the script below, you will find the following constants that control smoke generation:
RATE:
this controls the overall smokiness of the exhaust. a low value like 0.01 will produce thick exhaust, something like 0.1 will produce nearly transparent exhaust.
realistic values are around 0.03 - 0.07, default is 0.04. if you set this to zero, the locomotive will spew maximum smoke regardless of conditions.
COL:
this controls the change in smoke color with load. more precisely, smoke produced under high load (high amperage) will be black (or nearly black, see below).
smoke produced under low load conditions will be a lighter color. a value of 0 will always produce dark smoke, 1 less so, 10 will produce light gray smoke darkening
only under highest load conditions. realistic values are around 3 - 6, default is 4. if you set this to zero, the smoke will be black regardless of conditions.
RPMCF and AMPCF:
this controls smoke generation at high engine RPMs and high engine loads respectively. for example, RPMCF = 0.1 and AMPCF = 0.9 will result in a locomotive
that smokes heavily under high load, but little at high engine rpms but low load. conversely AMPCF = 0.1 and RPMCF = 0.9 will produce a loco that will smoke heavily
at high engine rpms but little under load (starting a heavy consist on a hill, for example). the sum of AMPCF + RPMCF should be 1. if it is greater than 1, the exhaust
will create surges and puffs of smoke, like those produced by a hunting engine governor. realistic values are between 0 and 1 each, depending on what you want,
defaults are 0.3 and 0.7 for RPMCF and AMPCF.
BLNSS:
this controls the color of the smoke at low load settings. 1 is neutral gray smoke. less than 1 will create brownish smoke like on a lean-running engine, more than 1
will create bluish smoke like a worn engine that's burning oil. realistic values are between 0.8 and 1.2, 0 and 1 will produce yellow and purple smoke respectively.
IDLERPM, MAXRPM and MAXAMPS:
these control the conditions where maximum smoke is generated. you should set them to something sensible for your loco for best (realistic) results.
PUTTING IT ALL TOGETHER:
let's say you want to simulate a run-down piece of junk, a GP7 perhaps. first you should set RATE to somere around 0.02 for lots of smoke. COL should be in the 2 - 3
range for a nice thick cloud of soot, that is if you don't go after the leaking headgasket look in which case it should be 10 or more to simulate a steam rich exhaust.
RPMCF and AMPCF should both be set high, perhaps 0.5 and 0.7 for lots of smoke when starting and at road speed with those nice misadjusted governor exhaust
puffs. finally you could set BLNSS to 1.3 - 1.4 for a heavy oil drinker or perhaps 0.8 for a lean-runner.
alternatively, if you want to simulate a brand new GEVO, use a RATE of about 0.07, a COL of 5, RPMCF and AMPCF of 0.3 and 0.5 respectively and a BLNSS of 1. this
will produce a locomotive that will smoke little except under the heaviest load conditions.
or better yet, uncomment (remove the two dashes in front) these lines from function Initialise()
- Code: Select all
-uncomment these to randomize smoke generation for each locomotive
--RPMCF = math.random()
--AMPCF = math.random()
--BLNSS = 0.75 + (math.random() * 0.5)
--COL = math.random() * 10
--RATE = math.random() / 10
this will randomize smoke settings for each locomotive so you could have a healthy one and two sick as dogs. by default RPMCF and AMPCF vary between
0 and 1, BLNSS between 0.75 and 1.25, COL between 0 and 10 and RATE between 0.1 and 0.01. you can bias the values by adding a constant to the output
of the pseudorandom number generator (math.random() + 5 = [5..6]) or expand/contract the generation interval by multiplying or dividing with an appropriate
constant (see COL and RATE above).
i suggest creating a consist with 4 or more locos coupled with a buch of loaded coal hoppers on a ramp and using the randomization option described above. this
should give you an idea of the possible configurations.
have fun!
the script:
- Code: Select all
--------------------------------------------------------------------------------------
-- Engine Script for controlling additional engines
-- RailWorks 2: Train Simulator
--------------------------------------------------------------------------------------
--adjust these to something sensible for your loco, defaults for ES44AC
IDLERPM = 350
FULLRPM = 1050
MAXAMPS = 2000
--this is the smoke generation rate, higher means less smoke, towards 0 means maximum smoke
RATE = 0.04
--this controls smoke discoloration at low power settings, 1 means dark black, higher is lighter gray
COL = 4
--this controls smoke generation at high RPMs, 0 means none, 1 means a lot
RPMCF = 0.3
--this controls smoke generation at high load (amperage), meaning as above
AMPCF = 0.7
--this controls the blueness of the smoke, 1.2 is bluish smoke, 0.8 is brownish smoke
BLNSS = 1.0
RPM_ID = 1709
RPMD_ID = 1710
AMPS_ID = 1711
function Initialise ()
-- Turn off "surge" at start.
Call( "Exhaust:SetEmitterActive", 1 )
gPrevRPM = 0
gPrevRPMDelta = 0
gPrevAmps = 0
--uncomment these to randomize smoke generation for each locomotive
RPMCF = math.random()
AMPCF = math.random()
BLNSS = 0.8 + (math.random() * 0.4)
COL = math.random() * 10
RATE = math.random() / 10
Call( "BeginUpdate" )
end
function OnControlValueChange ( name, index, value )
if Call( "*:ControlExists", name, index ) then
Call( "*:SetControlValue", name, index, value );
end
end
function Update ( time )
-- Get rpm values for this vehicle.
rpm = Call( "*:GetControlValue", "RPM", 0 )
rpm_change = Call( "*:GetControlValue", "RPMDelta", 0 )
amps = Call("*:GetControlValue", "Ammeter", 0)
--compute control values as ratio to max
gCurRPM = (rpm - IDLERPM) / (FULLRPM - IDLERPM);
gCurAmps = amps / MAXAMPS;
exhaustrate = RATE - RATE * ((( gCurRPM * RPMCF ) + (( gCurAmps ) * AMPCF )))
exh_col = (( MAXAMPS - amps ) / MAXAMPS ) * COL
Call( "Exhaust:SetEmitterRate", exhaustrate )
Call( "Exhaust:SetEmitterColour", exh_col, exh_col, exh_col*BLNSS )
-- If this is a player train and this vehicle is the driven one, then send
-- RPM values in both directions along train. Note the Driven control is set
-- by the simulation script, which only runs on the vehicle the player is driving.
-- Only send messages if values have changed.
if ( Call( "GetIsPlayer" ) == 1 ) then
if ( Call( "*:GetControlValue", "Active", 0 ) == 1 ) then
if ( rpm ~= gPrevRPM ) then
Call( "SendConsistMessage", RPM_ID, gCurRPM, 1 )
Call( "SendConsistMessage", RPM_ID, gCurRPM, 0 )
end
if ( rpm_change ~= gPrevRPMDelta ) then
Call( "SendConsistMessage", RPMD_ID, rpm_change, 1 )
Call( "SendConsistMessage", RPMD_ID, rpm_change, 0 )
end
if ( amps ~= gPrevAmps ) then
Call( "SendConsistMessage", AMPS_ID, gCurAmps, 1 )
Call( "SendConsistMessage", AMPS_ID, gCurAmps, 0 )
end
end
gPrevRPM = gCurRPM
gPrevRPMDelta = rpm_change
gPrevAmps = gCurAmps
end
end
-- Core sim function executed if a consist message is received.
function OnConsistMessage ( msg, argument, direction )
-- If this is not the driven vehicle then update the controls for RPM values with the supplied data.
if ( Call( "*:GetControlValue", "Active", 0 ) == 0 ) then
Call( "Exhaust:SetEmitterActive", 1 )
if ( msg == RPM_ID ) then
Call( "*:SetControlValue", "RPM", 0, IDLERPM + ( FULLRPM - IDLERPM) * argument )
elseif ( msg == RPMD_ID ) then
Call( "*:SetControlValue", "RPMDelta", 0, argument )
elseif ( msg == AMPS_ID ) then
Call( "*:SetControlValue", "Ammeter", 0, MAXAMPS * argument )
end
-- Pass message along in same direction.
Call( "SendConsistMessage", msg, argument, direction )
end
end