News:

Please request registration email again and then check your "Spam" folder

Former www.henthighschool.com

[Resources] Writing events for BK

Started by Goldo, May 19, 2022, 09:17 AM

Previous topic - Next topic

GoldoTopic starter

A GUIDE ON WRITING EVENTS FOR BK

SUMMARY

1- FAQ
2- HOW TO WRITE EVENTS FOR BK
3- THE LORE
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

GoldoTopic starter

#1
PART 1: FAQ

You can ask questions on event creation in this thread. New questions will be added to this FAQ as they come.


- Is writing new events for BK easy?

Yes! Writing events for BK only requires a basic understanding of Ren'py and, optionally, very light Python coding.

Ren'py is a simple, beginner-friendly language designed for writing visual novels.

To give you an idea, here is what Ren'py coding looks like behind the scene:

"Nothing is moving in the sleepy brothel. All your girls are fast asleep, exhausted by the hard work they had to pull last night."
 
play sound s_creak

"Suddenly, you hear some noise coming from the maintenance room."

you "This is strange... That room is locked, and there is no other entrance... Except maybe the old chimney?"

"Openning the door as silently as you can with your spare key, you prepare to confront the intruder."

you "Whoever is in here... Show yourself!"

play sound s_door

scene black with fade
show bg hmas at top with dissolve

play sound s_spell

if seen_hmas:

    hmas_girl "Hi, [MC.name]..."

    "You recognize the strange girl from last year."

    you "Oh, it's you again..."

else:
    you "Who are you?"

Even if you have zero experience with coding, you should be able to more or less find your way around this code, right? There isn't much more involved when coding basic events with Ren'py.
There are many tutorials online about writing events in Ren'py. All of them apply to writing events for this game as well.

In fact, the hardest part of writing BK events may be the writing. Many people volunteer to write for the project, only to face the H-game equivalent of writer's block or crumble under the weight of an overtly complex overarching story with dozens of events and characters...

As in learning anything, start simple: try to make a one-shot event with only a few characters, or a very short event chain with max 3-4 small events. Don't bite more than you can chew at first, you'll quickly find that writing (and testing, and proof-reading) is more time-consuming than you thought.


- Ok, but how easy is it to write complex events?

Complex events are a subjective category, of course, but generally-speaking there are several types of events in increasing order of difficulty.

  • Linear events with set characters (think about Kosmo events): Extremely easy to write, no python involved
  • Conditional events with set characters (think city events): Those are a little more complex because they require keeping track of some conditions (like player alignment) and choices, but still very easy to manage with extremely basic python
  • Events with dynamic characters (think about girl events that happen at night): Those are a little more complex because they require tracking which girl is selected and maybe check her skills, rank, level, sexual preferences... There are lots of built-in methods in the game that make this straightforward, but it requires understanding the basics of the game's python architecture. This could be considered 'advanced'.

My advice is always the same if you are new to writing events with Ren'py: start with the easy 'set character' pieces before venturing into more complex territory. Don't get too ambitious at first.

When you do get ambitious, you can always drop me a PM or leave some comments in the code for me if you are trying to achieve something in particular and don't know how to do it.


- How long should my events be?

I guess everyone has their own worthy ideas here, but I think most players agree that shorter is better. The story events I write are typically too long (sorry), and I struggle to make them shorter. I would recommend being more concise if you can manage it, especially for side events that are outside of the main story.
I find that breaking events down into chunks that let the player do something else in-between helps. If your event runs longer than 100 lines (you'll be surprised how quickly you'll get there), I would consider breaking it down.

The final trial scene in Chapter 1, for instance, has about 400 lines split along 3 different timelines, so about 150 lines for a single playthrough. For me, that's about as long as any single event should get without seriously overstaying its welcome.

With that said, I have found through testing that I much prefer to split dialogue in smaller snippets of 1 or 2 sentences (thus, ending up with more lines) rather than have long paragraphs for the player to read.

So, I try to avoid this:

sill "Hello Master! It's a nice day to take a walk, don't you think? Let's go to the harbor, I want to show you a nice jewelry shop I discovered there... I mean, I just want to look at it, it's not like I'm expecting a present... *blush*"
...and do this instead:
sill "Hello Master! It's a nice day to take a walk, don't you think?"
sill "Let's go to the harbor, I want to show you a nice jewelry shop I discovered there..."
sill sad "I mean, I just want to look at it, it's not like I'm expecting a present... *blush*"


Of course, that's just my preference. Other people might reasonably disagree.


- What tools do I need to write events?

