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.

Hautarche (talkcontribs)

I got around to playing a mechanitor in 1.5 and noticed that enemy diaboli behave oddly now; they seemed to prioritize using Fire Burst instead of using their Hellsphere Cannon or attempting to close the distance. At first, I thought this was an issue caused by mods.


So I started several Dev Quicktest runs without any mods. In each, I used Dev Mode to place down a diabolus, then I went through various scenarios of pawns attacking them with weapons of different ranges, running past them without attacking them, or outright ignoring them. I then also looked at the ThinkTrees that diaboli use, the AICanTargetNow function of the Fire Burst ability, and so on and so forth...


Anyways, sources for all the information I've edited into the Diabolus page:

- I ordered friendly diaboli to use Fire Burst, watched enemy diaboli use it, and used Dev Mode to force enemy diaboli to use it. In all three instances, their behavior is identical: a three-second warmup during which chemfuel puddles are deposited to random points in 5.9c radius, followed by the deposition of chemfuel puddles into the remaining cells in 5.9c radius and a flame explosion with 5.9c radius. The ability then goes on cooldown for what appears to be 1 hour according to the GUI, but is actually 2700 ticks (1.08 hours) per the XML.

- The code for CompAbilityEffect_FireBurst is just 'GenExplosion.DoExplosion(this.Pawn.Position, this.Pawn.MapHeld, this.Props.radius, DamageDefOf.Flame, this.Pawn, -1, -1f, null, null, null, null, ThingDefOf.Filth_Fuel, 1f, 1, null, false, null, 0f, 1, 1f, false, null, null, null, false, 0.6f, 0f, true, null, 1f, null, null)'. So yes, the damage type is Flame. The two fields after 'this.Pawn' are the damage amount and armor penetration fields, in that order; since the listed damage amount is <0, DoExplosion uses Flame damage's default damage amount, which is 10, and since the listed armor penetration is <0, DoExplosion uses its default armor penetration, which is 0.

- In testing, enemy diaboli start using Fire Burst as soon as someone starts aiming at them, unless they were already using the Hellsphere Cannon. Meanwhile, colonists, pets, and mechanoids can run in close proximity to a diabolus without provoking Fire Burst; instead, it tries using its Hellsphere Cannon or melee attacks. HOWEVER, in the run in which I first noticed odd diabolus behavior, it didn't seem to be this way; that may be due to the following reasons. 1) Some of my colonists have weapons that can attack from >=66c away; 2) Fire Burst's AI usage is governed by AICanTargetNow, which is ultimately called by the diabolus' ThinkTree under whatever ThinkNode gives it JobGiver_AIFightEnemy (or in this case its derivative JobGiver_AIFightEnemies); and 3) this node in the diabolus' ThinkTree has a targetAcquireRadius of 65c. Subsequent testing with mods that enabled me to give colonists weapons with >65c range showed that diaboli will start using Fire Burst if they are not currently using Hellsphere Cannon, and are being aimed at or attacked by a pawn within 65c.

- I actually tried to test the "friendly" claim and see how diaboli from an allied faction use Fire Burst. These diaboli, which I set to various allied or neutral factions, were instead confused about their existence and wandered around aimlessly, not responding to attacks from anything (though their mounted charge turret still shot at hostile pawns nearby). This may be due to how the "Set Faction" Dev Mode tool works, though - I suspect if a mod were to add an allied faction that can field diaboli, and bothers to give them a Lord AI that lets them attack, such friendly diaboli will use Fire Burst the same way enemy diaboli do.

Hautarche (talkcontribs)

After thinking about how AICanTargetNow gets called, and recalling discrepancies between diabolus behavior during testing and non-test gameplay, I ran another set of tests that were identical to the first, with one exception: instead of *spawning* diaboli from scratch, I had a mechanitor summon them, and then I either initiated the test while the diabolus was still preparing to attack or after it started making its way towards my base. This is important because diaboli spawned from the "Spawn Pawn" Dev Tool have a different AI Lord than those that drop in after being summoned by a mechanitor (or as part of the entourage of another mechanoid boss or raid); obviously the latter is the one actually pertinent to players reading the wiki.

This round of testing showed slightly different results. To make a long story short, non-player-controlled diaboli will only use Fire Burst if the ability's AICanTargetNow function says to do so, but that in turn only gets evaluated while the diabolus is fighting enemies. A diabolus that is NOT fighting enemies therefore cannot cast Fire Burst. Diaboli are NOT fighting enemies when wandering around in preparation for an assault, as well as when they are simply pathing towards your colony (or aiming a weapon at random buildings/furniture; this is also not 'fighting enemies'). Diaboli switch to fighting enemies when they are hit by a damaging attack, (sometimes) when anyone in their 'party' is hit by a damaging attack, or when they spend enough time proximate to pawns they COULD fight; you'll know they're in this mode because they path towards your pawns and then start trying to shoot them with the Hellsphere Cannon. Note that the charge blaster turret fires independently of the diabolus and so is not an identifier of the diabolus' current Toil.

All that said, when the diabolus IS fighting enemies, Fire Burst does in fact proc when attacked or even aimed at.

This is why I have submitted an edit-of-my-edit further clarifying how diaboli' fire burst work.

Reply to "Diabolus Fire Burst notes"

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