Writing AIF using sex.t
Copyright 2000 by Sir Gareth
sirgareth99@yahoo.com

This is a short guide to a set of libraries for writing adult interactive fiction.  Since it covers only the highlights, you should also take a look at the example scenario, test.t that I've included with the libraries to get a sense for how the libraries work in practice.

*** Part 1:  Overview of the main libraries and templates ***

  sex.t.  This is the main library and handles actors, body parts, toys, etc.  Its basic structure is similar to MMX, but it has some extra features allowing a greater variety of acitivty on the part of NPCs.  The main addition is that when one actor performs a sex action on another character, she is assigned that other character as her "partner."  In future turns, the actor can continue interacting with the same partner.

  xclothing.t.  Handles layered clothing.  See Part 3, below.

  bed.t.  Allows the player amd NPCS to get into various positions on beds and chairs.  This library isn't dependent on the other libraries, so it could be used with other libraries, like MMX.

  pronoun.t.  This library corrects pronoun problems to make sure you get grammatically correct messages when NPCs are performing actions.  For example, it avoids messages like "Laurie can't reach yourself from the bed" or "Laurie touches Laurie's breast." It also runs independently of the other libraries.

  aactor.t.  This optional library contains miscellaneous functions to allow more types of interactions with actors.  Sex.t can be used without this library, although the templates require it.

  maleme.t  Template for a male player character.

  femaleme.t  Template for a female player character.

  easygirl.t  Template for a basic female NPC.

  easyguy.t  Template for a basic male NPC.

  easytest.t  Very basic sample game with a male player and female NPC.

  fmtest.t  Very basic sample game with a female player a male NPC.

*** Part 2:  Using the templates ***

The templates provided make it very easy to implement a basic male or female character.  The templates are in fill-in-the-blanks form, so you will need to add a lot of stuff to flesh out the character.  The templates should be pretty self-explanatory, but here are some of the highlight.  See the source code for the sample game "McBeal" for examples of fully-written characters.

I.  The character's name.

You can so a find-and-replace to change the name from the "generic" name included in the template to your character's name.  For example, if your character will be named "Buffy," do a global find-and-replace, replacing "Jane" with "Buffy."

II.  ldesc

A good long description of each NPC is very important.  The templates provide a very basic generic description template, which you will need to customize for each character.  Sex.t provides several variables and methods to allow you to tailor an actor's ldesc to her current situation:

  xActor.position = the actor's current position (e.g., 'sitting')
  xActor.clothinglist = list of the actor's visible clothing
  xActor.partner = the person, if any, the actor is currently fooling around with;
  bodyPart.cover = the outermost article of clothing, if any, covering a bodyPart
  xActor.arousal = the actor's current arousal level, from 0 to 100+.

III.  Conversation

The templates include four possible responses that an xActor can give when the player tries something on her or asks her to do something:

  xActor.refusal = the actor is unwilling to perform the action requested
  xActor.stopit = the actor doesn't want the player to do something to her
  xActor.notyet = the actor  is not sufficiently aroused to let the player do something to her
  xActor.nothere = the location is not sufficiently private for the actor to perform or allow an action.

They also include space for you to fill in the actor's responses when the player ASKs or TELLs her about something, or tries to GIVE or SHOW her something.  You should make sure that you provide responses to anything the character might reasonably know about.

IV  Actor daemons

Daemons are methods that are automatically run each turn.  They can be used to allow a character to initiate actions, move around, etc.  Here are the main ones included in the templates:

   xActor.moveDaemon (makes the actor move if, for example, the actor is following the player or moving along a track)
   xActor.makeloveto(actor.partner) (actor performs an appropriate action on her partner if she has one)
   xActor.otheraction (used for "atmosphere" message in the event actor has no partner and can be seen by the player)

You can write whatever custom code you want as part of these methods, and it will be executed each round.

V  Bodypart

The templates include a bunch of pre-defined bodyparts for each character.  For each bodypart, you need to fill in:

  V.A  Descriptions

  V.B  Sexual interaction messages

   

VI.  Clothing

Finally, you need to define the clothing you want your NPC to wear.  The templates include basic clothing, and its easy to define other articles of clothing yourself (see Part 3 and Appendix 2, below).  For each piece of clothing, you need to customize:

  VI.A  Clothing descriptions

  VI.B  On/off messages

  VI.C  Fastening/unfastening


*** Part 3: [Advanced] Creating layered clothing using xclothing  ***

I. Properties of the class xClothing

Following is a list of the main properties that need to be defined for each article of xClothing:
size =     A number representing the size of the article of clothing.
           an actor can wear an article of clothing only if the size
           of the clothing is the same as the size of the actor.  By
           default, all actors and all pieces of clothing have size=0.
layer =    A number representing the layer that the article is part of.
           Layers range from 0 (innermost layer) up to about 4 or so.
           Here is a typical list of the layers that various numbers
           represent:
           0 = items worn directly on the skin (e.g., earrings)
           1 = underwear (e.g., undershorts, bra, etc.)
           2 = mid-layer (e.g. shirt, pants, etc.)
           3 = outer layer (e.g. sweater)
           4 = outermost layer (e.g. coat)
coverlist= A list containing the bodyAreas that the article of clothing
           covers when worn.  See the xClothing file for a list of
           bodyAreas.
isworn =   Set to true when item is being worn
istransparent =
           Set to true if the item is see-through.
isopen =   If this property is set to true, the article is worn
           without covering the areas in its coverlist.  This property
           is used for the various classes of openableClothing.  By
           default, isopen is reset to nil when the article is removed.
alwaysopen=If this property is set to true, the property isopen is
           not reset to nil when the article is removed.

II. Articles of clothing

  II.A. Creating an article of clothing

