Gameplay content

Sex scenes

Starting a sex scene from a script, filtering its animations, what it changes afterwards, and the narration and dirty-talk banks.

A sex scene is an interactive session: the player picks positions from the animations that fit the participants, and the scene script waits until they finish. Everything around it (who, where, what happens afterwards) is written in the calling scene.

Starting one

luaGame:moveTo("home")
Player:strip()
Actor:strip()
Game:Sex(Player, Actor)
-- the script continues here after the player finishes
Game:Narrate("…")
  • Game:Sex(a, b, …) takes up to six people. Order matters in group scenes: it decides who takes which role in the animations.
  • Game:SexNoAffair(…) is the same without the affair check, for scenes where the partner knows and approves.
  • Game:Filter("Oral") limits the next sex scene to animations with that tag (up to three tags). It is cleared once that scene starts.
  • Game:TalkNonConsensual(forcer) switches the dirty-talk bank to non-consensual lines for the next scene. Name the person forcing it: the scene is then recorded as a sexual assault by them on the others (Witnesses), which the engine cannot tell from the order of Sex()'s arguments. Without an argument, nothing is recorded.
  • Game:AnimatePair(a, b, "Kissing") plays a paired animation without starting a session (a kiss, a hug).

Clothes and what can play

Nobody undresses before the session any more: the half circle over the couple (a left click on the scene) has one Clothes petal per participant, with every move the player can make on what they wear, in the order it sits on the body:

  • Take off any garment.
  • Rip a top, bottom or underwear: the garment is torn open for good (the wardrobe's Ripped wear, it stays ripped after the scene). Tearing trousers open drags the panty under them aside.
  • Hike up / Let down a skirt or dress. A garment with a Lifted key in its Worn cut group uses it; one without uses its shortest Length (or Hem) cut while lifted and goes back to the cut it wore afterwards.
  • Push aside, lower a little, pull to mid-thigh / the knees / the ankles (one leg or both): every state the garment has, from its Worn keys and its StateOf garments (Clothing). Underwear is only reachable once what covers it is off, ripped or hiked up: with the trousers on, the panty stays where it is.

Nothing is offered on a minor. The states (aside, lowered, lifted) go back to normal when the session ends, before the original outfit is put back on.

What a position needs of each body is mod data, Anims/SceneAccess.json, by tag:

json"tags": {
  "Blowjob":     [ { "who": "male", "part": "genitals" }, { "who": "all", "part": "mouth" } ],
  "Cunnilingus": [ { "who": "female", "part": "genitals" }, { "who": "all", "part": "mouth" } ],
  "Vaginal":     [ { "who": "all", "part": "genitals" } ],
  "Kissing":     []
}

who is male, female or all; part is genitals, mouth or breasts. A position's needs are the union over its tags; a tag with an empty list needs nothing, so a position tagged only Kissing or Foreplay plays dressed. A position none of whose tags are listed needs everyone's genitals. A later mod's tag replaces the list whole.

A body part is reachable when: genitals -- no chastity belt, the bottom slot empty, ripped or hiked up, and the underwear under it off, ripped, pushed aside or pulled down past the thighs (a man's underwear too; "lowered a little" still covers); mouth -- no gag (a ring gag is the GagOpen slot and leaves it free); breasts -- the top off or ripped and the bra off, ripped or pushed aside. The pose list only shows what can play; when nothing can, the panel says why ("Anna's jeans are in the way") and the half circle opens by itself.

Out cold

A participant who is unconscious when the scene starts (Actor:knockOut: drugged, strangled, beaten; or passed out from the scene's own pain) is taken as they are: forced, resistance and pain at their maximum, in the positions that need nothing of them. The player can be that participant: Player:knockOut("drugged") works like anyone else's since the sedative scenes needed it (the scene that puts them under wakes them with Player:wakeUp(), or the clock does).

While the player is out cold the session offers nothing to choose: the other person leads outright (their proposals apply without a yes or no), picking positions from their likes_* stats and the pace from likes_rough, pushed harder by their cruelty and dominance facets, held slower by affection, and changing position more often with kink and libido. The rail shows Skip: the scene runs to the partner's climax at once, every consequence included (pregnancy, STDs, pain, the record of a sexual assault when the scene named who forced it), then ends. Not skipping means watching.

luaGame:TalkNonConsensual(Actor)
Player:knockOut("drugged")
Game:Sex(Actor, Player)
Player:wakeUp()

What happens afterwards

When the session ends, the game applies the consequences, for every pair of participants:

  • Affairs: if the player has a partner or spouse who is not in the scene, the other participants become the player's affairs. SexNoAffair skips this.
  • Virginity: not everyone is a virgin. The first time a person's virginity is asked about, it is rolled once and kept: the player never is by default; anyone with a sex history, a prostitute, or someone married, dating or with children never is; anyone else is a virgin if random(0, 500) < 250 - (perversion + age mapped 18..40 to 0..200). Actor:setVirgin() makes someone a virgin. The first vaginal scene with a virgin (scenes whose name contains fantasize excepted) records who took it (isDeflowerer(), isDeflowered()) and posts a "Virginity Lost!" note.
  • Pregnancy: a fertility roll where the anatomy allows it, unless the scene called Game:setUsingCondom(true) or Game:blockPregnancy() (see Pregnancy).
  • STDs: a roll that can queue the contract_STD consequence scene (Game:hasSTD()).
  • Partners and attraction: the partner list behind Actor:hadSex() and the attraction stats are updated.
  • Pain: a share of the worst pain the scene caused (after_scene below) is added to each participant's pain stat, which heals overnight.
  • Witnesses: incest between relatives, an affair (someone with a partner who is not in the scene) and a named forcer's assault are recorded as acts, and whoever was close enough may have seen or heard (Witnesses). Ordinary sex between people free to have it is not recorded.

A body that already hurts

Someone who comes into a scene in pain (a lasting condition, an injury) brings it with them. The numbers are in ul_Base/Anims/EnergyOrgasm.json, block pain:

  • body_start (0.5): the scene's own pain starts at that share of their pain stat and never calms below it;
  • body_arousal_damp (0.5): arousal builds that much slower at pain 100;
  • after_scene (0.25): the share of the scene's worst pain, above the start, left on the stat afterwards.

A condition's sex_avoid tags take positions out of the scene for everyone in it while its holder takes part (tags describe a position, not a role, so a bad knee keeps everyone off their knees).

Useful calls

Call Effect
Game:setUsingCondom(true), Game:isUsingCondom() Condom for this scene
Game:blockPregnancy() No pregnancy from any sex in this scene
Game:isSexSceneActive() Whether a session is running
Actor:setForcedParticipant(true) Mark a participant as non-consenting (tags the scene Aggressive)
Actor:getTagIfRape() The tag to filter on for such a scene
Actor:isDominantSex(other) Who leads by the legacy rules (gender, anatomy, then the masochist stat)

The lower-level pieces (startSexScene, selectSexAnimation, playSexAnimation, camera controls…) are listed in the Game reference for mods that build their own flow.

Pregnancy

Call Effect
Actor:isPregnant(), Actor:getBabyDaddy(), Actor:countPregnancyDays() State
Actor:impregnate(), Actor:endPregnancy() Force or end a pregnancy
Actor:setWantsBabies(true), Actor:wantsBabies() Their wish
Actor:getPregnancyTag() How it started (consensual or not)

A pregnancy lasts 280 days, as in the original game. The belly grows from day one, following the morph weights in Modules/Pregnancy_Morphs.txt scaled by days / 280. The engine counts the days and hands the story to scenes; it never writes the birth itself:

When Scene queued Notes
The player, on a day rolled between 15 and 45 player_discovers_pregnancy Once per pregnancy
The player reaches day 280 player_gives_birth The scene creates the child and calls Player:endPregnancy()
An NPC the player fathered reaches day 280 NPC_gives_birth getSpecific("Impregnated") is that mother while the scene runs
Any other NPC reaches day 280 NPC_gives_birth_neutral Same

Replace any of these scenes by shipping a scene with the same name. If no mod has the scene, or the scene never calls endPregnancy() within three days, the engine gives birth itself: it creates a child that blends both parents' looks and links it to them.

The cycle: fertility_cycle

The conception roll multiplies each body's fertility by its fertility_cycle stat divided by 100, when any enabled mod defines that stat (Stats/*.ulstat). Without such a stat the factor is 1 and conception is exactly as before. ul_Cycle writes it every day from the woman's menstrual cycle: 0 while bleeding, pregnant, before her first period or after her last; up to 500 at ovulation; 5 in the second half of the month. It applies to the player's scenes and to NPC couples off screen, so a one-night stand conceives by her month, not by a flat chance. The pill's buff on fertility still applies on top.

A mod that needs the month itself reads cycle_day (1 is the first day of bleeding, 0 no cycle) and cycle_phase (1 period, 2 follicular, 3 fertile window, 4 luteal) in an action's CONDITIONS, or asks Cycle.onPeriod(p), Cycle.phase(p), Cycle.late(p) in Lua; Cycle.touch(p) brings an NPC's month up to date before the roll. Period pain is a condition on the shared pain stat (period_light, period_cramps, period_cramps_bad), so a sex scene on a bad first day starts from it like any other ache.

Narration and dirty talk

While a session runs, the game shows narration lines (.uldesc) and dirty talk over the participants' heads (.ultalk). Both are line banks, found anywhere in your mod, that you can extend with your own files.

Format

Entries are separated by a line containing only ##. Each entry is a condition, then indented lines:

textTag(Kissing, Couple)
    <A2.S> pulled <A1.o> closer, and for a while neither of them said anything.
##
*START* Tag(Blowjob)
    ...
    Let me take care of you.
##
Tag(Penetration) && toCum > 70 && A2.isDating()
    ...
    Don't stop… don't you dare stop…
##
  • In a .uldesc entry there is one line: the narration.
  • In a .ultalk entry there is one line per participant, in order; ... means that person stays silent.
  • *START* restricts an entry to the moment a position begins, *END* to the climax.
  • A line starting with # (hash, space) is a comment, for a file header. A line of only ## is still the separator.

Conditions

Piece Meaning
Tag(A, B) The current animation has all these tags
toCum < 50 How close the speaker is to climax, 0–100
A1.isDating() A predicate on participant 1, 2…: isPlayer, isMale, isFemale, isDating, hasRelationship(Spouses, …), isPregnant, isVirgin, wantsBabies
A2:perversion < 50 A participant's stat
A1:pace, A1:like, A1:resistance, A1:pain Scene state: pace error (0 = right, above 0 too fast), how much they like the pose, resistance and pain (0–100)
A2:unconscious > 0 1 while that participant is passed out, else 0
IsIncest() A scene-level check
!, &&, ||, [ … ] Not, and, or, grouping (&& binds tighter than ||)

A condition that fails to parse is treated as false and logged once.

While someone is unconscious, only entries whose condition reads :unconscious are picked, in every bank. Ordinary lines describe a partner who looks up, answers, kneels; they would be wrong over a limp body. ul_Base/DirtyTalks/unconscious.ultalk and ul_Base/Descriptions/unconscious.uldesc hold the base lines; your mod adds its own the same way, e.g. A2:unconscious > 0 && A1:unconscious < 1.

Tokens

<A1.token>, <A2.token>… insert a participant's name or pronoun, with the same tokens as GetToken: <A1.name>, <A2.s>, <A1.his_or_her>, <A2.man_or_woman>. <we_or_they> and <our_or_their> refer to the couple from the player's point of view.

Tags

The tags come from the animations (see Animations). Common ones: Couple, NonSexual, Foreplay, Kissing, Hugging, Oral, Blowjob, Licking, Penetration, Vaginal, Anal, Standing, Aggressive.