Skip to content

Writing for Tailraise

First off, thank you for your interest in potentially contributing to Tailraise!

This article should serve as the tone, style, and narrative guidance for writing for scenes for the game and hopefully help guide you to making content appropriate for the game world.

To keep the game's "voice" consistent, please read through the following information and other guides before you begin writing anything!


Writing Perspective

Narration in Tailraise should be done in second-person perspective. This means that any time we are describing something about the player, we use "you". An example would be:

You start to wonder if the deer is even telling the truth. You reach a hand out, contemplating for a moment, grasping the box on the left. It's hard to say if this is the right choice, but you feel more confident with this one.

or

You let out a shaky moan, your eyes closing as you bite your lip, almost drawing blood; the feeling is intense. "How much longer will this take?" You wonder.

When using any internal thoughts, please use italicized quotations to denote the thought is internal to the player.


Formatting

In Tailraise, you can format text using the following:

Bold: <b>bold text</b>
Italics: <i>italic text</i>

For colours, we very sparingly use this, primarily for Dialogue. If you need to use it, we write it like so:

<color=\#FFFF00>This text would be in yellow</color>

Note that we include a \ before the hashtag because Ink strips this out normally as a comment, so we need to escape it.


Dialogue

There are three types of dialogue in Tailraise:

The player is speaking

When the player speaks, we simply will use quotations around it, no fancy colours or changes. You don't always need to use quotations and can just have something like:

You ask about the golems and what their purpose are.

Instead of

"What do the golems do? What's their purpose?" You ask.

Mixing it up is good.

An NPC is talking to the player

When NPCs are talking to the player, we format this with specific coloured text to denote this. This colour is F6CD4B in HEX.

<color=\#F6CD4B>"Didn't recognize you. New around here, or just quiet?"</color>

An NPC is talking in the background

When NPCs are not talking to the player and it's something overheard, we specify this with 979585 in HEX.

 <color=\#979585>"So then I said, 'That's not a kobold, that's your mother!'"</color>


Player Agency

In Tailraise, content should be written to offer a choice to the player when possible so we don't always railraod them. Giving a choice or letting them pick options or avoid kinks they may not want to be exposed to is very important.

An example, is if you are writing a scene and want to involve watersports. It's not everyone's cup of pee tea. If you plan to include certain kinks, it's good to frame your scenes in a way where people can enjoy it without being forced into specific kinks when possible.

To do this, consider writing your scene into several branches.

How to give players a choice

stateDiagram-v2
    state "Full scene" as s2
    state "Kink content" as s3
    state "Blowjob scene" as s4
    state "End of scene" as s5

    s2 --> s3
    s3 --> s4
    s4 --> s5
stateDiagram-v2
    state "Start of scene" as s2
    state "Optional kink choice" as s3
    state "Blowjob scene" as s4
    state "End of scene" as s5
    state "Change your mind" as s6
    state "Exit scene" as s7

    s2 --> s4
    s2 --> s3
    s3 --> s4
    s4 --> s5
    s2 --> s6
    s6 --> s7

Here's an example of the second flow, using the Ink Format that Tailraise is built upon.

For more information on why it's structured this way, please check out the sections below:
Branches
Choices and Navigation

A scene with player agency via Ink
=== start_of_scene ===
# writer: Taw
# artist: Taw
~ set_image("npc_placeholder")

<content here>

+ [Change your mind]
    ~ leave_npc()
    -> END

+ [Do optional kink]
    -> optional_kink_choice

+ [Skip kink]
    -> blowjob_scene

=== optional_kink_choice ===
# writer: Taw
# artist: Taw
~ set_image("npc_placeholder")

<content here>

+ [Catch your breath and continue]
    -> blowjob_scene

=== blowjob_scene ===
# writer: Taw
# artist: Taw
~ set_image("npc_placeholder")

<content here>

+ [Cuddle and enjoy some aftercare]
    -> end_scene

=== end_scene ===
# writer: Taw
# artist: Taw
~ set_image("npc_placeholder")

<content here>

+ [Return to NPC talk menu]
    -> start

NPCs

If you plan to add a new NPC to the game, this requires a bit of work because we need to generate their NPC file and fill out all of their attributes. If this is the plan, please contact Taw and ask for the current attribute list to fill out. You will also need to know where this NPC should be located, what hours they show up, and any other requirements.

For existing NPCS, you are able to use the parser system to pull information about them without knowing it off the top of your head. Please refer to Tailraise's Parser for more details.


File Structure

This is probably one of the most important parts of the game and you will need to learn the structure of how things work for Tailraise in order to write branching scenes and choices.