xClothing includes default definitions for a variety of different clothing types.  If you use one of these default definitions, the only properties you will need to define are location, isworn, and layer.

xClothing includes a default ldesc for an article of clothing.  If the article is being worn, it will print <article>.worndesc.  If the article is not being worn, it will print <article>.notworndesc.

Here is a simple example:

myshirt: longshirtClothing
  location = Me
  size = 10 \* must be equal to Me.size *\
  isworn = true
  noun = 'shirt'
  sdesc = "shirt"
  worndesc = "You are wearing the shirt."
  notworndesc = "The shirt is lying in a heap on the floor."
;

  II.B. Creating an article of openable clothing 

xClothing defines certain classes of clothing that can be lifted, lowered, unbuttoned, etc.  You can define some additional messages and descriptions that are displayed when the article is opened and closed.  For example, if you wanted to allow the player to unbutton his shirt, you could modify the above definition as follows:

myshirt: longshirtClothing, unfastenableClothing
  location = Me
  size = 10 \* must be equal to Me.size *\
  isworn = true
  noun = 'shirt'
  sdesc = "shirt"
  isopen = nil
  worndesc = "You are wearing the shirt, which is buttoned up."
  notworndesc = "The shirt is lying in a heap on the floor."
  opendesc = "The shirt is unbuttoned, exposing your hairy chest. "
  openedmsg(actor,wearer) = "You unbutton your shirt, exposing your hairy chest."
  closedmsg(actor,wearer) = "You button your shirt back up."
;

  II.C. Creating a custom class of clothing

If you want to have an article of clothing for which no default definition is provided, you can create a new class of clothing by assigning appropriate values to layer and coverlist.  For example,

class suitClothing: xClothing
  layer = 3
  coverlist = [chestArea backArea waistArea armsArea legsArea crotchArea]
;

III. Body parts

  III.A. Creating a new bodyArea

Suppose that you want to create a class of clothing that is worn on some area that is not already definind as a bodyArea.  You can simply define a new bodyArea and add it to the coverlist for the clothing you're creating.  For example:

class kneeArea: bodyArea
;

class kneepads: xClothing
  layer = 1
  coverlist = [kneeArea]
;

Note that if you wanted the player to be able to wear trousers over the kneepads, you would need to add kneeArea to the coverlist for the trousers.

  III.B. Creating a bodypart

An actor can have body parts, which should be definined as bodyAreas.  For example,

mychest: chestArea
  location = Me
  noun = 'chest'
  adjective = 'my'
  sdesc = "chest"
;

Since mychest has been defined as a chestArea, xClothing will automatically determine that it is covered when the player is wearing, for example, a shirt.  If the player attempts to intereact with his chest while wearing a shirt, he will get the message "I don't see any chest here."

  III.C. Testing whether a body part is covered by clothing

The method <bodyArea>.cover returns the outermost layer of clothing covering <bodyArea>.  So, for example, if the player was wearing myshirt, mychest.cover would return myshirt.  This provides an easy way for the programmer to determine whether a bodypart is covered by clothing.

IV. Automatic dressing and undressing

xClothing provides two additional verbs, dressVerb and undressVerb, that enable an actor to put on or take off all of his clothing at once.  To be able to use undressVerb, <actor> must have <actor>.willundress set to true.  To be able to use dressVerb, <actor>.coverlist must be set to the list of clothing that <actor> will put on when dressing.

*** Part 4: [Advanced] Appendices ***

Appendix 1:  list of bodyArea classes included in xClothing

faceArea
headArea
neckArea
chestArea
backArea
armsArea
wristArea
handsArea
waistArea
crotchArea
legsArea
ankleArea
feetArea

Appendix 2:  list of clothing classes included in xClothing

pantyClothing
braClothing
teddyClothing
shortsClothing
pantsClothing
skirtClothing
miniskirtClothing
shirtClothing
longshirtClothing
dressClothing
minidressClothing
robeClothing
coatClothing

Appendix 3:  Steps in a sex action called by sex.t

Following is a list, in outline form, of the steps that sex.t goes through when one actor performs a sexual action on another.  This will help give you an idea of what the various variables do.  This example assumes that the player has typed "Sarah, lick Laurie's breast," and that Laurie's breast is the object lauriesbreast.

1. Call lauriesbreast.verDoLick(Sarah)
a. Check that lauriesbreast.cover = nil (i.e., no clothes are covering Laurie's breasts);
b. Check that Laurie is in Sarah.loverlist (i.e., Sarah is interested in Laurie);
c. Check that Sarah.arousal >= Sarah.minlickarouse (i.e. Sarah is aroused enough to be willing to perform this action);
d. Check that room.isprivate(Sarah) = true (i.e., the location is sufficiently private for Sarah to do this);
e. Check to make sure Sarah is in Laurie.loverlist (i.e., Laurie is interested in Sarah);
f. Check to make sure Laurie.arousal >= lauriesbreast.minlickarouse (i.e., Laurie is sufficiently aroused to allow this)
g. Make sure that room.isprivate(Laurie) = true (i.e., the location is sufficiently private for Laurie to do this);
2. Call lauriesbreast.doLick(Sarah)
a. Call Sarah.engage(Laurie) (make Laurie and Sarah partners)
b. Call Laurie.join(Sarah) (move Sarah to same location and position as Laurie)
c. Print lauriesbreast.lickedmsg(Sarah) (print appropriate text describing what happens)
d. Increment Sarah's arousal by Sarah.lickarouse;
e. Increment Laurie's arousal by lauriesbreast.lickarouse;
f. Set Sarah.sexact to lickVerb and Sarah.sexdo to lauriesbreast
g. call lauriesbreast.finishlick(Sarah) (any custom code the game designer wants to add here; by default this is blank);
h. Call Laurie.checkorgasm (check to see if Laurie has an orgasm).


