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.


Three things about the bookkeeping that are easy to assume wrongly:

  • Progress belongs to the trait, not to the job. Every rule that names Tough adds to the same bar, so a worker who started earning it as a Farmer keeps the progress when she moves to Shepherd, and either job can finish it.
  • Tenure belongs to the job. minShifts counts shifts she has worked in that job. Only jobs that have a minShifts rule count at all, so a job without one never records tenure, and a save from before the rule was written knows nothing of shifts worked earlier: she starts at zero there.
  • A shift she worked counts even when it made nothing. A shift whose materials were missing, so its resource step was rejected, still adds progress. Refused and rested shifts add nothing.
Attribute Required Default Notes
trait Yes – Name of the trait to grant. Case-sensitive; must match the trait’s Name= in its .traitsx definition.
threshold No 1000 Total progress needed before the trait fires.
amount No 100 Progress added per qualifying shift.
minShifts No 0 Tenure floor: the girl must have worked this job at least this many shifts before the rule accumulates any progress.
Attribute Required Default Notes
trait Yes – Name of the trait to remove.
threshold No 1000 Total progress needed before the trait is removed.
amount No 100 Progress subtracted per qualifying shift.
minShifts No 0 Tenure 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.


What the player sees (game 1.21, unreleased)

Section titled “What the player sees (game 1.21, unreleased)”

When a rule flips a trait, her weekly report gets a line naming the job that did it and what the trait does (the description from the trait catalogue), so the player learns the cause with the change. Her practice is reported when the week closes, one line for each job that moved something and never a note per increment, so a refused or rested night does not swallow the day’s practice:

Practice this week (Farmer): toward Tough 40%; shedding Fragile 60%.

The percentage is progress against threshold, capped at 99 until the trait fires. A rule that does not apply to her, a gain for a trait she already has or a shed for one she lacks, moves nothing and is not practice: no “toward Tough 0%” for a worker who is Tough. Rules driven by enjoymentAbove (the chance-based ones) keep the message written in their body and show no progress figure, since there is no bar behind them.

The seven shipped files are the working example: resources/jobs/{farmer,shepherd,rancher,beastcapture,farm_marketer,farm_manager,farm_researcher}/gains.xml.

  • 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.