Ink Format

Tailraise runs in Unity with Inkly as the foundation for the storytelling, but this has been heavily modified with many functions added on top, and not all of Ink's features are utilized to keep this simple and straightforward. You can refer to Ink's documentation if you want, but please follow the examples below as the "right" way we do it for Tailraise for consistency.

Credits and Art

All scenes must include credits so we know who wrote the scene or who made the artwork displayed.

To do this, at the start of a branch, we add the following three lines.

This also means as more art is added, each scene can show different art. Taw already does this with a few different art pieces as a test run of the system in-game.

The way we set this up is the following:

# writer: Taw
# artist: Taw
~ set_image("npc_placeholder")

This always goes right below the start of the branch (see below).

~ set_image("image_name") is how we specify which art to use. The majority will use npc_placeholder unless it has it's own specific art.

Any art submitted for the game must include explicit permission from the artist(s) for it to be used in Tailraise.

No AI art will be permitted to be added to the game.

Branches (Knots and Stitches)

These are what each "scene" is in the game.

Ink has a system called knots, which is what we use when we build each NPC's branch and some of the branches on tiles (though this is more rare).

A knot designates the part of the file that is that part in the story to load in, and we use choices to give the player options. Tiles have a different system for generating choices, which you can find more information in the Tile File Structure documentation.

=== this_is_a_knot ===
# writer: Taw
# artist: Taw
~ set_image("npc_placeholder")

<content here>

+ [Leave NPC]
    ~ leave_npc()
    -> END

== this_is_a_stitch ==
<content here>

Knots always have three equal signs surrounding them === this_is_a_knot===.
Stitches only have two equal signs surrounding them == this_is_a_stich==.

Stitches are primarily if you want to inject a pre-made scene into another. They must exist in the same file, or the file they reside in must be included at the very top of the file. Primarily, stitches are used for things like the encounter system.

Choices and Navigation

Every scene needs to have a way for the player to do something. Tiles are the exception, where we simply just write -> END on them, which doesn't spawn choices. Navigational choices always exist based on the tile connections available to you so this satisfies Ink's compiler.

For NPCs, however, we need to always navigate somewhere, or give the player an exit back to the tile.

To make a choice at the bottom of a scene, simply write it so:

+ [This is a basic choice]
    -> new_knot

To leave an NPC and return to the tile, include this:

+ [Leave NPC]
    ~ leave_npc()
    -> END

Functions always start with a tilde ~.

Any time we offer a choice to go back or leave an NPC, it should always be the very first option on the list.

For advanced choices, you are able to structure them in the following way:

[Name ~ Conditionals ~ Tooltip for button ~ Content Warning]

They MUST be separated with a ~. This is how Tailraise knows what each section of the choice is.

Tooltips and content warnings are optional and the system will ignore them if they are empty or skipped. So you can just have [Name ~ Conditional] or [Name ~ ~ Tooltip], just make sure to count how many tildes you add!

Some examples:

+ [This is an advanced choice ~ has_attribute("pc", "hasCock") ~ You must have a cock for this scene! ~ This is a content warning]
    -> knot2

+ [This is an advanced choice with no tooltip ~ has_attribute("pc", "cockIsLocked") ~ ~ This is a content warning]
    -> advance_time(25)
    -> knot3

Automatic Pagination

"But Taw, what if I have more than 10 choices in a scene?"

Great news! Tailraise includes pagination, so if you have too many choices, it will start to put them on the next page. This makes the very last choice button (G) become a Next/Previous button to navigate. This is automatic, so you can have as many choices as you please.

Keep in mind, sometimes it's better to group your choices into different "talk hubs". So the initial things might be on taw_talk but if you have 15+ sex scenes, consider moving them to taw_after_work as a hub you can access from a choice from taw_talk.

While this means it's not consistent with the "return/leave option should always be first", the reasoning for this is we don't want someone to go back a page and accidentally leave an NPC if they tap twice.

Conditionals

For conditionals in a choice, you can check many things, and combine the checks for some really complicated things.

Examples of conditionals

+ [Doubleteam Taw ~ check_attribute("pc", "hasCock") and not check_attribute("pc", "cockIsLocked") ~ Requires an unlocked cock.]
    ~ advance_time(25)
    -> flint_taw_dom_path
+ {has_eflag("seko_throatfuck2_passed") }[Relax your throat ~ ~ ~ Oral ::Throatfucking ::Some roughness]
    -> seko_throatfuck2_success

In the second example, you can also see we have a flag in front of the choice box, {has_eflag("seko_throatfuck2_passed") }. This means if this flag is missing from the PlayerState, this option will never show whatsoever. It hides it entirely from the game until the condition is met and it won't be a valid choice.

