Open koosemose opened 7 years ago
I was going to post a new issue, but this is a right place :D. Okay I have a working example of it (it uses a simulation through javascript took maybe 6 hrs to build). Here is the link. Posted it also on discord but I'll do it here for right jollies. It has a 3D mode if you so desire (idk) and in 2D it'll show the current values (the redder the square the hotter). This uses the real world values for heat transfer (well its thermal conductivity) and applies a general formula (crafted by me :D), it seems incredibly accurate (and I'm constantly improving it).
It uses a few different ways to balance such as it requiring more heat the more heat it has (exponentially) and it loosing heat based on index and starting heat (therefore things that are hotter will cool down quicker, theoretically though haven't tested). It should work with negative temperatures (cooling things down, but haven't tested). This is incredibly fast since it doesn't require a complex algorithm and only needs to update whenever there is a new heat input, then once the heat is done it can apply a simple dispersion technique (find your neighbours and average out heat) to average out the heat and disperse it which will eventually fully disperse it across the map (admittedly haven't added this yet, but I did a test and it worked well, just wanted to right it non-hackily).
Anyways I think this is a good way to do temperature simplifying the whole process; there is even a variable k for us to play around with (lower k is, the more impact that index has effectively, essentially the more energy is lost). This wouldn't require us do it on a room by room basis and would stop bleeding through walls (though currently it does let a good amount of heat through, but with a k value of 0.1 its much much more accurate, just we can gamify requiring double thick walls and so on to our hearts content). Have a play around with the system (personally I like the 3D a lot), and the idea of adding a z dimension is trivial (literally its just adding another for loop) and I'll get around to it when I have the time to try to figure out 3D in javascript better (since I'm not particularly good at javascript and never used the p5 library I'm using before lol).
Note: it may seem rapid but remember the starting temperature (U) is 100, which means 100 c or 212 f per iteration outputted which is a high amount. A more reasonable amount is 21 which you can set it too just for testing its easier to do extreme amounts :D
I think we do want it to heat through walls (if much more slowly of course). And how will this handle empty space? In theory it shouldn't lose heat to space (or at least at an incredibly slow rate).
Also, from my understanding of what you're saying, a heat source functions by setting the heat of its tile? Is this correct? And if so would there be a way to do something to allow something similar to waste heat. Use case being the RTG, it's purpose isn't to generate heat, and instead just generates it as a by-product, with the intention (not currently implemented) that if it gets too hot it's less efficient (or more precisely as it gets hotter it gets less efficient).. the idea being as a balancing mechanic, to get a benefit from multiple RTGs, you either build it outside (where it's built-in heat radiators will be able to disperse the heat away) and have it vulnerable to attack, or build it inside, and begin to suffer efficiency loss (and possibly overheating in general), as it heats up the air around it, and eventually is no longer able to efficiently dump heat, or build some kind of way to dump excess heat (I assume eventually we'll have some kind of furniture that is either built outside of the base or in place of a wall and extends to the outside and is able to dump heat)
And in general the functionality looks good... of course the true test is how it handles when restricted to our updating system, and we have to worry about it's time taken during a frame.
What happens is you just tell the system where you want to place 'heat' then it will work out the dispersion of that heat. Currently it allows a good amount through walls (though this can be fine tuned, but that would be fine tuning through either index, or k, since if k is 0.1 ITS much more restrictive; the slider (on the top left I believe) if slided to the very left will do the 0.1 and then play with graphene and it won't even pass through one tile (and the one tile after is much smaller). So really nothing is a heat source (in the example I just chose one random tile to output heat), but whenever the command Cycle is called it performs a heat dispersion based on that tile location and area :D. Also we could change the equation to value index a little higher (index effects it so that a smaller index = less heat lost; larger index = more heat lost).
Note: I forgot to say this before but it could update every ms and not be slow at all (the operations its doing is simple and literally passing through all the tiles you see it stops when either the heat becomes too small to be impactful or the map edge), I only made them update that slowly because otherwise the colours would flicker (and I was worried about it being a seizure warning, since they flicked very, very fast). In reality you just set the index to 0 and it won't loose any heat what so ever (well you can't set it to 0 since it does log (index) so you would have to set it to an infinitesimal; where it would loose such a small amount of heat it would be un-noticeable).
However, if you wanted it too lose some heat, then all you would do would just set it to a number MUCH smaller than air (though I'm sure there is a thermal conductivity value of vacuum - well 'space vacuum').
Now the only real problem I can see with this system is that indexes have to be in double/decimal format (to support the small amount) but again not a problem since we set it once and its essentially a constant (and it isn't used with anything but a log function). Now currently its pretending if every single tile that you see is off index air, mineral water, water and so on. But it's relatively easy to implement it properly (in which case it looses energy depending on the material), and in that case implementing it will also make it so that putting a single wall like this:
y y y
y x y
y y y
This will cause the heat map to look something like this (random numbers):
19 5.5 19
44 22 44
66 66 66
And in 'theory' it should be fast again since I just base it off neighbours :D. Now this system kinda relies on neighbours and each tile containing its temperature, because what happens is that the system doesn't base how much you get based of the tile's temperature it just tells you how much 'energy' or 'potential heat/temperature' its placing into the object then the tile works out a basic linear relationship of the current temperature and the initial temperature as well as the temperature that was pushed. This is important since I'm planning to make it equalise once the 'push' of the new temperature has stopped in which it would do another temperature push. This time however it doesn't push temperature but rather tells each individual cell/tile that (it would normally influence with the previous heat) it should equalise, where all they do is a simple get all neighbours with a smaller temperature than me (to prevent them going back and forth you could just do a larger difference then x or whatever) then find the average difference and then loose that amount (averaged, a lot of averages lol), so that we equal approx. the same amount. Now personally I think this should only happen in rooms (and outside to a much smaller effect), since it disperses like this as heat rises causing the tiles above to become more hot (but we may not want to implement this) and the tiles below more cool.
All of this is perfectly implementable and should fit right in with our updating system (it only needs to update whenever there is a heat source OR after the heat source has ended, in the case of waste where its inconsistent it would have to do it twice after every operation, but it could delay it or could just do a bundle of them at once every second (like check all the change we did this frame, are any of them the same if so remove, then just iterate through each one removing any that reach 0 else telling the square to disperse) :D.
what if temperature system would use same system as our gas system (if you want to have it per room). Then only walls can be handled as were tiles before - so as temperature per tile for receiving and spreading the temperature further through walls
The problem is with the equation... its too slow to run and the system takes too long to spread out. Using the same system as gas would not fix it really and would still require things to equalise; and wouldn't work at all in space and wouldn't go through walls which we need, and it wouldn't be based on the index of the material. It really requires a new equation to disperse things based on an index (my proposal uses the thermal conductivity index). And it should be different depending on the wall and such, and with rooms it should depend on room size (x, y, and z) as well as shape and things like walls in the middle to properly disperse, and it needs to just 'put 50 degrees' at this location and so on. Though I do like the idea of making all the systems similar and connected. So maybe what could happen (either at this point or in the future) would be the connection of all these systems and then changed to work as core mods :D.
well, maybe question is, what gameplay elements you want to have hooked on temperature that will be still fun to have. If it's just mechanics to freeze your characters and maybe something to reinforce shield to prevent heat from sun or something, then we are good with just having flat temperature per room (similar to gas) and then conductivity only for walls you still want to keep tile-by-tile spread even for empty tiles (floor)?
Yeh we do, and there are a lot (tons) of mechanics we want. Like hot air rises, freezing characters, characters needing a specific temperature, food going off at higher temperatures, and so on that require dynamic things. I.e. sending out a naked guy in space should freeze him to death and I would rather that happen by temperature then just us saying: is he in space... yes okay freeze and that technically he could hold onto a heater and survive by that (though he would require an oxygen mask and probably other stuff too). And well what is a wall?? The system doesn't know what is a wall and what isn't so that would require too much work anyways, also different gases should effect what speed the temperature expands at (which I've already gotten to work on my local example through a javascript simulation) and different concentrations (also as things get hotter it requires more heat to heat them up).
Literally heat is sooooo complex (took me hours to make up an equation, that was accurate and a lot easier - no powers, few logarithmic functions, semi-linear), it requires soo much work to do flat temperature (otherwise if I had a 21 degree heater then is that room 21? no its going to slowly increase for ever and ever, and if we did something like gas could reach 400 degrees in like 5 mins... my system would take literally hrs to reach anything near that, and it takes quite a while at 200 degrees C and a maximum k value to reach even 100 degrees. Its more of a problem of how complex heat is requiring a semi-complex solution :D. There is a link (in my first comment) of an example I wrote in javascript that is pretty accurate (and hell it has 3D too for no real reason). :D. And its harder to say well we only want this to work for rooms cause then what if you have a room with a hole in it? Then what happens? Is it just instantly 0 degrees C, and just has no temperature changes ? Or does it work normally probably causing large inconsistencies and so on.
I don't know.. only case so far that can't be covered by flat (but dynamic) temperature per room is that naked guy in space - which would still require some pressure to survive, so only temperature source won't keep him alive. I don't like tile-by-tile temperature differences in room because of how characters are pathing things and how player doesn't have direct control over path or character (unless we will include temperature into pathing algorithm that is). Imagine half of room being frozen and half of it safe (warm). You would send character to pick up something from safe zone, but because of pathing, he may pass some tiles that will insta kill him (really really low temperature). That doesn't sound like fun mechanic. Alternative with flat room temp would be that temperature will be averaged and character getting some freeze damage from lower temperature in whole room. And by wall as conductor I meant something like having component (similar to GasConnection or PowerConnection) that may have some conductivity, temp absorption/emission parameters (HeatConnection?)
With a new system (and @BraedonWooding 's seems to perform along these lines, based on his javascript demo), it shouldn't be feasible to have one section of a room that is fatal, and the other safe. The temperature should diffuse through the room fast enough that it's going to equalise very quickly, and at most you would end up with more or less comfortable, or more or less deadly. Worse case scenario, you might manage to have a line where you are either extremely uncomfortable, and on the other side you are in an extremely minor amount of danger.
At the very least I am willing to consider this as a viable approach to be tried, pending testing of course. We did discuss doing a room based temperature tracking, and I still consider it a viable option if this doesn't work as desired, one of the most significant difficulties that would need to be overcome is tracking a room's walls, it would need to either begin tracking them specifically (meaning a lot of maintenance as rooms are changed), or a more efficient way of it to find it's bordering furniture on the fly. Neither of these are so insurmountable that room by room temp isn't viable, but it's enough potential extra weight added to it for me to consider an improved version of tile by tile tracking.
All temperature will diffuse accurately and yes as koose said mine is a good example of this. Inside a spaceship and even in space, air will never be cold enough to kill u as u pass through one square IF for some reason the system fails or the user places heat sources wrong and has a gap (but with air being such a low index thats relatively impossible), on average you require to be in space for a considerable few seconds to die and thats mostly from depressurisation and from lack of oxygen (essentially the mix if them force the oxygen from your cells through the loss of pressure, and people dont freeze up instantly like in movies thats a 'hollywood inaccuracy' it takes significantly longer to freeze up). So just being in a space of 0 degrees, or like -15 + won't kill you instantly or even near. Space is around 2.7 Kelvin or like -270 degrees C (-454 F) and due to the way the body works your skin will act as a cold shield essentially for quite a few seconds (regardless of the temperature, after that then the temperature matters). However, I doubt this will ever happen without the user to be at blame since once the heat has finished dispersing the temperature will disperse averaging out across its area.
And i will note i was suggesting to koose on discord about room by room and stating its benefits, but i feel that implementing a good tile by tile is imperative before we go into room by room (since tile by tile covers most of the map).
Do you think your system can handle things having a variable index? i.e. a door should have an index similar to a wall when closed, but when open it should be closer to air.
Yep, index will just be an attribute of the furniture so defined in xml, which means if you want it to change you will need some scripting behaviour for it though im sure the are other component based ways it could be done too. So short answer yes.
I think we should just go with Braedon's tile system for now. I'll hang on to the code for the room system for a qhile and it it turns out to not perform so well we can always try that instead.
I will just put a note not to merge this yet, since I have a few planned tweaks that I want to test out a little more, I'll get these out sometime tomorrow or the day after. Also @abackwood yeh don't delete your branch my system may not be as good if we have multiple world's due to some bizarre reason or whatever :D. So we'll see how tile by tile works and later on we can always make it so rooms do tile by tile but 'non' rooms do the diffusion is currently implemented (if speed is a concern at a point).
Just to start the conversation on the questing started in #1744.
There are two questions to be decided:
Should heating follow a (semi-)realistic model, where it is (to drastically simplify) more difficult to heat something up the hotter it is (for any interested in the specifics, I believe @BraedonWooding has the knowledge to detail the specifics further, but I don't think it is needed for the general decision of if it should be done.)
If it is to be done, how should it be done?
As far as the first, I have no strong opinion, other than that it doesn't negatively impact gameplay (both in the sense of the player's interaction with systems, and having enough relevant information to play well)
As for the second, there have been several ways suggested in the PR referenced earlier. The first suggested by @crazyfox55 is simply to have the energy have an exponential relationship with the actual temperature. While not strictly accurate this may be the most simple way of representing the intention, in that a certain amount of "heating ability" in a source will generate less and less temperature, the higher the temperature is. @abackwood 's suggested approach is to leave the calculations in the furniture's mechanics. I am not absolutely sure I am understanding their intention correctly, but if I am, I believe this is the wrong approach to leave it in the furnitures' hands, both from a realism standpoint and an use of use (for a modder or developer implementing a furniture), if each furniture is required to implement this it would require each modder/developer to reimplement the same sort of code, and either repeat code, or leave room for someone to do it incorrectly, so that one device that generates heat does it different from others.
My own personal suggestion would be for it to be in the atmosphere code, as it is a property of the physics involved, such that a furniture generating heat just has to say it is generating X amount of "heating power" and the atmosphere it is generating it into will be converting that into the amount of actual energy that makes it into the system.
Just to make it clear, I may be unintentionally misrepresenting the suggestions of others, I am simply trying to reiterate them here to get the discussion started and so that others have a rough idea of what has been discussed in the PR already. (those whose opinions/suggestions I am representing, please correct me if I am misrepresenting or clarify if I am oversimplifying.)
Now I do want to point out that this said model where heat requires more energy the hotter it is is only in relation to things like metals (and all other materials too), this is due to the motions of free electrons and the molecular vibrations that take place. Since air ecompasses every 'little' bit of the space around us it conducts heat extraordinarily well, so from this we can form two 'models' one which we generalise and state that merely all tiles (including 'air') perform this, and the reason why I suggested this originally is because we are doing room by room so it's not like we can 'single out tiles' so to speak. On the other hand we could also do a more energy based approach, and have a well built energy system (that I guess even the electrical energy could use and later on mechanical and other forms), then as what is currently done convert that energy to heat. We could get essentially an average 'energy resistance' value based upon either a constant for furniture/tiles then whenever something is placed we just need to recalc this 'average' in that room. This could give a more accurate reading but the 'general formula' i think is simple.
So then heaters (and coolers in turn) would still function linearly, since what we're tracking is the heating of the air in the room, it would only be the transmission through walls that should function more exponentially?
And would that also mean walls would heat rooms linearly (since again, they're heating the air)? Though that may be harder to differentiate (not being completely familiar with the system).
Trying to simplify and repeat to ensure that I understand and am parsing what you're saying correctly.
Yes that is completely correct as long as we are just tracking the air temperature then its linear (well rather the diffusion is more parabolic in nature but yeh) that's completely correct, I felt we were tracking including objects but from looking at it again we aren't we are tracking air so in that case we wouldn't need exponential. However, as a game feature/thing having it exponential is a lot more user friendly since it means if they install a super heater ('spitballing' here so to speak) and forget to lower its temperature before it stops (like its range of function) then the room could get insanely hot very quickly, so having an exponential (even if its ever so slight) or even more of a parabolic (well hyperbolic) representation is much more friendly and less prone to odd mistakes.
Displaying the temperature in more understandable terms exposes some other issues preexisting with temperature, most particularly it heats tiles up insanely fast at the heat source but doesn't dissipate that heat to surrounding tiles nearly fast enough, so the heat source will end up at around 1000F, the next tile over at 256F and the next out will be around -256F. Even doing it on a faster timer (everyframe) it doesn't work in any vaguely realistic way (and bogs the game down horribly, as one might expect).
That doesn't count all the things it just does horribly wrong, from trying to patch issues in the past that now the temperature system is just juggling around meaningless numbers, wasting time on an allegedly more realistic temperature simulation, that takes too much time, is really more simulation than we need if it worked correctly, and manages to work less realistically than a simpler method such as tracking per room.
I think we need to look into tracking temperature in a different way, perhaps on a room by room basis (of course that brings its own collection of problems to solve, such as how to handle heat transfer through walls), or even just rewriting the whole thing using the same general type of system, just in a way that actually functions more properly.