Character Attributes
Tailraise has several attributes in the game that each NPC can have set, which can be then used with the Tailraise Parser or with different Game Functions in order to change outcomes, dynamically change text that appears based on the player's current look, or change how a scene plays out based on their anatomy, etc.
Bools, Strings, and Integers
In order to understand this system better, you will need to know these terms and how they are used in Tailraise.
Bools
This is basically just a true or false.
For example, we have a bool
named isBald
. If this is checked in Unity, it means the player has no hair and is bald.
Behind the scenes, in your save file, you would see this as:
isBald = false
These are primarily used in conditional checks in a scene, where if the statement is true, we display the text. If it's not true, it never shows.
For example, we might have:
<<if_pc_isBald>>You reach up and gently stroke the top of your bald head.<</if_pc_isBald>>
<<!if_pc_isBald>>You reach up and gently run your fingers through your hair.<</if_pc_isBald>>
This means the first statement shows if isBald
is true
. So, if you are bald, you see the first one.
The second one is hard to see the difference. The !
at the start of it denotes the opposite should apply. So, normally, we are looking for isBald = true
. In this case, we are now looking for isBald = false
. If this matches, we show the second sentence instead.
For any bool, you can utilize the conditional text system this way.
Strings
This just means "string of text", for example, eyeColor = "blue"
. "blue"
is the string.
Strings are primarily used in the Dynamic Text Replacement System.
An example would be when you want to pull the NPC's eye colour, like above. We do not know what the player might set their eye colour to, so we need to use this system to retrieve this in our writing:
You open your [[pc.eyeColor]] eyes slowly and let out a yawn.
If the player has eyeColor = "blue"
this would then become:
You open your blue eyes slowly and let out a yawn.
Any attribute that is a string is able to be used in this way. Some of these are also used in Helper Systems.
Integers
Commonly just called int
. These are whole numbers (no decimals!). We use these for things like the game time (in minutes) to determine when a player should be allowed to unlock their cage, pick up their clothes, and more. Some of these are used for sizeLevel
type variables to use a list to determine which size adjective to use.
We don't typically use these in most systems, as they are used by the conditional text system, dynamic text replacement system, and helper systems.
Helper Systems
We have several helper systems in the game which use adjectives, size levels, and more to create descriptions or figure out other variables.
The below helper systems might not reflect the current game versions and should just be used as examples. If they have changed, Taw will adjust them accordingly in your writing for any submissions.
If you need something added, please talk to Taw.
skinOrFur
One of those most common ones you'll probably need is determining if the user has skin, fur, scales, feathers, and so on.
To use this in your writing, simply use [[pc.skinOrFur]]
You can also replace pc
with an NPC's ID, such as [[flint.skinOrFur]]
.
This is set up using the following code
private string GetSkinOrFur() => species switch
{
"fox" => "fur",
"wolf" => "fur",
"rabbit" => "fur",
"horse" => "fur",
"cat" => "fur",
"human" => "skin",
"dragon" => "scales",
"avian" => "feathers",
"kobold" => "scales",
_ => skinType
};
If the species is not listed, it defaults to using the player's skinType
field, which usually lists fur, skin, scales, etc.
pupName
When you want to have an NPC call the player by a pet/pup name, please use [[pc.pupName]]
.
Please use this instead of hard coding it in, unless it makes sense in a scene, such as kitten play vs puppy play vs horse play.
private string GetPupName() => species switch
{
"fox" => "pup",
"wolf" => "pup",
"dog" => "pup",
"cat" => "kitty",
"rabbit" => "bun",
"horse" => "colt",
"deer" => "fawn",
"bat" => "pup",
_ => "toy"
};
If the species cannot be found, such as human in this case, it defaults to using "toy" as the pup name.
nose
You can pull the literal string of the player's nose using [[pc.noseType]]
but you are also able to use this command, [[pc.nose]]
for one based off their species.
private string GetNose() => species switch
{
"fox" => "muzzle",
"wolf" => "snout",
"rabbit" => "snout",
"horse" => "muzzle",
"cat" => "snout",
_ => noseType
};
hand
The player's handType
string is usually plural, so this is best used when you need the singular version of their hand, based on their species.
You can use this in writing by using [[pc.hand]]
private string GetHand() => species switch
{
"fox" => "paw",
"wolf" => "paw",
"rabbit" => "hand",
"horse" => "hand",
"cat" => "paw",
"human" => "hand",
_ => handType
};
furSummary
This one puts together a very simple description using furColor
plus skinType
.
You use this in writing by using [[pc.furSummary]]
.
private string GetFurSummary() => $"{furColor} {skinType}";
Examples that it might return:
furColor = "red"
skinType = "fur"
red fur
furColor = "white"
skinType = "scales"
white scales
furColor = "blue and orange striped"
skinType = skin"
blue and orange striped skin
heightDescription
This will return a few difference variables based on how big or small the player's height is.
You can use this by writing [[pc.heightDescription]]
.
private string GetHeightDescription() => height switch
{
<= 130 => "tiny",
<= 150 => "short",
<= 170 => "average",
<= 190 => "tall",
> 190 => "towering"
};
If the player was 155 cm
tall, this would return short
because it's above 150 but less than 170.
hairDescription
This one will return a few things based on if the player is bald or not.
If they are bald, it will use their species to determine what to put.
If they have hair, it will use their hairLength
, hairColor
, and GetHairType
helper to get their hair.
To use this, you would write [[pc.hairDescription]]
.
private string GetHairDescription()
{
if (isBald)
{
return species switch
{
"human" => "smooth scalp",
"lizard" => "bare, scaled head",
"dragon" => "scaly head",
"cat" => "short fur",
"fox" => "soft fur",
"wolf" => "thick fur",
_ => $"{GetSkinOrFur()}-covered head"
};
}
return $"{hairLength}, {hairColor} {GetHairType()}";
}
and
private string GetHairType() => species switch
{
"lizard" => "scales",
"dragon" => "scales",
"cat" => "fur",
"fox" => "fur",
"wolf" => "fur",
_ => "hair"
};
So if the player is has isBald = true
and species = "wolf"
, this returns thick fur
.
If the player is a fox, their hairColor = "white"
, and their hairLength = "short"
this then returns short, white fur
.
tailLength
Tails use an int
in order to set their length, and we use this to determine the description.
To use this, you would write [[pc.tailLength]]
.
private string GetTailLengthDescription() => tailLengthLevel switch
{
0 => "lack of",
1 => "short",
2 => "medium-length",
3 => "long",
4 => "luxurious",
_ => "unknown"
};
If the player has tailLengthLevel = 3
, then it would return long
.
You still need to write "tail", or "appendage" or whatever else after.
dickDescription
We use a combination of two helpers to determine this based on the player's dickType
and dickSizeLevel
.
To use this, you would write [[pc.dickDescription]]
.
private string GetDickSizeDescription()
{
string adjective = GetDickSizeAdjective();
return string.IsNullOrEmpty(adjective) ? dickType : $"{adjective} {dickType}";
}
private string GetDickSizeAdjective() => dickSizeLevel switch
{
<= 0 => "tiny",
1 => "small",
2 => "", // Average sized, no descriptor
3 => "large",
4 => "huge",
5 => "monstrous",
_ => "unknown"
};
If the player has dickType = "canine"
and dickSizeLevel = 3
, then this would return large canine
.
If the player has dickType = "feline"
and dickSizeLevel = 2"
, then this returns just feline
.
This does NOT add on "cock", "dick", "shaft", etc. afterward so you can fill this in yourself after.
knotDescription
This one just simply uses the knotSizeLevel
to determine what to return.
To use this, you would write [[pc.knotDescription]]
.
private string GetKnotSizeDescription() => knotSizeLevel switch
{
<= 0 => "tiny",
1 => "modest",
2 => "thick",
3 => "fat",
4 => "massive",
_ => "unknown"
};
If the player has a knotSizeLevel = 3
, this would return fat
.
This does NOT add on "knot", "bulb", etc. afterward so you can fill this in yourself after.
slitType
This one checks for what type of slit characters with genital slits have, since it might use specific language.
To use this, simply write [[pc.slitType]]
.
private string GetSlitTypeDesc() => slitType switch
{
"vent" => "vent",
"cloaca" => "cloaca",
_ => slitType
};
sheathDescription
This describes a sheath, ending with the word 'sheath', so it's recommended to use this only once during a scene so it doesn't feel repetitive.
To use this, simply write [[pc.sheathDescription]]
.
private string GetSheathDescription() => sheathType switch
{
"plump" => "plump sheath",
"short" => "modest, short sheath",
"thick" => "hefty, prominent sheath",
"soft" => "plush sheath",
_ => "sheath"
};
So if the player has sheathType = short
, this would return modest, short sheath
.
ballsDescription
This describes the balls in a few different ways and might eventually get rewritten. This one hardcodes "balls" or "orbs" into the description so it's recommended to use this only once during a scene so it doesn't feel repetitive.
To use this, simply write [[ballsDescription]]
.
private string GetBallsDescription() => ballsSize switch
{
"small" => "tight, modest balls",
"coinpurse" => "soft, modest balls",
"swollen" => "full, swollen balls",
"heavy" => "heavy, dangling orbs",
_ => "heavy balls"
};
So if the player has ballsSize = "small"
it would return tight, modest balls
.
scentDescription
Every character has scent filled in to some degree, and this will pull the intensity based on what's written in their file. This might expand later to change or offer more dynamic descriptions.
To use this, simply write [[pc.scentDescription]]
.
private string GetScentIntensityDescription() => scentIntensity switch
{
"faint" => "barely noticeable",
"musky" => "noticeably musky",
"pungent" => "strong and overwhelming",
_ => "unremarkable"
};
So if the player has scentIntensity = "musky"
it instead returns noticeably musky
.
This one hasn't been used much and will probably be rewritten, please use sparingly.
List of Attributes
Here is the full list of attributes and what type they are so you can know if you can use it as either conditional text system (bools), dynamic text replacement system (strings), and helper systems (combination of multiple).
This system is constantly evolving and changing as the game is developed. Many of these fields may be repurposed, removed, or modified to better fit the game needs. Some of these may no longer be relevant as other game systems were developed to take their place.
A lot of these were added in as placeholders to be used for future systems and content. Please ask Taw for clarification if you're unsure how to use some of these, in case it's not fully implemented and needs work.
public string name = "Unnamed"; // Character's name, can use [[pc.name]] to pull this
public string species = "human"; // Character's species, many things use this.
public string subspecies = ""; // Subspecies can be added but is currently unused.
public string gender = "male"; // Character's gender, mostly unused to pull but we set this anyways in characters.
public PronounSet pronouns = new(); // This is currently being reworked to be pulled by the system easier.
public int age = 24; // Age if needed, we specify this for all characters.
public string sexuality = "pansexual"; // Character's sexuality
// Stats
public int strength = 3; // For the encounter system, we set these relatively high for NPCs, such as 10
public int dexterity = 3; // For the encounter system, we set these relatively high for NPCs, such as 10
public int intelligence = 3; // For the encounter system, we set these relatively high for NPCs, such as 10
public int charisma = 3; // For the encounter system, we set these relatively high for NPCs, such as 10
// Physical Description
public int height = 165; // This is in centimeters
public string heightLevel = "average"; // String description of their height
public string build = "lean"; // Usually either lean, slender, average, thick, or curvy
public string bodyShape = "slim"; // slim, plump, etc.
public string hipSize = "modest"; // narrow, moderate, modest, wide, etc.
public string buttSize = "plump"; // flat, round, plump
public string bellySize = "flat"; // flat, soft, chubby, large
public string muscleTone = "toned"; // low, toned, athletic, bulky
public string skinType = "skin"; // skin, fur, feathers, scales
public string furColor = "white"; // this describes the skinType's color so make sure this is set
public string eyeColor = "blue"; // If hasHeterochromia = true, this should match leftEyeColor
public string leftEyeColor = "blue"; // For heterochromia, make sure eyeColor matches if true
public string rightEyeColor = "blue"; // For heterochromia
public bool hasHeterochromia = false; // If their eye colours are different
public bool isBald = false; // If they are bald or not
public string hairColor = "black"; // Colour of the hair (if any)
public string hairLength = "short"; // short, medium-length, long
public string hairStyle = "messy"; // messy, trimmed, slicked-back, scruffy, fluffy, etc.
public bool hasTail = false; // true or false
public string tailType = "none"; // canine, feline, etc.
public int tailLengthLevel = 0; // 0 to 4 (lack of, short, medium-length, long, luxurious)
public string earType = "round"; // round, pointy, bat-like, etc.
public string hornType = "none"; // pointed, small, rounded, nub, etc., not really used right now
public string wingType = "none"; // armwings, shoulder, back, etc., not really used right now
public string noseType = "nose"; // nose, snout, etc.
public string handType = "hands"; // hands, paws, talons, claws, etc. ALWAYS plural
public string feetType = "feet"; // feet, footpaws, paws, talons, etc. ALWAYS plural
// Scent
public string scent = "clean"; // How do they smell? clean, lemon-scented, citrus, etc.
public string armpitScent = "neutral"; // neutral, spicy, musky, etc.
public string crotchScent = "neutral"; // neutral, spicy, musky, etc.
public string ballScent = "neutral"; // neutral, spicy, musky, etc.
public string scentIntensity = "mild"; // mild, strong, intense, overwhelming, etc.
// Genitalia & NSFW
public bool hasCock = true; // true or false
public string dickType = "human"; // human, canine, feline, equine, etc.
public string dickSize = "average"; // small, average, huge, etc. dickSizeLevel is mostly used instead of this.
public int dickSizeLevel = 2; // 0 to 5 (tiny, small, average (no descriptior), large, huge, monstrous)
public bool hasKnot = false; // true or false
public int knotSizeLevel = 2; // 0 to 4 (tiny, modest, thick, fat, massive)
public bool hasBarbs = false; // true or false
public bool hasSpines = false; // true or false, these are not the same as barbs
public bool hasRidges = false; // true or false
// Genital Slit
public bool hasSlit = false; // genital slits
public string slitType = "vent"; // vent, cloaca
public string slitAppearance = "neat"; // neat, taut, plump, pouty, hidden
public string slitColor = "flesh"; // if it's a different colour than the skin
// Sheath
public bool hasSheath = false; // true or false
public string sheathType = ""; // plump, short, thick, or soft
public string anusType = "tight"; // puffy, tight, taut, puckered
public bool isPlugged = false; // true or false, this can be set later using functions
public string plugType = "buttplug"; // anything, not used much yet
public string plugSize = "medium"; // anything, not used much yet
// Balls
public bool hasBalls = true; // true or false
public string ballsSize = "average"; // small, coinpurse, swollen, heavy
// Vagina
public bool hasVagina = false; // true or false
public string vaginaType = "none"; // human, feline, canine, etc
public string pussyStyle = "soft"; // soft, taut, etc. anything, not used yet
public int wetnessLevel = 1; // not used yet
public int tightnessLevel = 0; // not used yet
// Breasts
public bool hasBreasts = false; // true or false
public string breastSize = "flat"; // flat, small, average, big
public int breastSizeLevel = 0; // 0 to 5, flat, petite, modest, full, ample, heavy
public string areolaSize = "small"; // small, average, large
public string nipples = "standard"; // sensitive, perky, etc. not used yet
public string nippleSize = "small"; // small, average, large
// Anal Stuff (not used yet so don't worry about setting these)
public int analTightnessLevel = 3; // 0 = loose, 5 = vice-tight
public int analSensitivityLevel = 3; // 0 = very sensitive, 5 = numb
public string analLubeState = "dry"; // "dry", "slick", "dripping"
public List<string> analContents = new(); // e.g., ["cum"], ["piss", "lube"]
public float analStretchDecayTimer = 0f; // time since last stretch event (system not implemented yet)
public bool analGapedRecently = false; // auto-clears over time (not implemented yet)
public int analLoosenessLevel = 0; // how easily they can handle insertions (not implemented yet)
// Cum Inflation / Belly Swelling (not implemented yet)
public bool isCumInflated = false;
public float cumInflationLevel = 0f; // 0 = flat, 1 = slight bump, 5+ = distended, etc.
public float cumInflationDecayTimer = 0f; // tracks how long since last liquid filled them
// Exposure (not used for anything yet)
public bool cockExposed = false;
public bool vaginaExposed = false;
public bool breastsExposed = false;
// NSFW States (not used for anything yet)
public bool isInHeat = false;
public bool virginity = false;
public bool pregnant = false;
public bool lactating = false;
public string cumAmount = "normal";
public string cumFlavor = "neutral";
public bool hasCumOnFur = false;
public bool hasCumInMouth = false;
public bool hasCumInAnus = false;
public bool hasCumInVagina = false;
// NSFW Stats (partially in use, needs to be fully implemented)
public int arousal = 0;
public int libido = 5;
public int orgasmCount = 0;
public int orgasmDenialCount = 0;
// Chastity & Restraints
public bool cockIsLocked = false; // chastity cage for penises
public string cageType = "metal"; // metal, plastic, etc. Not used yet.
public string cageSize = "snug"; // flat, nub, snug, small, medium, large, not used yet.
public string keyholder = ""; // Currently used for tracking purposes when player is put in chastity by someone.
public bool canBeTeased = true; // not in use yet, for denial/long term control content
public int unlockAttempts = 0; // Attempts to unlock cage, not in use yet
public int daysLocked = 0; // How long the player ahs been locked, not implemented yet
public bool isWearingBelt = false; // chastity belt for vagina
public string beltType = "leather"; // metal, leather, leather straps with a metal plate, etc.
public int chastityFrustration = 0; // Not implemented yet, how horny/frustrated the person is
public int chastityHumiliation = 0; // Not implemented yet, how humiliated the person has been by chastity related content
public int chastityEnjoyment = 0; // Not implemented yet, how much the person is enjoying their chastity/confinment
// Social/Behavior
public string temperament = "friendly"; // Not used yet, the way this NPC should behave, may be removed later.
public int dominanceLevel = 5; // Not used yet, may be removed later.