For more information on eflags, see Functions (eflags)

You can utilize these to cut off branches and only show them once a player has advanced to a certain point in a story.

Conditionals to use include

check_attribute("ID", "attribute")

The player is always "pc" as the ID, and most NPCs just use their name, like Flint, Taw, etc. For a list of all possible attributes, please see Tailraise Attributes

Examples:
check_attribute("flint", "hasCock")
check_attribute("pc", "cockIsLocked")
check_attribute("nemi", "hasVagina")

Typically, you will want to use these to restrict a scene to characters with specific anatomy, or make sure if someone is topping they aren't locked in chastity, etc.

has_eflag("flag")

These flags are typically what are used in Tailraise to denote player progression. While it's not the most ideal situation to use, with the amount of choices given to the player and what they can do, this is the easiest way since not everything can fit into an enum.

Typically, these will appear BEFORE the choice box (square brackets), like so:

+ { has_eflag("orrick_brew_tease") && not has_eflag("orrick_brew_delivered") && not has_eflag("orrick_taw_tavern")} [Choice]
    -> go_to_scene

This example also shows you can include multiple conditions to check, as well as use the "not" modifier to denote this shouldn't be true.

If you want to add progression to your character, utilizing flags is an easy way to manage the progression, or using the NPC Relationship system.

get_npc_value("npcID", "relationshipName")

These are the preliminary parts of the relationship system and can be used in several ways and are very powerful.

Each NPC can have an unlimited number of relationship types with the player. You can make it "friendliness", "submission", "dominance", "romance", etc. The sky's the limit.

To use them in conditionals, put them before the choice box (square brackets), like so:

+ { get_npc_value("taw", "friendliness") >= 30 } [Lunch Date]
    -> casual_talk_closer_inspection

This means it will only show this option if your "friendliness" with Taw is 30 or higher. To add these in a scene, we simply add this somewhere during a scene or between the choice box name [Lunch Date] and the navigation -> casual_talk_closer_inspection:
~ add_npc_value("taw", "friendliness", 5)

This increases the "friendliness" with Taw by 5 every time you visit that scene and repeat it.

If you want a cap, like not letting it raise above 100, simply use the _clamped version of the variable:

~ add_npc_value_clamped("taw", "friendliness", 5, 100)


Adding Randomness

Some of the scenes in Tailraise actually are randomized and if you repeat them you might get a different outcome. You will primarily notice this as you navigate tiles, as typically we add three flavour texts per tile, in addition to static text that stays the same.

Examples of using randomness in Tailraise

You can make it so when you navigate to a scene, it rolls a number and picks a scene to branch to immediately and display. This way, you can write a few variations of a scene cleanly into their own scene branch sections and include different navigation for them if required.

To do this, you would make a new scene like this:

    === start_of_scene ===
    # writer: Taw
    # artist: Taw
    ~ set_image("npc_placeholder")

    ~ temp choice = RANDOM(0, 1)

    { choice:
        -0:
        -> scene_blowjob
        -1: 
        -> scene_anal
        - else:
        -> scene_blowjob
    }

What this is doing is creating a temporary variable that rerolls every time you revisit this using ~ temp choice = RANDOM(0, 1).

Always include an - else: block as a fallback in case it somehow rolls outside the range.

You can make this range higher, such as RANDOM(0, 25).

Instead of it using choice blocks, we use the Ink navigation to specify the scene to load, which loads immediately. So, for the player, they just see the content appear, they don't have to press any buttons, this all happens behind the scenes and navigates within a frame to the chosen path.

In a scene, you can use the temporary variable system in Ink to generate a number and based on that number, choose which scene gets displayed.

An example of this:

    You take a moment to think about how you want to proceed.

    ~ temp choice = RANDOM(0, 2)

    { choice:
        -0:
        You decide you'll give the wolf a blowjob.
        -1:
        You decide to top the wolf.
        - else:
        You decide you'll ride the wolf's cock.
    }

    Other content that is consistently the same here.

    + [Get dressed]
        -> npc_talk_hub

This way, you can write a bunch of stuff for a scene and have it all in one spot. It can be easier this way for things that only partially change in a scene so you're not duplicating your words across multiple scenes to write this way.

Keep in mind, doing it this way means all scenes variations should end the same way. I recommend writing it so the player and NPC(s) end up doing the same thing at the very end, like catching their breath and cuddling for a moment, then cleaning up. Then you can write the choices for the player to be the same each time.

If you need the choices to be different, it's better to use the random scene option instead.