User talk:Hautarche

Jump to navigation Jump to search

About this board

I (Hauts) don't know where else to do this, so I've been using this section to write out the justifications for edits I make to the front-facing wiki pages.

Proof for Psychopath nullified thought list

3
Hautarche (talkcontribs)

Went through all the xml files under RimWorld\Data\[Biotech, Core, Ideology, Royalty]\Defs\ThoughtDefs, searched for the term "Psychopath". Wrote down all thoughts for which Psychopath showed up in its "nullifyingTraits" list. Then went to test them in a Dev Quicktest run of RimWorld.

Harakoni (talkcontribs)

This is good work but I should let you know that annoyingly not all thoughts are in the ThoughtDef folders.

For example, precept related thoughts are often in the precept defs

Also, to make it even easier, coder oriented text editors like Sublime Text and Notepad++ have "Find in Files" searches that let you search the contents of all the files in a directory, so you can find every usage in all the .xmls. No need to manually look through each file.

Hautarche (talkcontribs)

Ooh, thanks for the tip. Will be using that File in Files search from now on.

Reply to "Proof for Psychopath nullified thought list"

Why Pyromania and Gourmand DO have 50 day MTBs for their random mental states (or: you can't plot a curve with just one point)

2
Hautarche (talkcontribs)

It is not easy to test how the mental states randomly induced by Pyromaniac or Gourmand (namely, fire-starting spree and food binge) work. They are, after all, random, and they seem to take a lot of time to proc. Of course, if you go find the XML of these traits, you'll find the randomMentalState and randomMentalStateMtbDaysMoodCurve fields which govern this behavior. The former governs which mental state is randomly induced by the trait. The latter governs the 'mean time between' (MTB) episodes. In both cases, the latter has a sub-field called "points" in which there is only one point, <0,50>. This has a clear relation to the MTB - for example, if you change it to <0,1>, you will very quickly find that this makes the random mental states extremely frequent. But how does it work, and why is it called a "curve"?

In the code, randomMentalStateMtbDaysMoodCurve's only use lies within an MTB calculation. These kinds of calculations use three fields, 'mtb', 'mtbUnit', and 'checkDuration'. In this case, 'checkDuration' is 150 ticks; mtbUnit is 60000 ticks (aka 1 in-game day); and mtb... is the SimpleCurve evaluation of the pawn's current mood, using the points described in randomMentalStateMtbDaysMoodCurve's "points" field. Well, uh, how does THAT work?

A SimpleCurve is created by plotting a list of <x,y> points onto a Cartesian grid. The curve is "simple" because instead of actually creating a curvy line to map the function, it just creates straight lines between each successive point. When "evaluating" a number, it treats that number as the x-value of a coordinate, and returns the y-value of that coordinate as it would be on the plotted 'curve' (again, not actually a curve). If the number would result in a coordinate point left of the 'curves leftmost point, the y-value is that of the leftmost point of the 'curve'; and if it would be right of the rightmost, the y-value is that of the rightmost.

That's fascinating and all, but you may have noticed a problem already. Our SimpleCurve is informed by randomMentalStateMtbDaysMoodCurve, and in both Pyromaniac's and Gourmand's cases, they each only list a SINGLE POINT (<0,50>). How do you make a curve - or a 'curve' - out of a single point?

You don't, actually. And this works just fine! Because, if a pawn's mood is lower than 0 (technically impossible, but let's allow it), it's left of the leftmost point... and so the returned y-value is the y-value of the leftmost point... which is 50. And if a pawn's mood is higher than 0, it's right of the rightmost... and so the returned y-value is the y-value of the rightmost... which is 50. And if a pawn's mood is 0, well! Then the y-value of the 'curve' at that point is 50.

It really is an MTB of 50 days for both traits.

Hautarche (talkcontribs)

Uh and obviously 'days' is the unit because the MTB calculation uses 60000 ticks (1day) for its 'mtbUnit'. This assertion is also somewhat testable - with Pyromaniac, change <0,50> in your copy of RimWorld's XML to <0,1> and you'll find a Pyromaniac's random fire starting sprees occur about once a day.

Reply to "Why Pyromania and Gourmand DO have 50 day MTBs for their random mental states (or: you can't plot a curve with just one point)"

Mechanics behind Pyromaniac fire moodlet

1
Hautarche (talkcontribs)

It didn't warrant putting in my proposed edit to the Pyromaniac section of the "Traits" page, but after testing each lit building and going through RimWorld's code via the dnSpy decompiler, it seems to work like this:

Whenever it needs to determine how many stacks it has, the thought checks all cells within 8cells of the Pyromaniac's position. If said cell is within map bounds, isn't in the fog-of-war, and is within the same room as the Pyromaniac, the thought then adds however many fires are in that cell to the amount of stacks it has (up to the max of 4 stacks). The method it uses to determine how many fires are in a given cell is weird. It grabs every 'Thing' in the cell, and checks if...

1) it has a component that is/derives from "CompFireOverlayBase" (meaning that, under some circumstance, the Thing will display a fire graphic overlaid atop it), that it has a "CompGlower" (under some circumstance the Thing will emanate light), and the CompGlower is currently glowing.

2) the Thing currently has a fire attached to it.

3) the Thing is Fire, and it is attached to an object.

For each such condition that is true, the cell is considered to have +1 fire.


Onto the weird exceptions in how the total mood impact of "Beautiful fire" is calculated:

- Lit burnbongs do not count as fires: burnbongs are the only building in unmodded RimWorld which DO have a derivative of CompFireOverlayBase, but DON'T have a CompGlower. They thus don't fulfill condition '1)'.

- Free-spreading fire counts as 2 fires: the Thing which caught fire fulfills condition '2)', and the fire itself is a Fire Thing, which fulfills condition '3)'. This feels unintentional.

- Free-spreading fire on a Pawn counts as 1 fire: ... I thought I had an answer for this, but on reading over the code again I have no clue why this is.

- Burning walls don't count: they're not part of the current room.

- If a building occupies at least one cell within 8c of the Pyromaniac, and it is on fire, BUT that fire is only in cell(s) further than 8c from the Pyromaniac... it will still be counted by condition '2)' since it is, technically, on fire. In fact, each cell of the building within 8c of the Pyromaniac will count as an individual passed check for '2)'.

- Due to similar per-cell logic, a building that fulfills '1)' can do so multiple times if it occupies multiple cells. This is why pyres, being 2x2, can provide up to 4 stacks of the buff.

- A doorway counts as its own room, so a Pyromaniac standing in a doorway won't get any stacks even if there's a fire directly on either/all side(s) of the doorway.

Reply to "Mechanics behind Pyromaniac fire moodlet"
There are no older topics