Skip to content
Snippets Groups Projects
Commit eaa22d86 authored by DCoded's avatar DCoded
Browse files

Began rewriting the scene guide

parent 75165456
No related branches found
No related tags found
2 merge requests!11159Draft: Updated scene guide,!11149Linting
# Writing scenes # Writing interaction scenes
Most writing is basically just plain text with branches for different cases. Players can directly interact with their slaves via interaction events, such as the ones found in the "Work" section of the Slave Interact menu.
## Examples
If you would like to view examples of scenes currently in the game, there are quite a few in `src/npc/interaction`. Before you start writing anything, make sure there isn't already a similar scene.
## Getting started
Writing a scene is similar to writing any other code for Free Cities; each scene should be a JavaScript function that returns either a `string`, `DocumentFragment`, or an `HTMLElement`. This main function can then be further broken down into subfunctions to increase readability.
<!-- Most writing is basically just plain text with branches for different cases.
Important cases to remember: Important cases to remember:
It's important to handle every RELEVANT variation of the above cases. Depending on what you're writing, other cases may also warrant consideration; e.g. a breast-play scene will probably need to account for breast size and lactation a lot more than a generic fuck scene. If a scene only applies to a specific type of slave, you can restrict the cases you account for to the ones that are only possible for that type of slave. -->
### Considerations
When writing a scene, make sure you properly cover different variations of the event. Here are some things to keep in mind:
- Does the slave have a dick/vagina/tits? - Does the slave have a dick/vagina/tits?
- Does the PC have a dick/tits/vagina? - Does the PC have a dick/tits/vagina?
- If the slave has a dick and you plan to use it, can they get erect on their own? - If the slave has a dick and you plan to use it, can they get erect on their own?
...@@ -12,51 +28,250 @@ Important cases to remember: ...@@ -12,51 +28,250 @@ Important cases to remember:
- Is the slave pregnant? - Is the slave pregnant?
- If you penetrate an orifice, is the slave a virgin in that orifice? - If you penetrate an orifice, is the slave a virgin in that orifice?
- Can the slave move (i.e. is the slave amputated and/or have massive tits and/or a massive dick)? - Can the slave move (i.e. is the slave amputated and/or have massive tits and/or a massive dick)?
- Does the slave like/hate trust/fear you? - Does the slave like/hate and trust/fear you?
- Does the slave have fetishes or personality/sexual quirks/flaws that would impact how they react? - Does the slave have fetishes or personality/sexual quirks/flaws that would impact how they react?
It's important to handle every RELEVANT variation of the above cases. Depending on what you're writing, other cases may also warrant consideration; e.g. a breast-play scene will probably need to account for breast size and lactation a lot more than a generic fuck scene. If a scene only applies to a specific type of slave, you can restrict the cases you account for to the ones that are only possible for that type of slave. ### Structure
There are, broadly speaking, two main ways to do this: <!-- There are, broadly speaking, two main ways to do this:
1. Write the same big block of text and then copy/paste it into each relevant case, and tweak the wording slightly. 1. Write the same big block of text and then copy/paste it into each relevant case, and tweak the wording slightly.
++Less thinking required
--LOTS of duplicate text; if you need to change something later, you have to change it in many places ++Less thinking required
--LOTS of duplicate text; if you need to change something later, you have to change it in many places
2. Decompose the scene into smaller segments or sections that can each be swapped out for the slave type in question. 2. Decompose the scene into smaller segments or sections that can each be swapped out for the slave type in question.
++MUCH easier maintenance
--Have to figure out how to phrase the scene in a way that can be broken down into discrete chunks
You can also combine the two cases. For example, you may want a complex, interleaved set of <<if>> conditions for the common cases, and then have big blobs for the corner cases that are hard to handle. ++MUCH easier maintenance
It can also be easier if you split the scene into a "prep", "main", and "finish" section (these would all be the same writing block, just 2-3 <<if>> chains in sequence); that way, you could, for example, take all the various possible cases that aren't really unique, and narrate them so that, in the main section, you don't have to do so much explanatory writing for the scene to make sense overall. Then, if necessary, wrap up with the finish section. (See src/pregmod/fSlaveSelfImpreg.tw for an example of this approach) --Have to figure out how to phrase the scene in a way that can be broken down into discrete chunks
All the variables for you and the slave are, generally, held in the variables $PC and $activeSlave, respectively. When the PC and the slave have the same attributes, they usually have the same name, but exactly what they do and mean can vary a little bit. RTFM for details. To access a specific variable, you do $var.attribName, so e.g. pregnancy is checked by $activeSlave.preg or $PC.preg. In rarer cases, you'll be dealing with an indexed entry in the $slaves array; if that's the case, you'd use $slaves[_u] or $slaves[$i] (or whatever) instead of $activeSlave. If a second (or third?) slave is present, it will be stored in another variable, the name of which will depend on the scene; for example, when impregnating a slave with another slave, the sperm donor is in $impregnatrix You can also combine the two cases. For example, you may want a complex, interleaved set of `if` conditions for the common cases, and then have big blobs for the corner cases that are hard to handle. -->
Conditions are usually checked by Generally speaking, interaction scenes are split into 5 main sections: "intro", "setup", "consummation", "aftermath", and "cleanup". Though not strictly required, more often than not, your scene will contain at least one of these.
```sugarcube #### `intro`
<<if CONDITION>>
SHOW THIS TEXT This is, as you might expect, the introduction text to the scene. This can be as simple as a single line of text or as complex as you need it to be.
<<elseif CONDITION2>>
SHOW THIS TEXT INSTEAD <b>Example</b>
<<else>>
IF NEITHER CONDITION IS MET, SHOW THIS ```js
<</if>> function intro() {
const text = [];
text.push(`You call ${him} over so you can`);
if (!canDoVaginal(slave)) {
text.push(`use ${his} sole fuckhole.`);
} else if (slave.vagina > 3) {
text.push(`fuck ${his} gaping holes.`);
} else if (slave.vagina > 2) {
text.push(`fuck ${his} loose holes.`);
} else if (slave.vagina === 2) {
text.push(`use ${his} whorish holes.`);
} else if (slave.vagina === 1) {
text.push(`use ${his} tight holes.`);
} else if (slave.vagina === 0 || slave.anus === 0) {
text.push(`take ${his} virginity.`);
}
return text.join(' ');
}
```
<sup>From `src/npc/interaction/fButt.js`</sup>
#### `setup`
This is where you can add "flavor" text to the intro, such as the slave's reaction, for example.
<b>Example</b>
```js
function setup() {
const text = [];
if (slave.vagina !== -1) {
if (slave.vaginaTat === "tribal patterns") {
text.push(`The tattoos on ${his} abdomen certainly draw attention there.`);
} else if (slave.vaginaTat === "scenes") {
text.push(`The tattoos on ${his} abdomen nicely illustrate what you mean to do to ${him}.`);
} else if (slave.vaginaTat === "degradation") {
text.push(`The tattoos on ${his} abdomen are asking you to, after all.`);
} else if (slave.vaginaTat === "lewd crest") {
text.push(`The crest on ${his} abdomen screams debauchery and implores you to use ${him}.`);
}
}
// ...
return text.join(' ');
}
```
<sup>From `src/npc/interaction/fButt.js`</sup>
#### `consummation`
This is where the "action" happens.
<b>Example</b>
```js
function consummation() {
const text = [];
if (slave.anus === 0) {
if (slave.devotion > 20) {
text.push(`${He} accepts your orders without comment and presents ${his} virgin anus for defloration. You`);
if (V.PC.dick === 0) {
text.push(`don a strap-on and`);
}
text.push(`gently sodomize ${him}. You gently ease into ${his} butthole and slowly accelerate your thrusting into ${his} ass. Since ${he} is already well broken, this new connection with ${his} ${getWrittenTitle(slave)} <span class="devotion inc">increases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in.</span> ${He} looks forward to having ${his} asshole fucked by you again.`);
slave.devotion += 4;
} else if (slave.devotion >= -20) {
text.push(`${He} is clearly unhappy at the idea of taking a dick up ${his} butt. ${He} obeys orders anyway, and lies there wincing and moaning as you`);
if (V.PC.dick === 0) {
text.push(`don a strap-on and`);
}
text.push(`fuck ${his} ass. You gently ease into ${his} butthole and slowly accelerate your thrusting into ${his} ass. However ${he} still squeals in pain as you continue pounding. <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} <span class="trust dec">fears further anal pain.</span>`);
slave.trust -= 5;
} else {
text.push(`${He} is appalled at the idea of taking it up the ass${(V.PC.dick === 0) ? ` and cries with fear as you don a strap-on` : ``}. ${He} does anyway though, sobbing into the cushions`);
if (hasAnyArms(slave)) {
text.push(`while you hold ${his} ${hasBothArms(slave) ? `arms` : `arm`} behind ${him}`);
}
text.push(text.pop() + `.`);
text.push(`You force yourself into ${his} butthole and continue thrusting your member into ${his} ass. ${He} sobs and cries with disgust while you pump into ${his} rear. The painful anal rape <span class="devotion dec">decreases ${his} devotion to you.</span> <span class="virginity loss">${His} tight little ass has been broken in,</span> and ${he} is <span class="trust dec">terrified of further anal pain.</span>`);
slave.devotion -= 10;
slave.trust -= 10;
}
slave.anus++;
}
// ...
return text.join(' ');
}
```
<sup>From `src/npc/interaction/fAnus.js`</sup>
#### `aftermath`
Here, you can add some more flavor text, as well as any effects on the slave the interaction may have had.
<b>Example</b>
```js
function aftermath() {
const text = [];
if (slave.fetish === Fetish.MINDBROKEN) {
text.push(`${His} posture doesn't change. ${He} initially only reacts slightly to your physical touch but eventually ${he} relaxes in the warmth of your embrace against ${him}. You know that this may only be a physiological reaction, nothing more. For a brief moment you think you detect a spark of life in ${his} dull eyes but just as quickly, it is gone. When you stop, ${his} ${App.Desc.eyesColor(slave)} track the movements of your hands briefly but then ${he} stares blankly ahead of ${him}, not understanding what is happening.`);
} else if (slave.relationship === -2) {
text.push(`In the warmth of your embrace, ${he} turns towards you, ${his} passionate ${App.Desc.eyesColor(slave)} staring intently at your face. ${He} leans closer to you and kisses you as you hold ${him}. ${His} heart beats faster and then gradually slows as ${he} grows accustomed to your body against ${hers}. Eventually, ${he} relaxes totally and ${his} eyes gradually close, melting in your arms. When you finally stop and relax your embrace, ${his} eyes remain closed and ${his} mouth still in a rapturous shape for a moment before ${he} slowly opens ${his} eyes and smiles at you with a blissful look on ${his} face.`);
if (hasAnyArms(slave)) {
text.push(`${His} hand reaches to your arms and ${he} strokes them longingly.`);
}
if (!hasAnyArms(slave) && !canTalk(slave)) {
text.push(`${He} slowly opens them and does ${his} best to communicate love with ${his} ${App.Desc.eyesColor(slave)}.`);
} else if (!canTalk(slave)) {
text.push(`${He} signs that ${he} loves you.`);
} else {
text.push(`${Spoken(slave, `"I love you, ${Master},"`)} ${he} ${say}s dreamily.`);
}
text.push(`${He} looks at you, almost begging you with ${his} eyes that ${he} wants much more than a mere embrace.`);
} else if (slave.devotion > 50 && slave.fetish === "dom" && slave.fetishKnown === 1 && slave.fetishStrength > 60) {
// ...
}
return text.join(' ');
}
```
<sup>From `src/npc/interaction/fEmbrace.js`</sup>
#### `cleanup`
If the slave needs to clean themselves up before returning to work, put that here.
<b>Example</b>
```js
function cleanup() {
const text = [];
if (V.PC.dick !== 0) {
if (slave.cervixImplant === 2 || slave.cervixImplant === 3) {
slave.bellyImplant += random(10, 20);
}
if (slave.anus > 3) {
text.push(`${His} gaping hole drips your cum right out again.`);
} else if (slave.anus > 2) {
text.push(`Cum drips out of ${his} loose hole.`);
} else if (slave.anus === 2) {
text.push(`Cum drips out of ${his} loosened anus.`);
} else if (slave.anus === 1) {
text.push(`${His} still-tight ass keeps your load inside ${him}.`);
}
if (canMove(slave) && V.postSexCleanUp > 0) {
switch (slave.assignment) {
case "whore":
text.push(`${He} heads to the bathroom to clean ${his}`);
if (canDoVaginal(slave) && canDoAnal(slave)) {
text.push(`holes before returning to selling them publicly.`);
} else if (canDoVaginal(slave) || canDoAnal(slave)) {
text.push(`fuckhole before returning to selling it publicly.`);
} else {
text.push(`face before returning to selling ${his} mouth publicly.`);
}
break;
case "serve the public":
// ...
}
}
}
return text.join(' ');
}
``` ```
Conditions are usually comparative (i.e. `$a < $b or $b == 5 or $c != $d.e`) and can be chained together with `&&` (AND) or `||` (OR) and grouped with `()` - for example: <sup>From `src/npc/interaction/fButt.js`</sup>
`<<if($a > 1 || ($b == 2 && $c != $a))>>`
lets you check that either variable A is greater than one, or both B equals two and C is not equal to A. <!-- It can also be easier if you split the scene into a "prep", "main", and "finish" section (these would all be the same writing block, just 2-3 <<if>> chains in sequence); that way, you could, for example, take all the various possible cases that aren't really unique, and narrate them so that, in the main section, you don't have to do so much explanatory writing for the scene to make sense overall. Then, if necessary, wrap up with the finish section. (See src/pregmod/fSlaveSelfImpreg.tw for an example of this approach)
All the variables for you and the slave are, generally, held in the variables $PC and $activeSlave, respectively. When the PC and the slave have the same attributes, they usually have the same name, but exactly what they do and mean can vary a little bit. RTFM for details. To access a specific variable, you do $var.attribName, so e.g. pregnancy is checked by $activeSlave.preg or $PC.preg. In rarer cases, you'll be dealing with an indexed entry in the $slaves array; if that's the case, you'd use $slaves[_u] or $slaves[$i] (or whatever) instead of $activeSlave. If a second (or third?) slave is present, it will be stored in another variable, the name of which will depend on the scene; for example, when impregnating a slave with another slave, the sperm donor is in $impregnatrix -->
<!-- Conditions are usually checked by
```js
if (condition) {
return `some text`;
} else if (condition2) {
return `different text`;
} else {
return `some other text`;
}
```
Conditions are usually comparative (i.e. `a < b`, `b === c`, or `d !== e`) and can be chained together with `&&` (AND) or `||` (OR) and grouped with `()` - for example: `if (a > 1 || (b === 2 && c !== a))` lets you check that either variable A is greater than one, or both B equals two and C is not equal to A.
There are also a few miscellaneous functions that let you check things like whether a slave can get pregnant or whether two slaves are mutually fertile There are also a few miscellaneous functions that let you check things like whether a slave can get pregnant or whether two slaves are mutually fertile
Variable names are interpolated straight into the text, so if you have a slave named "Beth" then the text
"You fuck $activeSlave.slaveName" becomes "You fuck Beth" "You fuck $activeSlave.slaveName" becomes "You fuck Beth"
You can also explicitly print a variable by doing <<print _varName>> (for temp variables) or <<print $varName>> (for global variables) which can be useful in various situations; it also lets you print the output of code expressions, like <<print $someNumericVar * 10>>. You can also explicitly print a variable by doing <<print _varName>> (for temp variables) or <<print $varName>> (for global variables) which can be useful in various situations; it also lets you print the output of code expressions, like <<print $someNumericVar * 10>>.
If you want to change a variable, you do something like If you want to change a variable, you do something like
`<<set $activeSlave.devotion += 5>>` `<<set $activeSlave.devotion += 5>>`
Which would, in this case, give a devotion increase of 5. Which would, in this case, give a devotion increase of 5. -->
Color is changed with YOUR @@.colorname;COLORED TEXT@@ HERE <!-- Color is changed with YOUR @@.colorname;COLORED TEXT@@ HERE
So a random (really stupid) example might be: So a random (really stupid) example might be:
...@@ -102,9 +317,9 @@ So a random (really stupid) example might be: ...@@ -102,9 +317,9 @@ So a random (really stupid) example might be:
<<else>> <<else>>
ERROR - PC doesn't have dick or vagina? ERROR - PC doesn't have dick or vagina?
<</if>> <</if>>
``` ``` -->
If you need to set a temp variable, prefix it with _ instead of $. This way, you don't go cluttering up the world with variables that only matter inside your little writing segment. <!-- If you need to set a temp variable, prefix it with _ instead of $. This way, you don't go cluttering up the world with variables that only matter inside your little writing segment.
You can "hot-test" stuff by text editing your HTML copy of FC, but it's a little more tedious because you have to "escape" double quotes, <, >, and & with &quot; &lt; &gt; and &amp; respectively. You can "hot-test" stuff by text editing your HTML copy of FC, but it's a little more tedious because you have to "escape" double quotes, <, >, and & with &quot; &lt; &gt; and &amp; respectively.
...@@ -189,4 +404,8 @@ whatever ...@@ -189,4 +404,8 @@ whatever
<</if>> <</if>>
``` ```
- Proof-read your shit before posting it. Spell-check wouldn't hurt. - Proof-read your shit before posting it. Spell-check wouldn't hurt. -->
## Tips
- Make sure you proofread before committing your changes. Many text editors nowadays have plugins you can use to catch spelling mistakes as you write, which can be a huge help.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment