Skip to content

Trait gain rules

This page covers the <GainTrait> and <LoseTrait> elements that live inside a job’s gains.xml file. These elements let you data-drive when a girl earns or loses a trait through repeated work.

For the XP / skill side of gains.xml (the <Skill>, <Stat>, and <Gains> attributes), see the gains.xml section in jobs-reference.md.


Each qualifying shift accumulates progress toward (or away from) the trait:

  • Gain: progress increases by amount each shift. The trait is granted when progress reaches threshold. Progress resets after the trait fires.
  • Lose: progress increases by amount each shift. The trait is removed when progress reaches threshold. Progress resets after the trait is removed.

Players can see in-progress traits on the Girl Details screen as a ten-cell bar and a running count — for example [██████░░░░] Mixologist (340/1000). Keeping threshold in the 500-2000 range means the bar reads naturally.


AttributeRequiredDefaultNotes
traitYesName of the trait to grant. Case-sensitive; must match the trait’s Name= in its .traitsx definition.
thresholdNo1000Total progress needed before the trait fires.
amountNo100Progress added per qualifying shift.
minShiftsNo0Tenure floor: the girl must have worked this job at least this many shifts before the rule accumulates any progress.
AttributeRequiredDefaultNotes
traitYesName of the trait to remove.
thresholdNo1000Total progress needed before the trait is removed.
amountNo100Progress subtracted per qualifying shift.
minShiftsNo0Tenure floor, same as for <GainTrait>.

Both elements also accept an optional <Curve> child — see Scaling progress with performance below.

Event="N" is also accepted for compatibility with older pack files but is a no-op in the current engine.


Default pacing — 10 shifts to earn Mixologist

Section titled “Default pacing — 10 shifts to earn Mixologist”
<GainTrait trait="Mixologist"/>

No threshold or amount — uses defaults (1000 / 100). The girl earns Mixologist after 10 qualifying shifts (roughly two and a half weeks of day-and-night work).


<GainTrait trait="Friendly" threshold="300"/>

Lower threshold means the trait arrives quickly. Suits common personality traits that are more about the job putting a girl in the right mindset than mastering a skill.


Mastery trait — takes extended commitment

Section titled “Mastery trait — takes extended commitment”
<GainTrait trait="Master Blacksmith" threshold="3000"/>

Higher threshold means the girl must work the job for roughly 30 shifts. Suitable for rare or powerful traits that should require sustained dedication.


Faster accumulation — same threshold, quicker progress

Section titled “Faster accumulation — same threshold, quicker progress”
<GainTrait trait="Resilient" threshold="1000" amount="200"/>

Doubling amount halves the time to threshold (5 shifts instead of 10). This is an alternative to lowering threshold when you want the bar to fill faster but still read as “halfway there” at the midpoint.


<GainTrait trait="Combat Veteran" threshold="2000" amount="100">
<When>
<Performance ge="200"/>
</When>
</GainTrait>

Only shifts where performance is at least 200 count toward the threshold. A girl who scrapes by on weak combat results will not accumulate progress; only strong performances build toward the trait. The <When> vocabulary is the same as in messages/work.xml — see when-conditions.md.


By default every qualifying shift adds the flat amount. A <Curve> child makes the per-shift progress scale with how well the girl actually performed that shift, so a strong shift moves the bar further than a weak one. With no <Curve> the behavior is unchanged.

<GainTrait trait="Skilled Whore" threshold="1000" amount="40">
<Curve type="sigmoid" min="0" max="100"/>
</GainTrait>

Three curve shapes are available:

  • linear — progress scales straight in line with the shift’s performance score.
  • sigmoid — rewards strong shifts and gives very little for weak ones, with a soft middle.
  • step — buckets the shift into low / medium / high and grants a third, two-thirds, or the full amount.

min and max set the performance range the curve is read across. A shift at min contributes the least, a shift at max the full amount.

<Curve> works on <LoseTrait> the same way.


minShifts stops a rule from accumulating until the girl has put in a minimum number of shifts on the job. It keeps a trait from creeping in after a single trial shift.

<GainTrait trait="Career Girl" threshold="1000" amount="25" minShifts="20"/>

Here progress only starts building once the girl has worked the job 20 times. Per-job shift counts are tracked per girl and saved with the game, so tenure survives a save and reload.


  • Progress is per-trait per-girl. Switching a girl to a different job pauses accumulation.
  • The visible bar has 10 cells, so threshold values around 500-2000 produce meaningful visual granularity. A threshold of 10 would fill the bar in a single shift and the player would never see partial progress.
  • <LoseTrait> only does anything if the girl currently has the trait. If she does not, the rule is ignored.
  • You can put multiple <GainTrait> entries in the same gains.xml — each tracks its own progress independently.