Wordpad. I'm half-kidding, because obviously it's not good for any kind of serious coding, but if you want to check any .rpy file in a pinch, Wordpad works just fine (I don't recommend Notepad, because of readability issues, and definitely not Word, which will add a bunch of metadata that will mess up your file. Notepad++ is of course fine, if you use it.).

For any serious event writing, however, you want to use a code editor that highlights various parts of the code as you type and helps with indentation. I use Editra Atom now, which works fine if you have the correct set-up. Check the Ren'py website for links to editors that work with the language, and download it from there so that the set-up is already done for you.

As for trying out your custom events, there are ways to test them directly in-game, but you might want to download Ren'py on its own anyway, if only to play through the tutorial.
They are all free distributions.


- How do I test my events in-game?

For simple events, the most convenient way might be to download Ren'py and start your own project, testing your events as stand-alones.

However, this often won't work for conditional events, because if you need to check for BK variables like player name, class or alignment, or girl love or fear, etc., the stand-alone game will start throwing errors.

So the next best thing is to test your events directly in-game.

First, you must understand this basic fact: ALL .rpy files in BK's game folder and its subfolders are read together as one big chunk of code by the game. So it doesn't really matter where you drop your code, or how many .rpy files you write, it will behave the same as long as it is dropped somewhere within the game folder and subfolders.

But just because your events are read doesn't mean they will actually play out in-game, though. To play them out, you need to go through a couple of steps:
  • Go to BKsettings.rpy and change 'debug = False' to 'debug = True'
  • Use the cheat menu in-game to find the cheat 'Test Event' and enter the label name you'd like to test
  • Alternatively, use the console (Shift+O) and call your event with the 'call' command:
call my_label_name

# Alternative python command if Renpy is disabled
renpy.call("my_label_name")

While this might not work for all complex events, this should be enough to get you started.

- How should I call my events?

Events are introduced by labels. The game already uses a lot of labels, so calling your event something like 'start' or 'next_day' will probably result in conflicts with the main game. I recommend using a prefix for all your events (such as: 'goldo_start' or 'goldo_next_day'), or use the new Ren'py system of local labels to avoid problems. As long as you use a unique prefix, you can then name your labels whatever you like.

- How do I make my events available to everyone?

There are a few ways:

  • Make a mod and share it, following the 'mymod' example you can find in the vanilla game. If the mod system doesn't cover all your needs, you can always request me to add some plug-ins here and there as some mod-makers have already done.
  • Make your events available in a girl pack (for girl-specific events), following the examples given for Boa Hancok in-game and on the forum.
  • Ask me to make those events part of the vanilla game. There are a few conditions for me to accept new events, however:
          - The events should match the lore and direction I want for the game (more on that below)
          - The events should be bug-free, and the text seriously proof-read (no typos, missing punctuation, etc.)
 

- Can I use characters from the main game in my events?

Yes! Do keep in mind that I have plans for all of the named characters that are currently in-game, so if you want to kill them off, significantly rewrite their back-story, or change their personality completely, know that I will most likely never include your event as part of the vanilla game. You're free to do it in your own mod, of course.

But if you stick to the game characters' current personality as described in game events and refrain from going all 'game of thrones' on them, you're more than welcome to make them parts of your events, for extra flavor. :)
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

GoldoTopic starter

#2
PART 2: HOW TO WRITE EVENTS FOR BK

This guide assumes that:

- You're looking for a quick and efficient way of trying your hands at making your own events for BK
- You have zero experience with coding
- You are willing to learn basic Ren'py and go through its tutorial

If you are already proficient with Ren'py and Python, you will know most of what is here already; but there are a few tips specifically for BK that might interest you.

Note: I have tried to use every day language here, so some of my wording might not be correct or 'pythonic'.

