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.
How progress works
Section titled “How progress works”Each qualifying shift accumulates progress toward (or away from) the trait:
- Gain: progress increases by
amounteach shift. The trait is granted when progress reachesthreshold. Progress resets after the trait fires. - Lose: progress increases by
amounteach shift. The trait is removed when progress reachesthreshold. 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
Toughadds 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.
minShiftscounts shifts she has worked in that job. Only jobs that have aminShiftsrule 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 reference
Section titled “Attribute reference”<GainTrait>
Section titled “<GainTrait>”| 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. |
<LoseTrait>
Section titled “<LoseTrait>”| 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.
Examples
Section titled “Examples”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).
Easy trait – arrives in 3-4 shifts
Section titled “Easy trait – arrives in 3-4 shifts”<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.
Gated by a condition
Section titled “Gated by a condition”<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.
Scaling progress with performance
Section titled “Scaling progress with performance”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 fullamount.
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.
Tenure floors
Section titled “Tenure floors”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.
Notes for authors
Section titled “Notes for authors”- Progress is per-trait per-girl. Switching a girl to a different job pauses accumulation.
- The visible bar has 10 cells, so
thresholdvalues 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 samegains.xml– each tracks its own progress independently.