-
Notifications
You must be signed in to change notification settings - Fork 19
7. Cutscenes
Note
This page is a work in progress. The information here is not exhaustive, as it was written early after the maybe engine update, when we first got access to .mist files.
The following guide was written by discord user pixie. (thank you, pixie!)
Each event will need two files to function: A .toml file for the properties of the cutscene, and a .mist file that contains the actual script for the event.
[meta_properties]
id = "3039d41c48118979" // a 16 digit hexadecimal string
asset_kind = "Mist" // will always be "Mist" for events
[asset_properties]
// none of the vanilla events have asset_properties, testing will be required to figure this outThe type of action block determines in what order actions will take place. If an action is not inside a block, the default behaviour is that they will happen sequentially (i.e. in a queue, never overlapping).
Different types of blocks can be nested inside each other (see example event).
| block | description |
|---|---|
sim{} |
'simultaneous': placing different threads in this block will make them all run parallel to each other. All threads will need to end before calls outside the block trigger |
free |
any action triggered after this will run until the animation ends or it is stopped/replaced (in the case of music). The action is run in parallel to any other actions |
free sim {} |
same as sim, but whenever one of the threads end, the next call outside the free sim block will be triggered. |
fun |
'function': create a function that can be reused in the event. |
Below is a more readable list of all the common functions that can be called. To see how these actually work, see the std.mist file.*
// MUSIC
request_music_play(track)
request_music_stop(seconds)
play_sound(sound effect)
//CAMERA FUNCTIONS
scene(location)
camera_position(trellis point)
pan_camera(seconds, trellis point)
fade_in(seconds)
fade_out(seconds)
camera_in()
camera_out()
//TIME
timelapse(target time, length)
clock_jump(time)
wait(seconds)
wait_one_tick();
//NPCs + ARI
place_actor(npc, direction, trellis point)
remove_actor(npc)
face(npc, direction)
animate(npc, animation name)
drink_item(npc, prop) // has to be an item that has a drink animation
anim_speed(npc, speed) // will change whatever animation the npc is currently on. 0-1, 0 being a full stop
await_npc_animation(npc)
bark speech(bark icon, npc)
set_move_speed(npc, speed)
set_outfit(npc, outfit)
walk(npc, trellis point)
walk_slow(npc, trellis point)
use_door(npc)
chat(npc a, npc b)
stop_chat(npc)
//ARI SPECIFIC
freeze_ari() // this only works for ari. To stop an NPC's animation, use anim_speed
unfreeze_ari()
set_ari_to_idle()
freeze_ari_on_last_frame()
set_ari_health(value)
set_ari_stamina(value)
give_ari_status_effect(effect, amount, hours)
await_ari_animation()
ari_set_attachment(item)
//PROPS
setup_prop(trellis point)
destroy_prop(trellis point)
toggle_asset_visibility(asset name)
//DIALOGUE
write_world_fact(world fact, true/false)
next_line()
close_textbox()
open_textbox()
repeat_line()
get_response() // used to have specific forks/routes depending on the dialogue prompt a user picks. Should only be used after a next_line() call that has prompts
//example:
if (get_response() == 0) {
} else if (get_response() == 1) {
} else {}*As discussed by pale machine on discord, this is not an exhaustive list of all functions you have available to use. There are also world functions such as __override_post_process_time(hr,min) which is used in the Shooting Star Festival to change the game's time in post-processing. Most of these world functions typically begin with two underscores. For more world functions, see [a new page that I will have to make later after consulting anna and felix for a more comprehensive list and description of world functions]. - June
All cutscene data can be found in the mist_scripts folder. A few events I recommend based on experience if you want to see some that use a lot of functions together are March’s 4 heart (shorter) and March’s 6 heart (longer).
To move a character from one point to another, or to place props/set the camera, you will need to use trellis points, which are coordinates from the tile maps. A lot of the rooms come with their own existing trellis points.
For a full list of the existing points, see the file named t2_location_descriptions in the fiddle folder. These points are usually more human readable (like "Kitchen Table Top Left" for the general store’s kitchen table), so you can use these without needing to create new ones. You would use these like this in the mist file:
camera_position("Kitchen Table Top Left")
walk(ari, "Kitchen Table Top Left")*Note 1: As of 06/15 I have not tested this with MOMI, I’ve only edit it in straight into the code. *Note 2: I haven’t tasted adding props points. Based on the old engine these take additional details such as the layer and the type of prop that is then referenced in the fiddle.
As creating trellis points requires coordinates, I recommend opening the tile map that you’d like to use to get a visual of where you want the prop/character to be in the map. These are found in the tiled\rooms folder.
Once you’ve gotten the coordinates of the point you want, you can scroll to the bottom of the .tmx file that you want to add a point to to find the existing points for that map. This is where we will want to add our new coordinates.
This is what the trellis points for March’s room looks like with added trellis points at ID 18 and 19.
</data>
</layer>
<objectgroup draworder="index" id="15" name="Lighting"/>
<objectgroup draworder="index" id="16" name="Meta">
<object id="15" template="../../../templates/obj_roomtransition.tx" type="obj_roomtransition" x="168" y="192">
<properties>
<property name="destination_id" type="int" propertytype="LocationId" value="14"/>
<property name="player_direction" type="int" value="0"/>
</properties>
</object>
</objectgroup>
<objectgroup draworder="index" id="17" name="TrellisPoints">
<object id="16" template="../../../templates/meta/obj_trellis_point_transition.tx" name="Blacksmith Store Door" type="obj_trellis_point_transition" x="148" y="197">
<properties>
<property name="direction" type="int" propertytype="Cardinal" value="0"/>
</properties>
</object>
<object id="17" template="../../../templates/meta/obj_trellis_point_default.tx" name="March Bed" type="obj_trellis_point_default" x="60" y="176"/>
<object id="18" template="../../../templates/meta/obj_trellis_point_default.tx" name="sleepover_ari_bed" type="obj_trellis_point_default" x="67" y="176"/>
<object id="19" template="../../../templates/meta/obj_trellis_point_default.tx" name="sleepover_march_bed" type="obj_trellis_point_default" x="53" y="176"/>
</objectgroup>
</map>There are 2 main ways that events are triggered in the game: with a quest, and without a quest. (Of course, there are other ways such as using functions in the GML files, but I’m not going to cover those here.)
These types of events are more simple to trigger: Once the player has reached the requirements needed, the cutscene is triggered once they enter a specific map (as a bounding box within the map).
All cutscenes are located in the cutscenes.toml file in the fiddle folder. All possible/default values are located at the top and have detailed comments noting what they do, so I recommend checking there fore more details.
The requirements{} field will determine what is needed by the player before the cutscene can be triggered. These can include any of the following (and likely more):
requirements = {
reached_date = { season = "spring", day = 2, exact = false }
unlocked_summit = true
repaired_haydens_farm = true
seen_cutscene = "find_the_weathervane_setup"
completed_quest = { quest = "procuring_the_sealing_scroll", days_after = 1 }
reached_heart_level.march = 8
has_left_house_today = true
is_festival_day = true
broke_fire_seal = true
is_dating = "adeline"
in_time_range = [24, 26]
}Additionally, you can write invert. in front of any requirement to say that the player must not have this requirement met. (i.e. invert.in_time_range = [24, 26] would mean that the player cannot be in the time range 24,26).
The trigger{} field then determines the location that the farmer must enter to trigger the event. You can indicate a bounding box or not depending on if you want the cutscene to be triggered when they enter the map, or when they reach a specific area of the map.
trigger = {
location = "eastern_road", bbox = [102, 132, 152, 176]
}
trigger = {
location = "farm"
}Most heart events in the game are triggered with a quest, meaning that you receive a letter, which then triggers a quest to start when you read it. The cutscene data for these types of quests are similar, however the trigger{} information and the requirement{} information is written in the letters .toml file rather than the cutscenes .toml file.
In this file, you’ll set the letter details, the quest that is started with the letter, and the requirements to get the letter.
[pie_in_the_sky]
subject_line = "In Need Of A Taste Tester"
local = """[Ari]
You've been in town too long without getting to taste test a new dish of mine. I think I've got just the recipe to try out on a hardworking farmer like you.
Come by the Inn when you get a chance!"""
npc = "reina"
quest_to_start = "pie_in_the_sky"
requirements = {
reached_heart_level = { reina = 2 }
}The quests are found under the fiddle folder, and inside the quests folder. Files are then separated based on the type of quest. This is where you will be able to set the name of the quest, the npc, and the quest description, and the rewards. If there are several stages to a quest it can also be set here:
[pie_in_the_sky]
name = "Pie in the Sky"
npc_for_icon = "reina"
description = "Reina asked me to meet her at the Inn to taste test a new dish."
rewards = [{ item = "wildberry_pie" }]
[[pie_in_the_sky.stages]]
objective_description = "Meet Reina at the Sleeping Dragon Inn."
queries = [{ cutscene = "reina_two_hearts", location = "inn" }]