Thursday, August 19, 2021

Engine Quality Facts

Twitch streamer RoyaleWithCheeseTV asked me to take a look at Engine Quality.

I've always wanted to more about engine quality, so I thought I'd take a look!

What I found:

  • Initial engine quality is random, based partially by the vehicle stats and vehicle type
  • Engine quality affects whether it will start
  • 100% engines always start (99% of the time they do)
  • 99% engines fail to start ~20% of the time
  • Temperature affects whether an engine will start (if the quality is < 65)
  • Engine quality affects hotwiring - lower quality engines are easier to hotwire

Here's how I found it:

I was surprised to see that engines appear to be created in the lua code, in Vehicles.lua:

function Vehicles.Create.Engine(vehicle, part)
	if SandboxVars.VehicleEasyUse then
		vehicle:setEngineFeature(100, 30, vehicle:getScript():getEngineForce());
		return;
	end
	part:setRandomCondition(nil);
	local type = VehicleType.getTypeFromName(vehicle:getVehicleType());
	local engineQuality = 100;
	if type then
		local baseQuality = vehicle:getScript():getEngineQuality() * type:getBaseVehicleQuality();
		-- bit of randomize
		engineQuality = ZombRand(baseQuality - 10, baseQuality + 10);
	end
	engineQuality = ZombRand(engineQuality - 5, engineQuality + 5);
	engineQuality = math.max(engineQuality, 0)
	engineQuality = math.min(engineQuality, 100)

	local engineLoudness = vehicle:getScript():getEngineLoudness() or 100;
	engineLoudness = engineLoudness * (SandboxVars.ZombieAttractionMultiplier or 1);

	local qualityBoosted = engineQuality * 1.6;
	if qualityBoosted > 100 then qualityBoosted = 100; end
	local qualityModifier = math.max(0.6, ((qualityBoosted) / 100));
	local enginePower = vehicle:getScript():getEngineForce() * qualityModifier;

	vehicle:setEngineFeature(engineQuality, engineLoudness, enginePower);
end

Looks like the engine quality is randomly determined, based partially on the vehicle definition in the script and the vehicle type.

Also looks like engine power is affected by the engine quality (but probably only upon engine creation).  So there will be a correlation between engine quality and engine power.

After a little grepping, I confimed that the BaseVehicle class was where the engine quality is used in the code:

    private void updateEngineStarting() {
        if (this.getBatteryCharge() <= 0.1f) {
            this.engineDoStartingFailedNoPower();
            return;
        }
        VehiclePart vehiclePart = this.getPartById("GasTank");
        if (vehiclePart != null && vehiclePart.getContainerContentAmount() <= 0.0f) {
            this.engineDoStartingFailed();
            return;
        }
        int n = 0;
        float f = ClimateManager.getInstance().getAirTemperatureForSquare(this.getSquare());
        if (this.engineQuality < 65 && f <= 2.0f) {
            n = Math.min((2 - (int)f) * 2, 30);
        }
        if (!SandboxOptions.instance.VehicleEasyUse.getValue() && this.engineQuality < 100 && Rand.Next((int)(this.engineQuality + 50 - n)) <= 30) {
            this.engineDoStartingFailed();
            return;
        }
        if (Rand.Next((int)this.engineQuality) != 0) {
            this.engineDoStartingSuccess();
        } else {
            this.engineDoRetryingStarting();
        }
    }

As expected, engine quality affects whether or not an engine starts (per attempt).

I didn't know that 100% engines never fail!  (if enginequality = 100 it just skips over the failure code) (with caveat below)

In regular warm weather, 99% engines fail to start ~20% of the time.  (99 + 50) = 149.  Random chance of 0-148 being 30 or under is ~20%.

I didn't know that cold temperatures reduce the chance that an engine will start!  I've only played in winter twice.  Basically, if the temperature is 2 or lower (probably Celsius, but I haven't confirmed), that will modify "n" (to an upper limit of 30, with a temp of -13 or colder) that will reduce the chance the engine will start (if the quality of that engine is < 65).

Despite what I said earlier, there is a 1% chance that a 100% quality engine will not start.  After getting through the other possible obstacles to starting, the engine has a 1 in engineQuality chance of not starting.  I guess what I'm saying is that a 100% quality engine will have a 100% chance of getting to a point where it will start 99% of the time.

Another surprise for me was that engine quality affects (vanilla) hotwiring!

    public void tryHotwire(int n) {
        int n2 = Math.max(100 - this.getEngineQuality(), 5);
        n2 = Math.min(n2, 50);
        int n3 = n * 4;
        int n4 = n2 + n3;
        boolean bl = false;
        if (Rand.Next((int)100) <= n4) {
            this.setHotwired(true);
            bl = true;
        } else if (Rand.Next((int)100) <= 10 - n) {
            this.setHotwiredBroken(true);
            bl = true;
        } else if (GameServer.bServer) {
            LuaManager.GlobalObject.playServerSound((String)"VehicleHotwireFail", (IsoGridSquare)this.square);
        } else if (this.getDriver() != null) {
            this.getDriver().getEmitter().playSound("VehicleHotwireFail");
        }
        if (bl && GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 0x1000);
        }
    }

Here's how this appears to work:

  • The worse your engine quality, the higher n2 is.
  • n2 gets to be either n2 or 50, whichever is lower
  • The higher n2 is, the higher n4 is
  • The higher n4 is, the more of a chance of a successful hotwire.

So, the better quality engines are more difficult to hotwire (with limits).

That's it!  

Thanks for reading.  If you see any mistakes I made or have any questions, please let me know!

No comments:

Post a Comment

Do Gloves Protect You From Broken Glass?

Yes, gloves protect you from handling broken glass - any pair of gloves.  But gloves are not needed when removing broken glass from a smashe...