Jump to content

player_classified SetTemperature rounding can result in no temperature damage feedback for client players


hoxi
  • Pending

This includes the host player of a server that has caves enabled, as they're also a client.

With how the server syncs temperature to clients in steps of 0.25 within a certain range, or 1 otherwise, it's possible for a player to take freezing or overheating damage, yet on the client's end, nothing will indicate this besides dialog from the character and health values changing (if hovering over the health bar, or displaying them with mods, as the arrow won't show up). That is, until they receive the next step at -0.25 or 70.25 degrees, respectively.

This is mostly an issue when having any sort of insulation, or anything that slows down temperature changes, but it can be significant, due to damage taken being the same regardless of how cold or warm you are. With enough insulation and other factors, it can take several seconds for the Ice and Heat overlay visual and audio effects to kick in.

Here's the function that syncs the temperature to a client.

local function SetTemperature(inst, temperature)
    if temperature >= max_precision_temp then
        inst.currenttemperaturedata:set(pivot + max_precision_temp * precision_factor + math.floor((temperature - max_precision_temp) * coarse_factor + .5))
    elseif temperature <= min_precision_temp then
        inst.currenttemperaturedata:set(pivot + min_precision_temp * precision_factor + math.floor((temperature - min_precision_temp) * coarse_factor + .5))
    else
        inst.currenttemperaturedata:set(pivot + math.floor(temperature * precision_factor + .5))
    end
end

And here's my suggestion about what to do with it (I'm doing it like this because it's probably easier to explain it this way rather than going into detail with just pure text, look for the comments):

local function SetTemperature(inst, temperature)
    local rnd_temp, temp_on_client, net_value = nil

    if temperature >= max_precision_temp then
        rnd_temp = math.floor((temperature - max_precision_temp) * coarse_factor + .5)
        temp_on_client = rnd_temp + max_precision_temp
        net_value = pivot + max_precision_temp * precision_factor + rnd_temp
    elseif temperature <= min_precision_temp then
        rnd_temp = math.floor((temperature - min_precision_temp) * coarse_factor + .5)
        temp_on_client = rnd_temp + min_precision_temp
        net_value = pivot + min_precision_temp * precision_factor + rnd_temp
    else
        rnd_temp = math.floor(temperature * precision_factor + .5)
        temp_on_client = rnd_temp / precision_factor
        net_value = pivot + rnd_temp
    end

    if temperature < 0 and temp_on_client >= 0 then
        net_value = net_value - 1 --we're freezing, but client will think we're not due to receiving 0°, so send one step less so they get -0.25°
    elseif temperature > TUNING.OVERHEAT_TEMP and temp_on_client <= TUNING.OVERHEAT_TEMP then
        net_value = net_value + 1 --we're overheating, but client will think we're not due to receiving 70°, so send one more step so they get 71°
    end

    inst.currenttemperaturedata:set(net_value)
end

I'm aware that this is kinda hacky and that there could be other ways. Maybe a refactor or major rework of the system is needed and instead syncing booleans for overheating and freezing would be better. But given that the system already syncs in steps of 0.25 or 1 to clients (which is pretty imprecise, yet it gets the job done, if we don't count this issue), I think it'd be a simple solution to fix this issue and make harmful temperature changes feel as responsive as they should be.

I tested this repeatedly and it makes it feel like it's singleplayer Don't Starve or when playing DST with caves disabled, with how your game will immediately let you know you're taking damage, even when wearing a lot of insulation, which is not how it currently works in DST. Sure, connection lag is still there for non-local servers, but solving this would help a lot.

On a similar note, I want to ask if you could please look at this report I made a few months ago. It's also related to temperature damage, but in this case, it's about the overlay warning that you're gonna take damage from freezing not showing up.


Steps to Reproduce
  1. While the world is cold or hot enough to damage you, wear a lot of the respective insulation to fight against it, freezing or overheating. So that your temperature changes slowly. You can test the cold part of this issue using an Ice Crystaleyezer.
  2. Once your getting close to freezing/overheating, pay attention to your character and your health bar (hover over it).
  3. Notice how eventually, your character will comment that it's too cold/hot, and your health will go down if you look at it, yet for a while, neither the overlay will play the visual and sound effects, and the health bar won't show an arrow pointing down.



User Feedback


Still an issue despite the recent temperature-related changes in the last updates.

I know the presented solution is kinda hacky and a slight rework using booleans or similar would work better, but you get the point.

Share this comment


Link to comment
Share on other sites



Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
  • Create New...