Jobs cookbook
Three recipes covering the most common job shapes. Each one is drawn directly from shipped game data so you can compare against the real files under resources/Jobs/.
For the complete schema (every attribute, every element), see reference/jobs-reference.md.
Recipe 1: Pure-effect job (no gold, no performance)
Section titled “Recipe 1: Pure-effect job (no gold, no performance)”When to use this shape: rest jobs, household chores, training sessions. The girl does something useful each shift but earns no gold and has no performance score. The shift summary shows a single flat message.
Exemplar: resources/Jobs/houserest/
This job has only three files:
houserest/ job.xml effects.xml messages/work.xml text/en.xmljob.xml
Section titled “job.xml”<?xml version="1.0" encoding="UTF-8"?><Job id="houserest" schema="1"> <Title>House Rest</Title> <Description>She relaxes at home, recovering energy and health.</Description> <DefaultImage>profile</DefaultImage></Job>No <Eligibility> block means any girl can be assigned. No performance.xml or wage.xml means no gold is paid.
effects.xml
Section titled “effects.xml”<?xml version="1.0" encoding="UTF-8"?><Effects> <SetStat target="self" stat="Tiredness" delta="-25"/> <SetStat target="self" stat="Happiness" delta="10"/> <SetStat target="self" stat="Health" delta="15"/> <SetStat target="self" stat="Mana" delta="10"/></Effects>Applied unconditionally every shift. Negative delta decreases the stat; positive increases it.
messages/work.xml
Section titled “messages/work.xml”<?xml version="1.0" encoding="UTF-8"?><Bank id="work"> <Text id="houserest.work.default" weight="1"/></Bank>One entry, no <When>, always fires. The content is in text/en.xml.
text/en.xml
Section titled “text/en.xml”<?xml version="1.0" encoding="UTF-8"?><Locale lang="en"> <Text id="houserest.work.default">She relaxed at home and recovered her energy.</Text></Locale>That is the entire job. No performance curve, no wage, no gains file needed.
Recipe 2: Performance + wage job
Section titled “Recipe 2: Performance + wage job”When to use this shape: any job where the girl earns gold and better stats produce a better result. The engine computes a performance score from her stats and skills, maps it to a gold amount via a curve, then picks a shift message that matches her tier.
Exemplar: resources/Jobs/barmaid/
This job uses all six files:
barmaid/ job.xml performance.xml wage.xml gains.xml effects.xml (not present for barmaid, but common) messages/work.xml text/en.xmlThe pipeline
Section titled “The pipeline”performance.xmlcomputes a score from the girl’s stats and skills.wage.xmlmaps that score to gold.gains.xmldistributes skill XP.messages/work.xmlpicks a message based on the same score.
performance.xml
Section titled “performance.xml”<?xml version="1.0" encoding="UTF-8"?><Performance> <Factor skill="Service" weight="3"/> <Factor stat="Intelligence" weight="3"/> <Factor stat="Charisma" weight="2"/> <Factor skill="Performance" weight="2"/>
<TraitMod trait="Psychic" delta="10"/> <TraitMod trait="Fleet of Foot" delta="10"/> <TraitMod trait="Optimist" delta="5"/> <TraitMod trait="Cum Addict" delta="-5"/></Performance>Each <Factor> multiplies the girl’s value by its weight. The engine sums all factors and divides by the total weight to produce a normalised score. <TraitMod> entries add or subtract flat points if the girl has that trait.
wage.xml
Section titled “wage.xml”<?xml version="1.0" encoding="UTF-8"?><Wage currency="gold"> <Curve type="piecewise"> <Point perf="245" wage="155"/> <Point perf="185" wage="95"/> <Point perf="145" wage="55"/> <Point perf="100" wage="15"/> <Point perf="70" wage="-5"/> <Point perf="0" wage="-15"/> </Curve></Wage>Points must be listed in descending performance order. The engine finds the two breakpoints the girl’s score falls between and interpolates linearly. Negative wages cost the player money (the girl caused more damage than she earned).
gains.xml
Section titled “gains.xml”<?xml version="1.0" encoding="UTF-8"?><Gains xp="15" baseSkill="3"> <Skill name="Service" weight="3"/> <Skill name="Performance" weight="2"/> <Stat name="Charisma" weight="1"/></Gains>15 XP is distributed across the listed entries proportional to their weights. baseSkill="3" adds a flat 3 points on top for each entry.
messages/work.xml (excerpt)
Section titled “messages/work.xml (excerpt)”<?xml version="1.0" encoding="UTF-8"?><Bank id="work"> <Text id="barmaid.work.perfect.1" weight="1"> <When><Performance ge="245"/></When> </Text> <Text id="barmaid.work.perfect.charming" weight="2"> <When> <Performance ge="245"/> <Trait id="Charming"/> </When> </Text> <Text id="barmaid.work.great.1" weight="2"> <When><Performance ge="185" le="244"/></When> </Text> <Text id="barmaid.work.good.1" weight="3"> <When><Performance ge="145" le="184"/></When> </Text> <Text id="barmaid.work.worst.1" weight="1"> <When><Performance le="69"/></When> </Text></Bank>Notice barmaid.work.perfect.charming: it has higher weight (2 vs 1) so it fires more often for charming girls at the top tier. Multiple entries can match the same shift; the engine picks one proportionally by weight.
Recipe 3: Parameterized multi-slot job
Section titled “Recipe 3: Parameterized multi-slot job”When to use this shape: several job slots that differ only in one dimension, so you want to avoid duplicating most of the XML. One data directory registers under multiple job IDs, each with a different parameter value. <JobParam> conditions in effects.xml and messages/work.xml gate which blocks fire for which slot.
Exemplar: resources/Jobs/houseso/
Three job slots (Straight Training, Bisexual Training, Lesbian Training) all share one houseso/ directory. They are registered in engine code with orientation=straight, orientation=bi, and orientation=lesbian respectively.
job.xml
Section titled “job.xml”<?xml version="1.0" encoding="UTF-8"?><Job id="houseso" schema="1"> <Title>Sexual Orientation Training</Title> <Description>She undergoes orientation training. The exact effect depends on the orientation parameter set when the job is registered.</Description> <DefaultImage>profile</DefaultImage></Job>effects.xml (abridged)
Section titled “effects.xml (abridged)”<?xml version="1.0" encoding="UTF-8"?><Effects> <Group> <When> <JobParam name="orientation" value="straight"/> </When> <SetSkill target="self" skill="NormalSex" delta_min="2" delta_max="4"/> <SetSkill target="self" skill="Anal" delta_min="1" delta_max="2"/> <SetSkill target="self" skill="Lesbian" delta_min="-1" delta_max="-3"/> <SetStat target="self" stat="Tiredness" delta="5"/> <SetStat target="self" stat="Exp" delta="2"/> </Group> <Group> <When> <JobParam name="orientation" value="bi"/> </When> <SetSkill target="self" skill="NormalSex" delta_min="1" delta_max="2"/> <SetSkill target="self" skill="Lesbian" delta_min="1" delta_max="2"/> <SetSkill target="self" skill="Group" delta_min="2" delta_max="4"/> <SetStat target="self" stat="Tiredness" delta="5"/> <SetStat target="self" stat="Exp" delta="2"/> </Group> <Group> <When> <JobParam name="orientation" value="lesbian"/> </When> <SetSkill target="self" skill="Lesbian" delta_min="2" delta_max="4"/> <SetSkill target="self" skill="NormalSex" delta_min="-3" delta_max="-1"/> <SetSkill target="self" skill="Anal" delta_min="-1" delta_max="0"/> <SetStat target="self" stat="Tiredness" delta="5"/> <SetStat target="self" stat="Exp" delta="2"/> </Group></Effects>Only the group whose <JobParam> matches the slot’s registered parameter will fire. The other two groups are skipped entirely.
messages/work.xml
Section titled “messages/work.xml”<?xml version="1.0" encoding="UTF-8"?><Bank id="work"> <Text id="houseso.work.straight" weight="1"> <When> <JobParam name="orientation" value="straight"/> </When> </Text> <Text id="houseso.work.bi" weight="1"> <When> <JobParam name="orientation" value="bi"/> </When> </Text> <Text id="houseso.work.lesbian" weight="1"> <When> <JobParam name="orientation" value="lesbian"/> </When> </Text></Bank>Each slot sees exactly one eligible message because only one <JobParam> condition matches per run.
text/en.xml
Section titled “text/en.xml”<?xml version="1.0" encoding="UTF-8"?><Locale lang="en"> <Text id="houseso.work.straight">She underwent straight orientation training.</Text> <Text id="houseso.work.bi">She underwent bisexual orientation training.</Text> <Text id="houseso.work.lesbian">She underwent lesbian orientation training.</Text></Locale>The parameter pattern works for any dimension where two or three slots share most of their logic. If the slots differ in more than one dimension, or have very different effect lists, separate directories are cleaner.
See also
Section titled “See also”reference/jobs-reference.md: full attribute and element referencesnippets/effects.xml: copy-paste starter for common effect patternsreference/when-conditions.md: full<When>condition language