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