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 ofSex()'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
Rippedwear, 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
Liftedkey in itsWorncut group uses it; one without uses its shortestLength(orHem) 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
Wornkeys and itsStateOfgarments (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.
SexNoAffairskips 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 containsfantasizeexcepted) 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)orGame:blockPregnancy()(see Pregnancy). - STDs: a roll that can queue the
contract_STDconsequence 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_scenebelow) is added to each participant'spainstat, 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 theirpainstat and never calms below it;body_arousal_damp(0.5): arousal builds that much slower atpain100;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
.uldescentry there is one line: the narration. - In a
.ultalkentry 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.