The Effects of Temperature

That sounds great! It’d certainly make it more worth while to not just wear utility vests and cargo/army pants and the idea of a limb based cold system would be fantastically horrible if frostbite was introduced. Similarly, in hot weather it gives more of a choice of wearing a helmet or not wearing a helmet (but needing some sort of hat) for heatstroke and delirium.

I’m sure I don’t really need to point this out, but perhaps some caution is needed on tying it to much to the endurance system as it could get frustrating (or needlessly grinding) if the weather affected it too much.

I think we’re all on the same page here! I’d like to call dibs though :3

At the moment, this is what I have

void game::check_bodytemp()
{
  // HEAD
  int timer = 300; // 30 minutes
  int change = bodytemp - temperature + 35
  if (turn % timer == 0){
    bodytemp -= change/abs(change); //May need balancing
	
	// timer increments
	
	if ( timer < 300 && timer > 0){			// Rain and sleep will affect code. 
	  if (weather  =  rain && outdoor) {timer -= 10;} 	// Pseudo code, need real values
	  if (weather !=  rain || indoor) {timer += 10;}
      if (fatigue < 192) {timer += 10;}
	    else if (fatigue < 383) {timer -= 10;}
	    else if (fatigue > 575) {timer -= 30;}
    }
  }

I just want to make sure that changes are slow moving and whatnot. After I get bodytemps going, I can assign diseases to it (which already exist but aren’t in use).

int stands for integer, right? So I can’t be having decimals in here…

Anyone know how long it takes a body to cool? Would be nice to have data :3

I would do something more like:

(not in C++ obviously, but it should be roughly translateable)
[tt]updateBodyTemp(){ //Called every 30 tics or something, I’d rather have the time consistent I guess.
multiplier = .1
player.bodyParts.each{|body_part|
if(environment.heat < body_part.heat){
multiplier += player.environment.windchill //Wind chill is only a factor for reducing temps
multiplier -= body_part.coldResistance //Product of worn clothes, any mutations, and wet status. May be negative.
}
if(environment.heat > body_part.heat){
multiplier -= body_part.heatResistance //Product of worn clothes, any mutations, and wet status. May be negative.
}
change = environment.heat - body_part.heat * multiplier; //Let’s say heat values range from 0 to 1000 in normal gameplay, and 500 is optimal.
body_part.temperature += change
body_part.temperature += player.heatGeneration
if(environment.heat > body_part.heat){
body_part.temperature -= player.heatDispersal //Probably dependent on a lot of the same things as cold_resistance
}
body_part.updateTemperatureConditions //update conditions as appropriate
}
player.normalizeTemperature //Just a basic function that moves heat around a bit, so insulating your torso will at least provide some protection overall.
}
[/tt]

Or at least that’s what I’d do off the top of my head. a little more thought would probably come up with something way better

I agree that having a fixed timer is probably better than dynamically adjusting the timer period, you can end up with some serious weirdness when a piece of code adjusts it’s own timing. Clothing, windchill, and dampness would influence the magnitude of temperature changes rather than how often adjustments happen.

I’d actually prefer to have the sampling rate be pretty quick, possibly around once a minute (10 turns). This is to make extreme environments take effect more smoothly. For example, if you go out into a blizzard wearing jeans and a tshirt for 5 minutes, there should be a noticeable effect, but if you have the refresh rate set to 30 mins there’s a really good chance that it will have no effect at all, whereas ducking out for literally just a few turns should have a decent chance of having no noticeable effect.

I’d prefer that the turn counter be checked in the main loop and conditionally call the function to handle temperature changes, because after having it brought to my attention I’d really like to unify all of that in a systematic way so it’s easier to understand what’s happening.

Why the 35 in “change = bodytemp - temperature + 35;”? Body temp should just move toward ambient temp for the time being, right? (basically the player is coldblooded right now, we can add warm-bloodedness once the endurance system gets added).

Not sure what units temperature are in right now, probably whole degrees in either C or F, if we’re doing this we might want to change that to degrees C or F * 10 or so so it adjusts more smoothly, and just convert to the nearest degree when outputting, or even just output a descriptive label.

Looking at Glyphgryph’s pseudocode:
I’m not sure about windchill only influencing cold temperatures, when it’s hot a breeze helps you stay cooler too.
As such I’m not sure it’s necessary to distinguish between losing heat and gaining heat, though something might come up that makes it necessary.

There’re a few different formulas for calculating windchill, just google wind chill chart. Might as well use one of them as a starting point as long as windchill is an issue.

More as a FYI than anything else, this is a sketch of how I’d start out.

// Might just want to push all of this down into a function in weather.cpp, and just pass in the ambient temp according to the game object.
// There might be more weather-based factors that influence effective temperature.
// regardless, the idea here is to do the calculations where they make the most sense.  On the other hand, it needs access to all the
// pertinent data, so it might want to know if the player is wearing a hat or not, it's a balancing act.
int game::effective_temperature(bool is_outside, bool is_wet) {
 int local_temp = temperature;
 if( is_outside ) {
  // This one might want to know if you're wearing a hat to adjust the results.
  local_temp = weather::adjust_for_sunlight( local_temp, is_wet );
  //Magic function that calculates windchill based on one of the weather service formulas
  //Wind speed might be internal to weather, so no need to pass it in.
  local_temp = weather::windchill( local_temp, wind_speed, is_wet );
 }
 // Kind of like windchill for heat, factors humidity into the temperature.
 // Since it's based on humidity, it doesn't care if you're inside or outside.
 local_temp = weather::heat_index( local_temp, is_wet );

 return local_temp;
}

player::update_body_temp(game *g) {
 normalize_temp();  //I think it's better to normalize the previous result, then apply the new effects, makes it lag a little bit.
 for( int i = 0; i < num_hp_parts ; i++ ) {
  int effective_body_temp = temp[i] + ( MAGIC_WARMTH_SCALING_FACTOR * warmth(i);
  const int temp_difference = g->effective_temperature( g->m.is_outside(posx, posy), p->is_wet() ) - effective_body_temp;
                                                   
  temp[i] += temp_difference * MAGIC_TEMP_SCALING_FACTOR;
}

Actually, wind still only keeps you cooler if a) the air is colder than your body temp (which lets be honest is most likely, so even in 90+ degree whether wind chill would be giving a bonus to prevent you from overheating, since you’re counting on the chill to balance out your internal hate generation) or b) it’s working with your bodies heat dispersal system, like sweat, and would get rolled into that call (since it might be enhanced by being extra sweaty or eliminated with very dry skin).

I’m almost 100% sure that a hot, over 100 degree wind doesn’t actually cool down things that are less than 100 degrees.

I purposely left out humidity. And since time and scale in game doesn’t really match reality, using reality-based wind chill formulas won’t really help - we need to focus on the result we want, and find one that gets to it.

And overall, you can note that my code /doesn’t/ distinguish between losing or gaining heat (they both get stuck in the same calculation, one is just negative).

What it DOES distinguish between is temperatures greater than body temperature or less than body temperature, which is quite different. It’s pretty exceptional circumstances to EVER use heat resistance - we are talking suits that let you move more safely through fire and the like at that point, or days that are incredibly hot and over 99 degrees. Mostly, this would only be used in places that are hot artificially, like the middle of a burning building or maybe a lab room that has the heat cranked way up for some reason. (I may be having some ideas, heheh)

The key to my formula is finding a balance between a characters native heat creation and heat loss at “normal” temperatures.

Note that as a bodyparts temp drops it will actually balance at a lower point, so that a “cold” day won’t kill you but rather give a consistent penalty.

Make sure any solution takes things like that into account.

I really like the ideas you guys are having about individual body part temperatures.

I think temperature should effect items as well. This might make things too hard, but maybe very low temperature’s should freeze water? In food it would prevent rot but require heating before eating.

It’s certainly a conceivable next step, but for the purposes of the poor processor it might just be easier to have items take whatever the environmental temperature is at the time, no calculations involved, even if calculations might be technically more accurate.

Okay, I did some research on body temps (that is, read a few wiki articles)

98.6 is average, you gain a bit during the day (let’s say 0.5), and you lose during the night (let’s say -0.5 tired / -1.0 dead tired / -1.5 exhausted). The ranges are approximate, but of course it’s ambiguous. 99.6 can be normal for one person, and 100.0 can be a fever for another.

I would say 101.0 and up, a fever kicks in, 103.0 and up is heat exhaustion, and 105.0 and up would be heat stroke. Perhaps 107.0 would be death. Symptoms include : confusion, fatigue, headache, sweating, vomiting, fainting. Remedies are : fluids, removing clothing, bathing, fanning. Drugs (coke, meth, and others) aggravate overheating.

I would say 95.0 and below, hypothermia kicks in. 95.0 and below could be mild, 92.0 and below moderate, and 86.0 and below severe. 82.0 would be death. Symptoms include : (violent) shivering, loss of dexterity, sluggish movement, confusion. Remedies are : warm fluids, wearing clothing, being near external heat sources. Alcohol and being wet aggravates hypothermia.

The way the game handles the levels of intoxication is with disease duration, but I would rather do intensity for temperature related diseases. Because as you warm up, they disappear. If the game checks every 10 turns to see if you’re cold, the diseases could last 10 turns. Intensity would increase as you breach the different levels of hypo/hyperthermia.

As for how the temperature changes… wind chill and heat index are modifiers for body heat. Should we add that information to weather patterns? Or should we just hack something together, like if it’s raining, then humidity is high.

Wind chill : http://upload.wikimedia.org/wikipedia/commons/f/ff/Wind_chill.png

Heat index : http://www.nws.noaa.gov/os/heat/images/heatindex.png

Humidity averages : http://www.ncdc.noaa.gov/oa/climate/online/ccd/avgrh.html

On a related note, now would be a good time for you to dig out your old better homes and gardens mod Gryph, with all the temperature stuff getting effects, not being totally crippled by wearing a tshirt under a jacket will become important. (I was actually just about to start working on that when I remembered you’d already done so in the past)

Honestly, most of what that mod did was reworking how items worked. Since I’m working right now on item rewrite, I feel like I’d have to just redo it all again, hah.

But honestly it might not be that big a deal to bring it over, and I’ve cleared my schedule tonight for Cataclysm coding, so maybe I’ll make that my first priority.

I won’t bother with any of the other bits though - everything else in the mod will be invalidated by the new item system.

I suppose it depends on how long the temperature stuff takes to implement, there’s no real rush until it’s actually finished. It’s just something to keep in mind.

Does this mean where weather and temperature is updated at the moment should be moved?

Not necessarily, once I actually start the cleanup I can move it along with any similar pieces of code, but I’d like new code at least to have the dispatch handled in the main game loop.

I have now coded enough to start thinking about penalties for hot/cold limbs. Body parts are : Head, eyes, mouth, torso, arms, hands, legs, feet.

At the moment, I might add encumbrance the cold penalties for most, and have special ones for torso and head. Perhaps eyes and mouth won’t have any because it’s a little hard to cover up.

One thing that’s done at extremely low temps is covering your mouth such that you have a pocket of air trapped against your mouth so it gets pre-warmed, I’m not sure there’s a condition that should be inflicted from your mouth getting cold, I think it’s enough for your mouth to get cold, and bring down your core temp when body part temperatures are normalized. Obviously it has the opposite effect of retaining unwanted heat when the temp is high.

With the eyes the main thing that happens is they water a lot if they aren’t protected from the cold and wind, which implies a perception penalty similar to glare, but now that I think of it that can just be encumbrance too.

EDIT:
I really can’t think of any bodypart-specific disorders that’d be brought about by high/low temperatures (short of actual burning/freezing), which is why the more i think about it the more I like the idea of just factoring per-limb body temp into the encumbrance calculations for those limbs. At the extremes frostbite could be reflected with straight up damage, and I’m not sure there’d be any heat-related issues at all for particular limbs, getting too hot is pretty much a purely systemic problem. On the other hand, sunburn? :stuck_out_tongue:

The real impact of tracking temp on a per-limb basis is to simulate heat loss/retention across the whole body so you don’t have silly things like just layering warm clothes onto body parts you don’t mind being encumbered and leaving the rest totally bare.

well all this looks promising im glad i took a break now

Shivers/Shakes can hit an individual bodypart, as well as the whole body. Particularly present when trying to be precise about something.

I think frostbite for individual bodyparts is a must in my opinion - and it’s fine for it to be a bit skewed as cold is usually more dangerous than heat in an urban/shaded environment. Straight up damage seems to be an ok way to go for frostbite, but as damage can currently be insta-healed with first-aid kits/bandages I wonder if a more ‘permanent’ solution would be better, perhaps it could reduce the total hp for those areas permanently ( to simulate bits falling off!)? Depending on how much work it is, I guess there could be a time frame in which warming up would negate the effects of frostbite and return you to normal.

I do think that water consumption should rocket up in hot weather though, and possibly heat delirium/sunstroke could also be a factor (maybe in perception, or maybe as similar to the schizophrenia trait?).

That’s an interesting idea, extreme frostbite could lower max limb HP while it’s in effect, so you just can’t get those HP back until you warm up. Perhaps a bit of both where it does periodic damage as well as adding the HP cap. Obviously super-extreme frostbite (limb reaching 0 HP) would no longer be recoverable by normal means.

RE: water consumption etc, I want to add in a whole metabolism system where activity burns calories and makes you tired and hungry, and the temperature system would feed into that, so that’s on the list.