-
Notifications
You must be signed in to change notification settings - Fork 684
Dialogue Coding
init 5 python:
addEvent(
Event(
persistent.event_database,
eventlabel="monika_twitter",
category=['monika'],
prompt="Twitter",
random=True
)
)
label monika_twitter:
m 1eud "Did you know I'm on Twitter?"
# ...
return
Standard dialogue (dialogue that is brought up randomly or is trigger by the player using the "Say/Hey Monika" option) known as a "topic". Topic creation consists of two parts: the init 5 block
and the actual dialogue. The init 5 block
assigns properties to the topic, which can change how the topic can be seen and where it can be found.
While "Topic" is used to refer to standard dialogue, the structure behind a topic is an Event
. The init 5
block is used to assign properties to these Event
s as well as tell the system that an Event
exists.
The Event
object can accept several properties, the most commonly used are shown here:
init 5 python:
addEvent(
Event(
persistent.event_database,
eventlabel="monika_topic_name",
category=["category name", "another category name"],
prompt="Prompt Name",
random=True,
pool=True,
conditional="<python_expression_here>",
action=<EV_ACTION_HERE>,
start_date=datetime.date.today(),
end_date=datetime.date.today() + datetime.timedelta(days=1),
rules={},
aff_range=(mas_aff.NORMAL, None)
)
)
-
eventlabel
:- The label for your topic.
- This should correspond to the label used for the actual dialogue.
- Standard topics should use a label prefix of
monika_
. - This is required.
-
category
:- A list of categories (names) this topic belongs to.
- These should always be lowercase.
- This is used when viewing the topic in "Repeat Conversation" or "Hey Monika".
- Note that if this is not provided, topics will show up in the category list instead of in a category.
-
prompt
:- The text shown on the button that will trigger this topic.
- If the prompt is a title, then the prompt should be capitalized as the title is. If not, only the first word should be capitalized
- This is used when viewing the topic anywhere in the "Talk Menu".
- Note that if a prompt is not provided, its eventlabel will be used instead, and will be visible.
-
random
:-
True
will allow this topic to be shown randomly. - This should be used for topics where Monika initiates the conversation. (Default:
False
)
-
-
pool
:-
True
will allow this topic to appear in the Unseen menu as well as the "Hey Monika" menu. - This should be used for topics where the player initiates the conversation. (Default:
False
)
-
-
conditional
:- A string conditional representing the condition which must be met in order for this topic's
action
property to be executed - This is essentially useless if there is no
action
set
- A string conditional representing the condition which must be met in order for this topic's
-
action
:- An action to use when the Event's
conditional
and (if applicable)start_date
andend_date
properties are all satisfied - Available actions:
-
EV_ACT_QUEUE
:- Queues the event
-
EV_ACT_PUSH
:- Pushes the event
-
EV_ACT_RANDOM
:- Makes the event random
-
EV_ACT_POOL
:- Makes the event pool
-
EV_ACT_UNLOCK
:- Unlocks the event
-
- An action to use when the Event's
-
start_date
:- Marks the
date
/datetime
that the event can be shown on. - This date is inclusive. (
action
can execute on this date)
- Marks the
-
end_date
:- Marks the
date
/datetime
that you can no longer see the event. - As a
datetime.date
, it is exclusive, meaning that the last day theaction
can be executed is the day before theend_date
. - As a
datetime
, as long as the current time is before the time of theend_date
, then theaction
can be executed.
- Marks the
-
years
:- Marks what years this topic's
start_date
,end_date
, andconditional
properties will be maintained through (the topic's action will retrigger on those years if all conditions are met and the properties will not be wiped after performing theaction
- If an empty list (
[]
) is provided, the topic will always repeat annually
- Marks what years this topic's
-
rules
:- A dictionary of rules for the event
- Available rules:
-
"no_unlock"
:- Only applies to
pool
topics. - Takes no value.
- Ensures that the topic will not be unlocked via random pool unlocks.
- Only applies to
-
"skip alert"
:- Only applies to
random
topics - Takes no value.
- Ensures that when the topic is brought up by Monika, no notification is shown for a topic alert.
- Only applies to
-
"bookmark_rule"
:- Acceptable values:
-
mas_bookmarks_derand.WHITELIST
- Marks this topic as bookmarkable. (use if theeventlabel
doesn't have an acceptable prefix) -
mas_bookmarks_derand.BLACKLIST
- Marks this topic as non-bookmarkable. (use this if the topic shouldn't be able to be bookmarked, but has an acceptable prefix)
-
- Acceptable values:
-
"notif-group"
:- Accepts a notif-group value. (string representing a group to send the notification under)
- Only applies to WindowReacts.
-
"force repeat"
:- Only applies to random topics.
- Takes no value.
- Forces this topic to be repeatable even if repeat topics is set to
False
- Generally, this should NOT be used for topics. Exceptions are for event related topics or for delegate random topics
-
"no_rmallEVL"
:- Only applies to topics with a registered
MASUndoActionRule
which will derandom the topic. - Takes no value.
- Ensures the topic isn't removed from the event list when the Undo Action Rule executes and the topic is derandomed.
- Only applies to topics with a registered
-
-
unlocked
:-
True
will make this topic show up in its respective collection (Hey Monika/Repeat Conversation) by default. - You should only really need to set this to True on
pool
topics. (Default:False
)
-
-
aff_range
:- This limits the availability of the topic based on Monika's current affection.
- Using
None
will specify unlimited range, so using(mas_aff.NORMAL, None)
means that the topic is available from NORMAL affection and above.
The following properties will NOT be changed if event objects already exist for the eventlabel (loading in with an addEvent for the eventlabel):
random
unlocked
pool
conditional
action
start_date
end_date
aff_range
, category
, rules
, and prompt
will always revert to the value in the addEvent
.
-
BROKEN
- Monika appears broken -
DISTRESSED
- Monika looks sad -
UPSET
- Monika shows a neutral, uninterested expression. This does not mean the literal meaning of upset -
NORMAL
- standard affection. Monika has the standard smile (1eua) -
HAPPY
- Monika shows happier expressions -
AFFECTIONATE
- Monika is affectionate -
ENAMORED
- Monika is enamored with the player -
LOVE
- Monika is completely comfortable with the player
See definitions.rpy
for the full list of properties. Many of these properties are specific to certain types of events and are not for standard dialogue usage.
Dialogue is standard Ren'Py dialogue code. The general format is:
m spritecode "Dialogue"
If you look through some of the dialogues, you'll find that some topics end in a return "derandom"
, return "no_unlock"
, return "love"
, and in some cases, a combination, return "love|derandom"
.
Each of these do something different. Below are the available return keys and their usage:
-
"derandom"
:- Only has an effect on random topics
- Used for derandoming a topic after it's finished
-
"no_unlock"
:- Works ONLY for random topics
- Will ensure that the topic is not unlocked (doesn't have its prompt show) in repeat conversation
- NOTE: This has no effect if the topic is already unlocked when this key is returned
-
"rebuild_ev"
:- Rebuilds the event lists
- For the most part, you'll never use this. It's only used to rebuild the lists in case a major flag has been set which requires the available topic pool to be regenerated (for example, sensitive mode)
-
"idle"
:- Puts MAS into idle mode (brb mode)
- Used at the end of brb events to enter idle mode for the brb
-
"love"
:- Turns the "I love you!" prompt on the main talk screen to "I love you too!"
- Should be used if the topic has "I love you" somewhere close to the end of it
-
"quit"
:- Allows Monika to close the game herself (safely)
- Should be used for farewells
-
"prompt"
:- Returns you to the main talk screen from the topic
- Should be used for topics which start with a
mas_gen_scrollable_menu
or something of the sort as a part of theNevermind.
option
As in the example above, return keys can be combined by simply putting a bar character (|
) between keys, without spaces.
MAS has a fairly powerful sprite system which can handle numerous different expressions, poses, and other things too.
Dialogue uses spritecodes, to build these expression spritecodes visually, you can use the Expression Previewer.
You'll notice after using this a little that spritecodes will be represented in either pink or red text.
- If a spritecode appears in pink, the sprite exists in the current source code and can be used without issue in your dialogues.
- If a spritecode appears in red, the sprite does not exist in the current source code and using it in dialogue will have Monika dissapear.
Don't let this push you away from using red spritecodes, though. If you think that sprite works for your dialogue, add it in. We've also added a special set of tools to help you create these sprites too. We'll address this in the following section.
With the source code of the Monika After Story project, there's a certain file containing some useful utilities.
Head over to MonikaModDev/tools/toolsmenu.py
and run it with Python 2. From here, you'll see something like this:
#=============================================================================#
# MAS Dev Tools #
#=============================================================================#
1) Sprite Puller
2) Check Sprites
3) Make Sprites
4) Generate Expressions Test
[0] Exit
Utility:
- Sprite Puller
#=============================================================================#
# Sprite Puller #
#=============================================================================#
1) Generate Sprite Code List
2) Generate Optimized RPY
[0] Exit
Option:
- For the most part, you shouldn't need this.
- What you might find useful in this is the first option within it, allowing you to generate a list of sprites for Monika (this is exported to
MonikaModDev/tools/zzzz_spritelist
).
- Check Sprites
#=============================================================================#
# Include Dev? #
#=============================================================================#
1) Yes
2) No
[0] Exit
Option:
- This option will go through the rpy files in the
/game
folder of the repository and checks if all the spritecodes used (m spritecode "dialogue"
,extend spritecode "dialogue"
,show monika spritecode
, etc.) are all valid. - If they're not, the tool will mention it and export a list of invalid spritecodes with their filenames and line numbers in
MonikaModDev/tools/zzzz_badcodes.txt
. - You shouldn't need to
Include Dev
for this.
- Make Sprites
#=============================================================================#
# Sprite Maker #
#=============================================================================#
1) List Codes
2) Make Sprite (Interactive)
3) Make Sprite (By Code)
4) Generate Sprites
[0] Exit
Option:
- This option will allow you to generate your sprites.
- The first sub-option here allows you to view a list of all spritecodes with filters on certain features (pose, eyes, mouth, etc.)
- The next option allows you to make sprites by prompting you what kind of each part of the expression you want, and for optional parts, whether or not you want it.
- For example: what kind of eyes you want, (normal, winkleft, smug, etc.) or whether or not you want blush (and what type if you do want blush)
- The third option allows you to make sprites by the spritecode. If you're familiar with the expression system or you've used the expression previewer to make the sprite you want, simply enter its code and this will build the sprite for you based on that.
- The final option is used to export the sprites you made to the sprite-chart files. Use this when you're done making sprites. Be sure to confirm the overwrite of the rpy files to save them.
- Generate Expressions Test
- This is pretty much useless to you as it won't do anything to your scripts
MAS uses its own form of menus, the structure to follow is as such:
m expression "Question?{nw}"
$ _history_list.pop()
menu:
m "Question?{fast}"
"Option 1":
#Dialogue/code for this path
"Option 2":
#Dialogue/code for this path
#...:
#...
- The
{nw}
tag on the first Question line. This ensures the player sees the question before the options come up, and that they come up automatically. - The
$ _history_list.pop()
after the first question line. This makes sure that the question only appears once in the history tab. - The lack of
expression
on the second question line. Menus do not accept expressions inside them. - The
{fast}
tag on the second question line. This ensures that the line is shown instantly after the menu options come up.
if
is used when you want to make code execute or dialogue show if the provided condition is True
.
elif
is used after an if
. It also has a condition on it and is evaluated if the condition above it is False
.
else
is the fallback case. If none of the if
or elif
conditions evaluate to True
, else
is run. (Though it is not required to be chained with if
or elif
)
x = 3
if x == 1:
print("x is 1!")
elif x == 3:
print("x is 3!")
#There can be more conditions between here
else:
print("x isn't 1 or 3!")
In this example, the elif
block runs, and "x is 3!"
would be printed.
NOTE: that equality comparisons are done by using ==
instead of =
If you're checking variable string
s, use the following form:
if stringvar.lower() == "comparison":
pass
- This is done because
"Hello"
is not the same as"hello"
You can access the amount of times a topic has been seen using mas_getEV("eventlabel").shown_count
. (NOTE: that eventlabel
must be valid or you will get an error)
To have dialogue change on different repeats of topics, you can check the shown count during a topic, as it is only updated after it has been seen.
label monika_example:
$ ev = mas_getEV("monika_example")
if ev.shown_count == 0:
m 1hub "This is the first time you've seen this topic!"
elif ev.shown_count == 1:
m 3eub "This is the second time you've seen this topic."
#You can keep going here
else:
m 1wud "Wow [player], you've seen this topic so many times!"
return
The conditional
property of an Event
allows you to make your topic's action
property to happen if the conditional evaluates to True
.
If you would like your topic to be triggered at a certain time while the player is with Monika, Event
s have two properties for this, a start_date
and an end_date
property.
These are can be datetime.datetime
or datetime.date
objects and will work in tandem with the conditional if it is present (It is possible to use start/end dates exclusively or conditionals exclusively)
These properties also will make the action
property happen.
-
EV_ACT_QUEUE
- queues an event -
EV_ACT_PUSH
- pushes an event (higher priority than queue) -
EV_ACT_RANDOM
- sets the event'srandom
property toTrue
(can be brought up in random chatter) -
EV_ACT_POOL
- sets the event'spool
property toTrue
(can be accessed through theHey [m_name]...
option in theTalk
screen) -
EV_ACT_UNLOCK
- unlocks the event (NOTE: This only allows the event to be seen in therepeat conversation
orHey [m_name]...
sections in theTalk
screen)
- The conditional must be written as a
string
- The condition must also be able to be evaluated at
init 5
(You cannot use methods defined at higher init levels) - Using a start or end date will make the event's
prompt
(eventlabel
if not present) show up on the calendar by default. (This can be avoided by using theskipCalendar
parameter) -
end_date
s are not inclusive.start_date
s are
init 5 python:
addEvent(
Event(
persistent.event_database,
eventlabel="monika_example",
prompt="The Southern hemisphere"
category=["misc"],
conditional="persistent._mas_pm_lives_south_hemisphere",
start_date=datetime.date(2019, 4, 15),
end_date=datetime.date(2019, 4, 16)
action=EV_ACT_PUSH
)
)
label monika_example:
#dialogue
return
This example topic will be pushed if you tell Monika that you live in the Southern hemisphere and it is between April 15th and 16th in 2019.