For any serious effort, you'll want to use a code editor. There are for instance Atom, Notepad++, Editra: they are all free. Some of them support Ren'Py (download their builds on the Ren'Py website, they come with the right set-up), but in a pinch setting them up with regular Python syntax is perfectly fine.

When writing events for BK, I generally follow these steps:

1 - Create characters and pictures
2 - Write the story and dialogues
3 - Add sound and visual effects
4 - Add conditions
5 - Proof-read and test events

You can fudge the order of steps 2-4 a little bit, but for starting out I would recommend following this primer.


1 - Create characters and pictures

This is the step where you introduce your new characters and pictures. Of course, you could also use existing characters and pictures from the game. But you will probably want to have some of your own.
For this part, let me refer you to all the great Ren'py tutorials online.

Most vanilla BK declarations happen in BKdeclarations.rpy. Declaring pictures in the classic Ren'py way is recommended. The game uses home-made 'declare' functions to save coding space, but I wouldn't recommend using them unless you know what you are doing.


Note that many characters in BK have their own portrait, so it is recommended you have one for each of your non-generic characters. Name color also changes for main characters.

For truly minor characters, most of the time, you do not need to declare them. Ren'py lets you use a string (= text between quotes) as a character's name to introduce dialogue, like this:

"Random guy" "Watch out! Aaaaaah!!!"
The name of such characters will always display in white.


2 - Write the story and dialogues

While time-consuming, this is by far the easiest part. If you would like to write events for BK, and think of yourself as a good writer, know that writing is only about 25% of the actual work. This is, however, one of the most fun (to me).

Do yourself a favor and write directly in the code editor. Copy-pasting from word processors will result in disasters more often than not (Indentation will screw you... See below.)

Ren'py makes writing story and dialog a breeze. There are a few tips specific to BK:

- The main character is referred to as 'you'. You can write any text for the MC like so:
you "Hello, world."

- It's good to add flavor to the text by using user-defined names such as 'MC.name' or 'brothel.name', like so:
sill "Hello, Master [MC.name]. I feel today will be a good day for [brothel.name]!"Note that 'brothel.name' is supposed to include the article (if applicable).

- If referring to a specific Girl object in-game, a Ren'py character is created as the 'char' property so you can write this to have the correct character show up:
girl.char "Hello, Master. I am [girl.fullname]."Where 'girl' is a variable that must been set first to the correct girl, of course. If this last part doesn't make sense to you, best to skip such events for now.


3 - Add sound and visual effects

Writing the dialogue is only half the battle in a Visual Novel, we must not forget the visuals - and sounds.


3.1 Pictures

First, you want to show relevant images as background for your dialogues.

A few common operations:

Show a black background
scene black with fade
Hides all pictures and shows a black screen with a longer Fade effect. As a rule, the game uses fades when changing scenes or when a significant stretch of time is supposed to pass in the story.

This does not, however, hide screens (such as the home menu). If needed, you can call the following BK label which should clear most screens:
call hide_everything()

Show a character
show sill with dissolve
Shows a picture on top of all other active pictures. Note that as a rule, most showing and hiding in game happens with a 'dissolve' transition. Following that rule for your events will make them integrate more seamlessly with the vanilla game.

Show an image as the background
scene black with fade
show bg spice_market at top with dissolve
This is the recommended way to show a background. If the background image is exactly the same size ratio as the screen, you could go with a simple 'scene bg xxx with fade'. However, many pictures are in a wide format that doesn't match the screen. In those cases, it is best to use the code above. The black background will avoid an ugly checkered default background from showing next to the picture.
The 'at top' instruction will align the picture at the top instead of the default bottom, where it would be hiding behind text.
Note that the game doesn't "know" that this is a background, so the picture will still show on top of all other active pictures. This is why the order of 'show' statements matters: always start with the background.

Hide an image
hide bg
hide sill
with dissolve
Hides both pictures with a single dissolve transition. Note that in many cases, 'scene black' is enough to hide all pictures: using 'hide' is only necessary when only some pictures are hidden.
When written by itself, a transition such as 'with dissolve' will apply to all the statements above it.


3.2 Transitions

You might notice the 'with' statements above. With statements introduce transitions. Ren'py comes with set transitions like 'dissolve' or 'fade' or 'pixellate', but advanced renpyists can create their own.

I heavily recommend using a transition EVERY time you show or hide a picture. Omitting a transition results in pictures popping in or out in a harsh, unnatural way.
It is also possible to use transitions by themselves, and is useful in a number of situations to create special effects.

Here are the most common transitions:

with fade
Fades to black for a second then to the new picture

with dissolveFades the new picture in/out. This is the one I use the most when showing/hiding pictures.

with vpunchI use this one a lot: it shakes the screen vertically, for instance when the player is hit. There is also 'hpunch', but I tend to use it less as I don't like the effect.

with flash
with doubleflash
These transitions flash the screen once or twice. Useful for lightning effects and, ahem, 'finish' scenes.

with pixellateBlurs the picture in or out with a pixellating effect. I use this mainly for combat KOs or deaths.

The ninja minigame has some creative uses of transitions.
It is possible to get very creative (and much, much better than I am) at using transitions. Look up 'ren'py ATL' if you want to learn more.

By all means, feel free to experiment and tinker with transitions or add your own for your events. It's part of the fun of Ren'py.


3.3 Sounds and music

It's easy to forget sound when writing events, but a few strategically placed sound effects help make the event more lively, as well as an appropriate background music.

On the other hand, sounds playing at an inappropriate time or mismatching music can take away from the event's quality. Thus, it is vital to test sounds and music carefully before releasing an event.

Also, some breaks from overbearing music is sometimes needed. Don't forget to stop the music when it is no longer needed.
To get Ren'py to play sound or music is very easy:

Sound

play sound s_punchThe 'play' command line will play sound or music. 'sound' is the channel on which it plays, in that case, it's the basic channel for sound. 's_punch' is a sound file: for ease of reference, all the sound files BK uses are defined as variables starting with 's_' and can be checked or edited in BKsettings.rpy.

Here is a more complex example:
play sound s_crash
pause 0.3
play sound2 s_wscream

This code will play the first sound (crash), wait 0.3 seconds, then play the second sound (scream). I use another channel here, 'sound2', to allow for both sounds to be heard without the second one cutting off the first one.
There are 3 default sound channels in BK: 'sound', 'sound2', 'sound3'. Note that all three channels refer to sounds in the 'game/sounds' directory. You could create your own channel if you're modding and want to use another path (see channel declaration examples in BKsettings.rpy).

Music

play music m_disco fadein 3.0Using the 'play' command line again, we can activate the 'music' channel. The music channel refers to the 'game/music' folder. For convenience, all BK musics are stored in variables starting with 'm_'.
'fadein 3.0' means that the music volume will increase gradually over 3.0 seconds. This is recommended, as it helps the music transition to be smoother.

stop music fadeout 3.0
This stops the music currently playing with a 3.0 second fadeout. Remember to shut down the music when appropriate, especially epic or dramatic music, to avoid wearing down the players' nerves.
Music will keep playing in a loop until it is actively shut down with 'stop'.
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

GoldoTopic starter

#3
4 - Add conditions

Until now, writing an event has been laughably simple, right? Only use quotation marks, a few 'show' and 'play' commands...

But many times, you will need to use menus, or even Python code (ominous background music playing) to add various conditions so that your event feels more dynamic.


4.1 Choice menus

Let's start simple, with renpy choice menus.

menu:
    "Are you ready to use Python?"
 
    "Yes":
        "Bring it on, bitches!"
 
    "No":
        "I'd rather not, thank you very much."
This code presents a menu to the player, with the 'prompt' being the first sentence, then the choices in the menu being "Yes" or "No", followed by ':'.
Now is the time to introduce a concept that will kick your ass over and over when coding, no matter how simple or difficult the task: indentation.

As you can see, the 'prompt' and choices are indented once, meaning they are four spaces to the right of the command line menu.
This is how Ren'py knows that these are instructions linked to the menu command line (your code editor will usually auto-convert a press of the 'tab' key to four spaces as required).

The same is true for each choice: notice how each choice is followed by ':' and the following lines are indented one step further.
This is how Ren'py knows that these lines should follow this choice or that choice.

Like I said, it's easy to get indentation wrong, and all hell will break loose if you do. This code, for instance, will throw errors at you like bricks:

menu:
"Are you ready to use Python?"
 
    "Yes":
        "Bring it on, bitches!"
 
        "No":
        "I'd rather not, thank you very much."
All I did was change the indentation slightly, but that's enough to make this code an unworkable mess. This is also why you want to be using a code editor: they make indentation problems easier to spot and fix.

Indentation ruins lives. You've been warned.


4.2 Variables

Let's say that you get indentation and are not deterred by the risks to your sanity. You might think: 'Cool, I can give choices to the player, but how can I have the game remember their choices?'

To do that, you need to use python variables. It might sound scary, but it's really quite easy. Take the following code:
$ result = "Yes"This simple line creates (or overwrites if it already exists) a variable called 'result' and tells it that its value is 'Yes'. 'Yes' is called a string (basically, text) because it is contained between quotes.

Very importantly, the line starts with the '$' sign. This tells Ren'py that what follows is a python line of code. Every time you change a variable, you will need to use python, and thus, the '$' sign, so get used to it.

There are many, many things to say about python variables, but you should be able to learn little by little about them on your own.
I would recommend getting a good comprehension of strings, integers, floats, lists/tuples and dictionaries, and it should suit most if not all of your needs.

For starters, though, using simple variable like 'result' above will do, but be careful: some nouns are already used by the game (like 'game' or 'district'), others are reserved for Ren'py or Python: you should try to name your variables something unique to avoid problems.

I use the variable name 'r' or 'result' all the time in-game for storing temporary variables, so you can do the same in a pinch.

But for variables that need to be used throughout an event chain, please make sure to use a unique name (I recommend using a prefix specific to your mod to name variables, such as mymod_xxx).


4.3 Player input

Now that you know about variables, here is a useful application that you can use in your events: asking the player for input.
$ middle_name = renpy.input(prompt="What is your middle name?", default="Danger")

"Wait, [middle_name] is your middle name?"
This will show the input screen and ask the player to type something. The 'prompt' will be shown, and 'default' will be written as the default answer.
The result will be stored as the ''middle_name' variable. The second line shows how you could use it in a Ren'py sentence.

Important: Note that even though renpy.input is specific to Ren'py, this line is still python code, so it needs to be introduced with '$'.

Side note: Results of 'renpy.input' are stored as strings (text). If you want the player to input numbers, you need to convert the result to a number format like float or integer, likeso:

$ number = int(renpy.input(prompt="Go ahead, pick a number.", default=1))

4.4 If clauses

Arguably the cornerstone of programming, the 'if' clause is of major importance to make many events work.

'if' typically comes with secondary clauses such as 'elif' and 'else':
if number > 0:
    "The number is positive."

elif number < 0:
    "The number is negative."
 
else:
    "The number is zero."
'elif' means 'else if' and is useful to check other conditions after the first one. 'else' activates if no prior condition was met. Note that 'if', 'elif' and 'else' must be followed by ':', and (typically) an indented block, otherwise you will get errors.

Interestingly, Ren'py lets you use 'if', 'elif', 'else' directly as part of Ren'py, even though they originally come from Python. So you DON'T need to use '$' with 'if' clauses in Ren'py, in fact adding it will cause errors.


Another cool feature Ren'py has is the ability to integrate choice menus and if clauses. Consider this example:

menu:
    "Do you want to buy something?"
 
    "Buy the red dress for 50 gold" if MC.gold >= 50:
        you "Give me that dress."
     
        play sound s_gold
     
        $ MC.gold -= 50
     
    "Give up":
        you "Nah, I'm just browsing."
The first choice option will only be shown if the player has at least 50 gold to pay for the dress. Neat.


4.5 Useful variables/methods

Note that the game has many built-in variables and methods that can save you time. Here are a few useful ones for events:

- MC.name is the player's name
- MC.gold is the player's gold
- MC.playerclass will return 'Warrior', 'Wizard' or 'Trader'
- MC.god will return 'Arios', 'Shalia' or None (without quotes)
- MC.get_alignment() will return 'good', 'evil' or 'neutral'
- calendar.time is a number showing the total number of days since the beginning
- calendar.get_weekday() returns the current weekday (e.g. 'Thursday')
- calendar.get_date() returns the short M/D date format (e.g. 4/25)
- calendar.get_season() will return 'winter', 'spring', 'summer' or 'fall'
- game.chapter will give you the current chapter (from 1 to 7)
- game.has_active_mod(mod name) will check if 'mod name' is activated
...

Note: 'Object properties' like game.chapter work just like regular variables. 'Methods' like calendar.get_weekday() are not variables and MUST be used with the brackets '()', otherwise you will get nasty bugs.


4.6 More advanced stuff

Using choice menus, variables and if clauses will let you do pretty much anything you want for your events with a little imagination.
Of course, at some point you might want to do something a little more complex than that.

Here are a couple of more advanced techniques you might need to use for your events.


Using 'for' loops

One of the limitations of using Python within Ren'py with the '$' sign is that you can only make Ren'py read one line at a time. So a simple 'for' loop you might be used to from other languages will cause an error.

To make it work, you need to write a python block:
python:
    hurt_girls = 0
 
    for girl in MC.girls:
        if girl.hurt:
            hurt_girls += 1

"There are [hurt_girls] hurt girls in your brothel."

The whole indented block after 'python:' is python code. Thus, there is no need to use the '$' sign anywher within that block.


Setting up a chain of events

If your event is split in several chapters, it's very likely you will want to set up a chain of events so that a second event happens the next day, or the next time the player visits a specific location...

For this, I would recommend using the mod system I implemented, using 'Goldo's cool mod' as your introduction.

If you don't want to use a mod and are willing to get into a little complexity, here is a quick and dirty cookbook to set up your event chains:

$ add_event(label = "kosmo_returns", date = calendar.time+7, type = "morning")This code will call the 'kosmo_returns' label 7 days after the current date, in the morning.

$ add_event(label = "dodgy_meeting", chance = 0.5, type = "city", location = "thieves guild")This code has a 50% chance of calling the 'dodgy_meeting' label the next time the player visits the Thieves guild.

Accepted values for 'type' here are 'night', 'morning', 'any', and 'city'.
The add_event() function can be found in BKfunction.rpy and takes many other useful arguments.

Those two examples should be enough to get you started. Drop me a PM if you need to do something more advanced and can't figure out how to go for it.


5 - Proof-reading and testing events

Did you think you were finished? Far from it. Proof-reading and testing is by far the most time-consuming part of making events.

If you are not spending at least as much time testing as you did on steps 1 to 4, you're doing this wrong!

Yes, testing is tedious, but it's the only way to make sure your events are bug free and that the 'flow' of the event with its different parts (text, pictures, sounds, effects, choices...) feels good and natural.
As for typos, well, some people don't care, but I do. Typos or poorly-written lines are immersion-breaking and will make your events look amateurish.

I personally try to eliminate typos whenever possible, and would not consider making any event part of the main game if it had sloppy spelling. I'm glad people like DougTheC are here to kick my butt when I let some slip!

When you are reasonably proud of your work, don't forget to put it out there for other people to test it! People might see things differently and help you catch the last remaining bugs or typos. Plus, it's a great motivator to have people try and comment constructively on your work.

But before releasing even as a test version, make sure you did your homework first as far as proof-reading and testing goes. People are not necessarily happy to pick up the slack...



Final tips on writing events

This checklist might help you make sure that your events are not just working but actually good:

- Do the characters have an engaging personality, a believable backstory (even if it isn't spelled out in the events) and understandable motivations? (for instance: this is a H game, so obviously some women are sluts, but if all random girls you meet while doing groceries just drop on their knees to suck you off, you might be light on character background and motivation ;) )

- Don't forget the MC! Did you allow for various lines or outcomes depending on the player's class, god, alignment? Having an event where the player plays the part of a romantic hero might look very odd in the middle of an evil playthrough.

- Did you remember to cover exceptions (e.g. the player must pay but has no money, a girl is picked from the brothel but the player has 0 girls, ...)?

- Are the events written in digest chunks and not too long?

- Are your sentences reasonably short and to the point?

- Are there no bugs or typos?

- Is the event fun?

Perfect then. I can't wait to see what you come up with! 8)
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

GoldoTopic starter

#4
PART 3: THE LORE

I've always thought that making a hentai game does not mean that the game shouldn't have an engaging back story, so I've put some efforts into making a world that is fleshed out.
Event writers will find some background information below. I've kept all of this spoiler free, even though many of the details below can be learnt simply by playing the game and paying attention to the small talk.

The world of Brothel King

Welcome to the world of Brothel King!
A world of fantasy where gods, magic and monsters are all facts of life.
The main continent, Xeros, contains all kinds of climates and cultures, and the game's location, the city of Zan, heavily draws from oriental influences.
While the world's advancement could be compared to our own medieval/early renaissance period, magic and ancient technology means that pretty much anything is possible.


Society and culture

Obviously, as befitting a hentai game, sex plays a large role in this world and the people's morals regarding sex are a lot looser than IRL. In particular, things like harems, prostitution, sexual slavery, having sex with monsters (don't try this at home)... are not frowned upon so much.

These are normal occurrences for the people in this world, and they just don't think too hard about it. Of course, 'reputable' people still care about looking moral and chaste, so they still make some effort to hide their personal kinks.

As the game is set in a medieval/fantasy setting, there are kings and nobles, peasants and serfs. Social class plays a much larger part in Xeros than it does in your own place and time (hopefully).

Nevertheless, the times they are a-changin', and wealthy bourgeois often wield just as much if not more power than many high-born nobles, thanks to the almighty denar (the currency of Zan, and one of the most commonly used in Xeros). Organized religion and the military also play their parts at leveling the playing field a little between the elites and the masses, even though they are also dominated by the noblety.


Geography



BK's main events are set in Zan, aka the City of Jade, the most prosperous city on the super-continent of Xeros (very cool map courtesy of Neronero).

Zan sits in the North-East corner of Xeros, with easy access to major sea routes and surrounded by good agricultural land. It has a mix of oriental influences drawing from the real world, from the Middle East to India or Japan. Zan's wealth is built on trade and slave trading, and its economy is as strong as its leaders are divided and weak. Corruption runs rampant, as a matter of course.

Other major locations in Xeros can feature in your events, if they strike your imagination:

The Holy Lands: The Holy Lands are wild lands in the North of Xeros, layered with jagged mountains and dense forests where the god Arios is said to have first descended on Xeros. A bloody war has been waged here for years, involving humans, non-humans and monsters to settle the control of this region. This is where the Warrior spent most of his adulthood.

Karkyr: Smack in the center of Xeros, Karkyr is the City of Mages, a place where magic-users gather to learn and experiment freely with magic. Karkyr sits at the confluence of several rivers and atop a powerful magical nexus, allowing its inhabitants to easily use magic to improve their daily lives. This is where the Wizard used to study.

The Arik mountains: These high peaks sit between the Holy lands and Karkyr, some ways off from major trade routes and settlements. They have a mystical aura, and many legends feel alive there, attracting hermits and rogues alike.

Westmarch: The West of Xeros is occupied by feuding principalities, where dozens of minor noble families vie for power, prisoners of a complex network of alliances and grudges that are often inscrutable for foreigners. The Princes tend to live easy and privileged lives, with some being eager patrons of science, arts, and magic, while their subjects live squalid lives of hard menial and agricultural labor to pay for it all. Westmarch is where the Wizard used to work as an advisor to a local prince.

Borgo: Borgo is Zan's main rival as a major port, located further South in the East of Xeros. Called the Harbor city, it sits at the entrance of a massive river that allows for boat transport to reach as far inland as Karkyr.
Borgo is significantly rougher than Zan with lots of poor, working class people or outlaws. Only a loose coalition of merchants and middle class citizens calling itself the 'Republic' ensures something akin to 'Law and order', still leaving a lot to be desired. This is the native city of the Trader.

Hokoma: The far South of Xeros is at first a large desert, then covered by dense jungles that haven't been properly mapped yet by the 'civilized'. There aren't any large settlements, but a great many nomad tribes, some of them with truly bizarre cultures and rituals. They sometimes venture North to acquire modern goods and captives. This is where the Trader lost his previous livelihood in an ambush.

The Goliath desolations: In the far North-West of Xeros sits a harsh realm of ice and rock known as the Goliath desolations. Forgotten to many, the West of Xeros was once a center of culture and power rivaling the East, but this ended long before recorded history. Legend has it that it used to be a charming and bucolic place, full of green pasture, but it all ended during the time of the Goliath invasion. A nearly mythical event in Xeros, the invasion or invasions were a terrible war fought against a mysterious people of giants, that found its conclusion in the infamous wastes. Whatever happened, it devastated the land so that, to this day, it remains harsh and barren. Human settlements still cling to the desolations, perhaps remnants of large cities that existed before the event. The people there are hardened Nordic folks, used to handle the brutal cold and many dangers of the desolations.

The Blood Islands: A hundred miles off the coast of Zan lies a large archipelago called the Blood Islands. It is surrounded by the Blood Sea, which gets its name from the reddish color of the ocean and the violent reputation of the islands' slavers.
The absolute masters of the islands are the Blood Council, powerful nobles and mages said to have high-elf blood running in their veins. They are cruel slavers who made their reputation on their creativity and ability to accommodate every customer need - for a steep price.

Other places: This only scratches the surface of the massive continent that is Xeros. In addition, there are many stories about what lies beyond the seas that surround it. Some large islands trade heavily with the continent, while other landmasses remain completely unmapped. A few mad men claim there are even other continents out there, but if it's true, no reliable scientific expedition has been able to prove it. Not that there are many of these, of course, as most governments in Xeros are too weak or self-centered to support such intellectual endeavours.


Politics and religion

Zan is a city-state ruled over by a king for the past 20 years, Pharo the First, from the Pharo dynasty. The king is a widower with an only daughter, princess Kurohime. The king's grip on power is weak, however, as the real power in Zan belongs to a coterie of wealthy nobles and bourgeois guilders that control the flow of trade and slavery. The high level of corruption in Zan means that most of the city's loyalty is up for grabs, and that any faction's domination is short-lived.

The weakness of the King is seen as an advantage by many, thus the unrest has not affected the stability of the royal family so far. Princess Kurohime is now ripe for marriage, however, and the city is holding its breath to see which noble family will gain an edge by allying itself to the King's bloodline. The King's choice in this matter could very well upset the fragile balance between the big families and power brokers that compete for control.

As befits a city-state, the King's powers only cover Zan and its surrounding lands. Xeros is home to hundreds of big or small and realms which all have their own system of government, such as the Princes of Westmarch, the Elder Circle of Karkyr, the Freelancer Republic of Borgo, the Blood Council of the Blood Islands...

The weakness of most of Xeros's governments means that many private organizations wield just as much if not more power, especially the guilds that exist for every possible trade, and the churches or cults. Some major factions of note:

The Slavers Guild: This guild handles most slave trading in Xeros and is especially powerful in Zan. They are a separate organization from the Blood Islands slavers that provide the continent with some of the highest priced sex slaves. The two organizations mostly ignore each other, although some kind of deal must have been struck in the shadows to prevent them from encroaching on each other's turf.

The Magic Guild: This guild handles the affairs of magic-users away from Karkyr, where its headquarters are located. The magicians are always eccentric and aloof, and prefer to handle their affairs between themselves. They also worry (with good reason) that ill-informed citizens might sometimes mistake their lawful magical activities for the forbidden kinds, such as necromancy or sexomancy, and burn them at the stake before asking questions.

The Thieves Guild: This guild is very secretive, some even doubt it really exists, as thieves are not likely to be able to trust each other enough to organize themselves. Its headquarters are rumored to be in Borgo. It has strong links to the Goddess Shalia.

The Arios Church: The leading cult in Xeros, the Arios church and its followers worship Arios, the Sun, god of Light and Strength. It is a powerful and flamboyant religion, which tends to be rigid and intolerant of other creeds and minorities. Its seat of power in Zan is the Cathedra (no final 'L'), currently operated by nuns (the high priest and knights are at war).

The Shalia cult: Not an organized religion, but still a popular one, Shalia followers worship the Moon, goddess of Shadows and Cunning. It is a favorite among misfits and outlaws. Arios followers don't like it one bit.

The elder races: Wood elves are the main elder race that people think about, but these includes many other beings from diminutive fairies to dog, cat or fox people, to sentient dragons and giants. Elves, animal people and similar races are known as 'the fairy people'; they live a lot longer than humans, and most of them are female, for reasons unknown (convenient, eh?). They aren't well understood by 'civilized' humans and most cling to their old nature-worshiping ways (with some notable exceptions). They rarely show up in human cities and are not welcome there, mostly because of the ongoing Holy war, where most people equate elves with the enemy.

Cimeria: An extinct race of technology-advanced beings, about which very little is known. Some say they were the dwarves or gnomes of legend. Little is left of their once mighty empire, but their ruins and artifacts still lie beneath the foundations of Zan.

The City Guard: Responsible for maintaining order in the lower quarters of Zan, they are an organized militia paid for by city taxes.

The Knight orders: In charge of the higher quarters of Zan, the knights are high-born and sworn to protect the King, although most of them also leverage their position to advance the interests of their noble family.

The Ninja Dojos: All over Xeros, ninja dojos act as training grounds, shelters and temples for the ninja and their apprentices. Each follows a given 'school' blending martial arts and combat magic. The ninjas usually work for hire, serving all sides of the many conflits plaguing Xeros, but some take sides and even forge long-lasting alliances with powerful factions.
Ninjas can be male or female, but exceptional female ninjas can be elevated to the rank of 'Kunoichi'. Their activities are even more shrouded in myth and mystery than that of the regular ninjas.


The Holy War

Although the causes of the war are murky, it started as a concerted effort by the Church of Arios to settle the Holy lands and un-root the elder races and monsters that call it home.

Much like a real-world crusade, they called on volunteers from all-over Xeros to join the war effort: some out of faith, other for glory or gold. It was conceived as a simple expedition that would crush the local resistance in a matter of months. Instead, the war has been dragging on for many years with heavy casualties and little territory gain.

The Arios armies enjoy technological and numerical superiority, but suffer from ambushes, long and fragile supply lines, and lack of knowledge of the surrounding land and environment. Their adversaries, a loose coalition of resistance fighters drawn from local villages, regional powers, mercenaries and wandering monsters or marauders, appear to be uncoordinated, but manage to continuously wear down the Sun God's followers. Frustrated at their lack of progress, the Arios armies have been known to raid and loot peaceful elven, animal people and even human villages, and cause terror and mayhem as payback against their invisible enemies.

The burden in lives and coin of the war effort is being felt widely across Xeros and fuels prejudice and resentment, especially towards elves and other elder races that are unfairly seen as enemies, regardless of their actual involvement in the war.



Final note: Hints on writing 'canon' events

If you want to write events that may become part of the vanilla game, I recommend following a few tips below. Of course, when modding or creating stand-alone events, you're free to do exactly as you please and move the story in another direction altogether.

Matching the game setting and tone

The game is set in a classic fantasy setting with some elements of steampunk. Magic, elves, monsters exist alongside humans, medieval weapons and renaissance guns...
This loose setting allows almost all kinds of stories and pictures to fit in.

While this setting gives you a very broad sandbox to play with, there are some story lines that will not necessarily fit in (modern high school drama, giant robot sci fi, 21 jump street fan fic, you name it). Use your best judgement and try to fit the setting.

As far as 'tone' is concerned, I'm going for a traditional 'light eroge setting' such as the one in Alicesoft games, for instance, which does not mean there cannot be some dark moments and story lines, but it's clear that terrible tales of bloody revenge, depressing emo drama or gory horror stories will likely not fit the general mood of Brothel King. Once again, use your best judgement to try and match the game's tone.

Allowing for different play styles

There are good and evil characters in the world of BK, and the best written events will reflect that, as well as the diversity of gods, classes, factions that the player can choose from.

Using existing locations and NPCs

When using elements from the game such as locations, NPCs... Feel free to draw inspiration from what's there or to create your own. It's safe to assume that I have a precise plan for every named character in the game.

But as long as you don't go too far, killing them off or changing their personalities in-depth, you're welcome to use them within your own events.
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

Vaan

#5
Hi Goldo,

I had an idea about expanding the bisexual tag by creating some events, was wondering if you would be able to point me in the right direction. At first i wanted to be able to mix two packs with tags, so that if one girl is included in the other girl's pack and you have them both, they will both appear in the event or in training, instead of calling Sil. I feel like it's a bit too complicated and came up with another idea. I wanted to check if instead of mixing packs of photos, there is an event which can include and play them one of the other. What i mean by that is, i want to create an event which includes more than one girl, will i be able to add a code which  plays images from 2 - 3 packs or more, one after the other? For instance, taking the constitution event and adding more girls to it. Instead of starting the event with only one other person, you meet 2 - 3 or more. The event then plays their constitution images, one from each pack, one after the other. Then i simply call that event "Sports Day" or something. The idea of it being, that more people are included in it and it gives you the feeling that you actually have more people in the brothel when you recruit more, instead of doing events with one person. I have this idea to try and expand some of your events and create some of my own, by including more girls into them, by playing their packs one after the other. Hope you can give me some pointers if something like that is achievable? I'm not really good at coding and i want to try and make this my first project. If it's not too hard, i will eventually use that as a base to include battle events, where if a girl has a perk warrior or something, she will be able to join those events and fight. Kind of like a mini rpg game with different characters. Her constitution and defense points will be considered and so on. I wanted to get your opinion first, because you know the game better than anyone, i want to know what i'm getting myself into and whether you think it's something too difficult for a beginner?

neronero

#6
The multi-girl bisexual events sound complicated to me, because there aren't any image tags that allow you to identify who the secondary girl is in a bisexual/lesbian picture. One way around this would be to hardcode the event to only work with specific girlpacks of your own making, but then you're putting in quite a lot of effort into a very niche event that only works under very specific conditions.

The "Sports Day"-type event on the other hand seems very achievable. Let's look at a 1-girl constitution event for inspiration (from BKday_events.rpy) and examine what we would need to change to include multiple girls:

label random_morning_events():

    # This event is a hub dispatching the various events that can happen in the morning (this avoids several events popping up at once)

    # Girl events

    $ able_girls = [g for g in MC.girls if not (g.away or g.hurt or g.exhausted)]

    if able_girls:
        $ girl = rand_choice(able_girls)
First in the line ($ able_girls...) a list of eligible girls is created by copying over every girl that's in the brothel, as long as they're not away or hurt or exhausted. Next, if that list is not empty (if able_girls:), then out of that list a random girl is selected for the event ($ girl = rand_choice(able_girls)).

This bit you would want to change to:
1) Make sure not to start the event unless there are multiple girls in the list instead of just checking that it's not empty (as many as you want to use in the event)
2) Give the random girl you pick out of the list a more unique identifier than "girl" ("girl1" will do)
3) Remove "girl1" from the able_girls list
4) Select another random girl like in step 2 with a unique identifier ("girl2")*

