Rules System - Monika-After-Story/MonikaModDev GitHub Wiki

Introduction

Since version 0.7.4 a new rule-based system for Event has been introduced, with this system event's availability can be determined by checking the diverse rules that an event can have. The rules currently include time based repetition rules, affection range based rules, special random chance of selection rules for greetings and farewells.

Repetition rules

These rules check for time based intervals to determine whether or not an event can be repeated.

MASNumericalRepeatRule

This rule is defined by a repeat property which specifies the time interval for the repetition and the advance_by property which specifies how many of the time intervals the next repetition is going to get scheduled. This rule is intended to help updating the start_date and end_date of the Event containing this rule, so it is intended to play nicely with the current calendar system.

An example of how this rule works:

Let's suppose we have an Event scheduled for January 1st of 2018, if we want this event to repeat on January 1st of 2019 we just add a new Numerical rule specifying the repeat property to year and the advance_by to 1. If we wanted to make that event run each two months we would have defined the repeat property to month and the advance_by to 2.

The repeat accepts only the values: "day", "week", "month" and "year". The advance_by accepts any integer higher than 0.

Code example:

init 5 python:
    rules = dict()
    rules.update(MASNumericalRepeatRule.create_rule(repeat=EV_NUM_RULE_YEAR))
    addEvent(
        Event(
            persistent.greeting_database,
            eventlabel="greeting_example", 
            start_date=datetime.datetime(2018, 2, 1),
            end_date=datetime.datetime(2018, 2, 2),
            unlocked=True, 
            rules=rules
        ),
        eventdb=evhand.greeting_database
    )
    del rules

label greeting_example:
    m "Oh, hello [player]!"
    m "This is just an example"

MASSelectiveRepeatRule

This rule is defined by a set of parameters: seconds, minutes, hours, days, weekdays, months, years. Those parameters specify ranges for when the Event can be accessed. The rule can check against the current time or any arbitrary given time to see if it fits in the specified ranges(usually is against current time unless we're doing something special).

An example of how this rule works:

Let's suppose we have an Event that we want it to be available only from 9am to 4:59 pm, to achieve that we need to add a new Selective rule with the hours property containing an array containing [9,10,11,12,13,14,15,16], that array can be defined also with the python built-in range function: range(9,17) that way it feels more natural to use it. This rule isn't limited to use only one of it's properties, for example to specify that an Event is only available on friday 13th of any month we would specify a rule with the property days set to [13] and the property weekdays set to [4] (weekdays start on monday = 0 and end on sundays = 6).

Each property is validated to only accept valid time intervals.

Code example in a farewell:

init 5 python:
    rules = dict()
    rules.update(MASSelectiveRepeatRule.create_rule(days=[13],weekdays=[4]))
    addEvent(
        Event(
            persistent.farewell_database,
            eventlabel="bye_special_friday",
            unlocked=True,
            rules=rules
        ),
        eventdb=evhand.farewell_database
    )
    del rules

label bye_special_friday:
    m "Bye [player]!"
    m "Example farewell"
    return 'quit'

Greetings rule

There's just one special rule only for greetings:

MASGreetingRule

This rule it's only used to define two things: first if the greeting should skip the visual initialization and second to define if the greeting has a special random chance of appearing. This is done by using the properties skip_visual and random_chance.

Code example:

define opendoor.chance = 20

init 5 python:
    rules = dict()
    rules.update(
        MASGreetingRule.create_rule(
            skip_visual=True,
            random_chance=opendoor.chance
        )
    )
    addEvent(
        Event(
            persistent.greeting_database,
            eventlabel="i_greeting_monikaroom",
            unlocked=True,
            rules=rules
        ),
        eventdb=evhand.greeting_database
    )
    del rules

label i_greeting_monikaroom:
    #Some code for this special greeting

Farewells Rule

For farewells we only have one rule defined:

MASFarewellRule

This rule only defines a special random chance for this Farewell to be available, the property name is random_chance

Code example:

init 5 python:
    rules = dict()
    rules.update(MASFarewellRule.create_rule(random_chance=10))
    addEvent(
        Event(
            persistent.farewell_database,
            eventlabel="bye_example",
            unlocked=True,
            rules=rules
        ),
        eventdb=evhand.farewell_database
    )
    del rules

label bye_example:
    m "Goodbye [player]!"
    return 'quit'

Affection based rules

With the introduction of the affection system on version 0.8.4, we can start using rules based on the current affection status of Monika.

As the moment of writing this guide we only have one affection rule.

MASAffectionRule

The rule is defined by the min and a max properties, both properties accept an integer number used to define the minimum and maximum affection for an event to be determined as available, both properties are inclusive. To express a range of "higher than", you must define the min property to your desired threshold and the max property to None. To express a range of "lower than", you must define the min property to None and the max property to your desired threshold. Both properties shouldn't be defined as None at the same time, since having no affection threshold means this rule would be useless, because it would return a positive availability always.

Right now the rule is only checked for greetings, and it's only intended to determine availability it doesn't force selection.

Code Example

init 5 python:
    rules = dict()
    rules.update(MASAffectionRule.create_rule(min=160,max=None))
    addEvent(
        Event(
            persistent.greeting_database,
            eventlabel="greeting_high_affection",
            unlocked=True,
            rules=rules
        ),
        eventdb=evhand.greeting_database
    )
    del rules

label greeting_high_affection:
    m "Welcome back my love!"
    return