Fires lit in fireplaces and furnaces go out in a single turn with plenty of perfectly good fuel in Build version: 0.E-7472-g7f7deed
They do not do this in
Build version: 0.E-7427-g895bbd8 that I was using yesterday.
The log says the fire was successfully lit.
go to a lovely ol' furnace in a basement, or a fireplace
use that good ol' advanced inventory to throw some planks and even rags in for good measure
have a lighter or matches
light fire, get told you were successful
fire goes out after a single turn.
fire burns as per normal
Platform : Windows
Graphics : Tiles
Build number : #11153
Build version: 0.E-7472-g7f7deed
Major version: 0.E
Confirmed.
Potential culprit: #44663
This issue has been mentioned on Cataclysm: Dark Days Ahead. There might be relevant details there:
This bug affects fire rings, wood stoves, braziers, and kitchen ovens as well. Haven't been able to do a survival only start cooking on any of those since I upgraded from 11133 to 11153 & then 11157.
Yeah, given the centrality to fire in the early game, I think this needs to be sorted out or reverted post-haste.
EDIT: comments below this one are updated with accurate info
I've been looking into this, and from what I can see, it's the do_decay field function that was PRed a few days ago mentioned above, but there are 2 problems to this.
@kevingranade
The first problem seems to stem from the exponential distribution coming up with random values based on the half_life of fire (1800 turns), which end up in the 600 turns range. In principle, this would mean fire has a max lifetime of 10 mins, not the 30 mins in the half_life definition.
The second problem, and why fire dies instantly, is that due to legacy code, as simulacrum told me, fire was created through map::add_field with an age of 600 turns or 10 minutes in order to handle shorter initial lifespans and a decreasing age for increasing fuel.
So then you have both problems converging, a fire that starts at 10 minutes of age, and a random distribution that kills it when it goes close to 10 minutes.
Potential fixes
I reckon fire should be redesigned to conform to a generic add_field and do_decay design, with increasing half_life for more fuel instead of decreasing age, with an overflow guard (which I understand it has at the moment, but for negative age), therefore starting at age 0 and not dying instantly, giving a 10 minute window to add more fuel before it dies on its own, which looks much cleaner. And/or the distribution should be redesigned, or half_life bumped up so the distribution gives higher values than 10 minutes (though all this seems like too much hassle for a snowflake fire which could be made to conform)..
Workaround
Currently there is a workaround I've found, which is creating a fire field through the debug map editor on a tile with fuel, etc. which gives it age 0, thereby skipping the age-distribution clash. Due to the way the distribution works, it is more reliable to spawn a stage 1 (or 2 if 1 doesn't work after a few tries, because 2 gives you more leeway) fire and fuel it heavily before the distribution kills it, and pray.
Another way is to directly light a stage 2 or stage 3 fire (fire or raging fire instead of small fire), but I have no clue if that's possible ingame. What this does is that due to do_decay, it lowers the intensity to 1 below (if you light a small fire, stage 1 - 1 is 0, and stage 0 deletes the fire, that's the exact line where the fire disappears) and resets age to 0. So if you light a stage 2 fire directly, it bumps down to stage 1, resets age,and then works perfectly fine for 10 minutes or more if you keep adding fuel.but you have to fuel it heavily to keep it alive before the distribution can come kill it.
"legacy_enum_id": 10,
is this the problem?
I'm going to try and fix this because it makes winter impossible to survive in.
this is in fields btw. It seems I was looking at json when this a problem with src files, not json.
No, that's just the id of the field, it's not a problem. I'm going to edit my comment because it wasn't entirely correct. 99% of the problem is actually the new exponential distribution. I looked at a few turns and the values it spat were close to 600 turns, so I thought it generated close to that, but now that I've begun to look into it, that's entirely not the case.
The initial 10 minutes of age for the fire effect is nothing more than speeding up the inevitability of death by exponential distribution.
I zeroed out all the initial ages in all the code I could find that creates a fire field, but that just made the decay distribution's effect more apparent. This is also why the workaround wouldn't work consistently, you immediately need to fuel your fire very hard so that it catches on and age can go into negatives (fuel subtracts age) before the exponential distribution comes reaping the poor fire's soul.
where is the error coming from?
You can't fix it without heavy work, it requires redesigning the do_decay function which requires experimenting and controlling variables and potentially statistics so it's just not a simple fix.
The problem is that the decay function gives values _every turn_ according to an exponential distribution which comes out to lots of low values and fewer high values, so statistically, you are far more likely to have a 1 minute fire vs 15 minute fire.
So in summary: every turn, the age of your fire increases from 0 onwards, then do_decay calculates a turn when your fire should die, for example 800, if that turn hasn't come yet, your fire lives. If the turn is lower than your fire's age, your fire dies. The problem is that do_decay can calculate more small numbers than big numbers, and since it does this every turn, at some point it calculates a lower number than your fire's age and so it dies.
Ok, that sounds complicated, just gonna wait until proper fix is implemented. Just gonna hope I don't get any winter starts until then. I have random starts on btw.
If you are comfortable with debugging and then reactivating achievements, you can just spawn a stage 1 or 2 fire and put a lot of fuel (something as flammable as possible, like kindling, dry stuff, etc. because only planks don't tend to do it) and just wait and see if it catches on. Once it has caught on, it won't die as long as you keep adding fuel.
If you want to make sure through the debug menu, go to map editor and move to the fire's tile, if the "A:
ok I'm pretty sure this is a lot simpler than it seems, what do_decay is supposed to do is choose a decay deadline once and only once for each field that has a half life, and for anything else just increment age by one.
Fire in particular is bad for this because it keeps bumping it's age as it consumes fuel or whatever, and ends up re-rolling the decay duration over and over again, which means yes it ends up extinguishing very quickly, in addition to whatever effect is making it go out almost immediately.
I thought do_decay() already excluded fire, but obviously I was wrong, so do_decay just needs a better test to exclude fire.
Ah, I see that now. But what happens when do_decay generates a very low number? I had a 5 generated one time and many lower than 100. Is this supposed to mimic randomness in reality so that you'd have to relight it?
Fire is very idiosyncratic and it makes zero sense for it to have a half-life in the first place. The previous code would never trigger decay if age was less than half of half-life, and this stuff was tuned around that.
For other fields, which are ALL generated at age 0, it's fine for them to be very ephemeral if the "dice" go that way (but you still almost never have them decaying immediately like we're seeing with fire).
This issue has been mentioned on Cataclysm: Dark Days Ahead. There might be relevant details there:
https://discourse.cataclysmdda.org/t/fire-goes-out-too-quickly/25271/16
This issue has been mentioned on Cataclysm: Dark Days Ahead. There might be relevant details there:
https://discourse.cataclysmdda.org/t/fire-fireplaces/25337/2
I found that dropping around 150 tinder on the fuel tile seems to almost guarantee it stays lit. I'm not sure if it's the tinder specifically but it definitely helped.
Most helpful comment
EDIT: comments below this one are updated with accurate info
I've been looking into this, and from what I can see, it's the do_decay field function that was PRed a few days ago mentioned above, but there are 2 problems to this.
@kevingranade
The first problem seems to stem from the exponential distribution coming up with random values based on the half_life of fire (1800 turns),
which end up in the 600 turns range. In principle, this would mean fire has a max lifetime of 10 mins, not the 30 mins in the half_life definition.The second problem, and why fire dies instantly, is that due to legacy code, as simulacrum told me, fire was created through map::add_field with an age of 600 turns or 10 minutes in order to handle shorter initial lifespans and a decreasing age for increasing fuel.
So then you have both problems converging, a fire that starts at 10 minutes of age, and a random distribution that kills it when it goes close to 10 minutes.Potential fixes
I reckon fire should be redesigned to conform to a generic add_field and do_decay design, with increasing half_life for more fuel instead of decreasing age, with an overflow guard (which I understand it has at the moment, but for negative age), therefore starting at age 0 and not dying instantly,
giving a 10 minute window to add more fuel before it dies on its own, which looks much cleaner.And/or the distribution should be redesigned, or half_life bumped up so the distribution gives higher values than 10 minutes (though all this seems like too much hassle for a snowflake fire which could be made to conform)..Workaround
Currently there is a workaround I've found, which is creating a fire field through the debug map editor on a tile with fuel, etc. which gives it age 0, thereby skipping the age-distribution clash.Due to the way the distribution works, it is more reliable to spawn a stage 1 (or 2 if 1 doesn't work after a few tries, because 2 gives you more leeway) fire and fuel it heavily before the distribution kills it, and pray.Another way is to directly light a stage 2 or stage 3 fire (fire or raging fire instead of small fire), but I have no clue if that's possible ingame. What this does is that due to do_decay, it lowers the intensity to 1 below (if you light a small fire, stage 1 - 1 is 0, and stage 0 deletes the fire, that's the exact line where the fire disappears) and resets age to 0. So if you light a stage 2 fire directly, it bumps down to stage 1, resets age,
and then works perfectly fine for 10 minutes or more if you keep adding fuel.but you have to fuel it heavily to keep it alive before the distribution can come kill it.