*There might actually be a way to instantly pick 3 random girls within a single line of code so you don't need to repeat step 3 for each girl, but this is how I would code it as a fellow amateur.

On to the event code itself:

            # Constitution event

            if ev_type == "constitution" and girl.energy >= 25:

                $ renpy.show_screen("show_img", brothel.pic, _layer = "master")
                with fade

                "As you come out for some fresh air in the early morning, rubbing the sleep from your eyes, you are surprised to meet [girl.fullname], already up and running."

                show screen show_event(girl.get_pic("constitution", "dance", "profile", naked_filter=True, soft=True), x=config.screen_width, y=int(config.screen_height*0.8), bg=None)
                with dissolve

                girl.char "One, two, three, four..."

                "She is doing her morning exercise, bursting with energy."

Wherever it says "girl" in this part of the code, you can now use "girl1", "girl2", "girl3".
For example:

                # show a picture of girl3 exercising

                show screen show_event(girl3.get_pic("constitution", "dance", "profile", naked_filter=True, soft=True), x=config.screen_width, y=int(config.screen_height*0.8), bg=None)
                with dissolve

                # the other girls comment

                girl1.char "Wow, look at her go... Where does she get the energy?"

                if girl2.personality.name == "creep":
                    girl2.char "I want to taste her sweat!"
                else:
                    girl2.char "Let's join her!"
My Girl Packs: [ link ] - Trait King mod: [ link ]

Vaan

I'll give it a go, thank you. Have been trying to copy some of the original code and change it around a bit for the past few hours, and i keep getting errors...I'll give your example a try tomorrow and see where it leads me. Thank you!

Hareb

#8
The sports day sounds like a good idea for an event.  8)

I just wanted to add: if enjoy writing, there is still one personality (Easy) up for grabs in the Community Dialogue Project.

It doesn't require knowledge of Python, but will familiarise you a bit with how the markup in Ren'Py works. I've been planning to get into writing events once I'm done with dialogue.

Vaan

Thank you, i'll give it a go over the weekend and see how it feels, it was nothing but errors yesterday and i gave up. I will give it a try when i'm not working and see what happens. I have so many ideas for this game, but i have no idea how to make them a reality and it's a bit frustrating haha. Will let you know if i go through with it :)

neronero

I started out the same way ;D in fact I'm still outstanding at producing errors.

Feel free to share your progress/errors if you're starting to get a headache from banging your head into the wall.
My Girl Packs: [ link ] - Trait King mod: [ link ]

Vaan

#11
Will do, thank you! I think i'll start small and just add a function after function to familiarise myself with coding. I thought i could do it all immediately and went to try what was probably the more advanced code. I started small today, by just adding some sound and a dialogue, will slowly build up on that, was happy when it worked

GoldoTopic starter

#12
Quote from: Vaan on May 23, 2022, 06:12 PMHi Goldo,

I had an idea about expanding the bisexual tag by creating some events, was wondering if you would be able to point me in the right direction.

Ouch, wall-of-text alert ;)

I will try to break it down in smaller sections and answer your questions.


QuoteAt first i wanted to be able to mix two packs with tags, so that if one girl is included in the other girl's pack and you have them both, they will both appear in the event or in training, instead of calling Sil. I feel like it's a bit too complicated and came up with another idea.
Some tips to help you achieve this:

1/ How to check if a girl exists in your brothel with the right template:
$ girl_list = [g for g in MC.girls if g.pack_name == "Boa Hancock"]

if girl_list:
    $ girl = rand_choice(girl_list)

This code will check if one or more of the brothel girls follows the Boa Hancock template (must be spelled like the girl pack folder name), and return one of them as "girl", or False if there are none.


2/ How to create a girl on the fly (if you'd like her to show up anyway):
$ girl = create_girl("Boa Hancock", free=False, force_original=True, level=1)
The first argument is the girl pack folder name. The next 3 arguments allow you to create either a slave or a free girl, decide if she's an original or a clone, and decide her starting level. They can be omitted if you are fine with the default options above.

3/ Where should you edit the code to add the extra girl:
Check 'BKinteractions.rpy' and check the references to "bisexual" acts to edit those sections.

QuoteI wanted to check if instead of mixing packs of photos, there is an event which can include and play them one of the other. What i mean by that is, i want to create an event which includes more than one girl, will i be able to add a code which  plays images from 2 - 3 packs or more, one after the other? For instance, taking the constitution event and adding more girls to it. Instead of starting the event with only one other person, you meet 2 - 3 or more. The event then plays their constitution images, one from each pack, one after the other. Then i simply call that event "Sports Day" or something. The idea of it being, that more people are included in it and it gives you the feeling that you actually have more people in the brothel when you recruit more, instead of doing events with one person. I have this idea to try and expand some of your events and create some of my own, by including more girls into them, by playing their packs one after the other. Hope you can give me some pointers if something like that is achievable? I'm not really good at coding and i want to try and make this my first project.

Some pointers:

1/ How to get several random girls from your brothel:

if len(MC.girls) >= 3: # Important to check that there are enough girls in the brothel before attempting this
    $ girl1, girl2, girl3 = rand_choice(MC.girls, 3)
This will fetch 3 girls from the brothel, but you can of course edit the code to fetch a different number of girls. If you want to fetch girls from the city instead, you could replace instances of 'MC.girls' with 'game.free_girls'.

2/ How to display a girl's picture

neronero's suggestion is fine:
# show a picture of girl3 exercising
$ pic = girl3.get_pic("constitution", "dance", "profile", naked_filter=True, soft=True)
show screen show_event(pic, x=config.screen_width, y=int(config.screen_height*0.8), bg=None)
with dissolve

Some explanation of what's going on here.
$ pic = girl3.get_pic("constitution", "dance", "profile", naked_filter=True, soft=True)This part will look for a picture from girl3 in the following order of preference: 'constitution', then if not found 'dance', then if not found 'profile'. The picture will be naked or not depending on girl's current status, and exclude hardcore acts.

show screen show_event(pic, x=config.screen_width, y=int(config.screen_height*0.8), bg=None)This part displays the image as an event that takes up 100% of the screen width and 80% of the screen height (leaving enough room at the bottom for text). There is no background (bg).

with dissolveThis adds a dissolve transition to make the display smoother.

Once the event is done, you'll want to hide it with the following code:
hide screen show_event
with dissolve

This will be fine for a start. For more in-depth understanding, check the 'get_pic' picture in BKgirlclass.rpy (but be warned that it is quite complex).

QuoteIf it's not too hard, i will eventually use that as a base to include battle events, where if a girl has a perk warrior or something, she will be able to join those events and fight. Kind of like a mini rpg game with different characters. Her constitution and defense points will be considered and so on. I wanted to get your opinion first, because you know the game better than anyone, i want to know what i'm getting myself into and whether you think it's something too difficult for a beginner?
I definitely don't recommend biting more than you can chew at the moment, but yeah in the long long run it's definitely possible. The coding is not the hard part, the system design is. One word of caution: as I remember, the SimBro-like Pytfall devolved into a rpg battle sim at some point and this more or less killed the project. It's easy to overcomplexify things when designing new systems. I like to quote the KISS mantra, even though I often fail at it.
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

GoldoTopic starter

Does anyone have a copy of the cool map that someone made to illustrate the lore?
Maker of BK. Looking for the latest patch for BK 0.2? The link doesn't change, so bookmark it!

neronero

My Girl Packs: [ link ] - Trait King mod: [ link ]