From 7b813b54f98fadaddca3722f6d7d023b57f2b009 Mon Sep 17 00:00:00 2001 From: Elijah Voigt Date: Thu, 10 Jul 2025 21:31:36 -0700 Subject: [PATCH] Add readme for trees game --- src/bin/trees/README.md | 193 ++++++++++++++++++++++++++++++++++++++++ src/bin/trees/main.rs | 8 +- 2 files changed, 198 insertions(+), 3 deletions(-) create mode 100644 src/bin/trees/README.md diff --git a/src/bin/trees/README.md b/src/bin/trees/README.md new file mode 100644 index 0000000..42854a0 --- /dev/null +++ b/src/bin/trees/README.md @@ -0,0 +1,193 @@ +# 🌲 Trees 🌳 + +## How to Play + +> currently in hella alpha so subject to change and/or be out of date + +* Left click a tree to start a Monologue +* Right click + drag to move a tree +* Middle Click to delete a tree +* F12: Debug Menu + * Click a monologue script to spawn a tree + +## Monologue File Format + +In `assets/trees/` there are `.mono` files that contain the monologues that drive this game. + +Here is an example of a simple monologue: + +``` +This is a simple monologue + +There are two options for this fist batch + +--- + +This is the second batch of lines + +There are three options + +You get the idea + +--- + +This has one option +``` + +* Files contain "Monologues" +* Monologues are broken up into "Line Option" batches +* Lines are separated by one or more blank newlines +* Batches are broken up by lines with `---` + +> Monologue vs monologue, Batch vs batch, and Line vs line. +> The capitalized versions specify a game object, the lower case specifies the common meaning of the word. + +### Comments + +Comments are lines that start with a `#`. +Comments are discarded by the parser so are only for the reader of the raw text files. + +``` +# This is a comment +This is a dialog line +# If you connect two lines with a comment +They count as part of the same line + +# Comments can exist on their own + +This line of monologue # Will include the comment +# So always start a line with the comment +``` + +### Empty batches + +Batches with no lines are a no-op. +Even if the batches contain comments and/or directives. + +## Monologue Directives + +> This feature is in planning, not implmeneted + +Monologue Directives are basically how we "script" monologues. + +With directives you can: +* Set variables based on what a user sees or does. +* Add pre-requisites to a line or entire Monologue. +* Requirement that an "actor" meets some criteria. + +In general directives can be set at the Monologue, Batch, and the Line scopes. +* At the Monologue scope they must be set at the top before any batches. +* At the Batch scope they must be separated from Lines by at least one blank line. +* At the Line scope they must be on an adjacent Line. + +Example: + +``` +# This directive affects the monologue as a whole +@directive + +--- + +# This directive affects this entire group +@directive + +this is a line + +# This directive just affects this line +@directive +this is another line + +# This directive also affects the entire group +@directive + +last line in this batch + +--- + +# This batch has no directives + +option one + +option two + +``` + +### `@set var val` + +The `@set` directive sets a variable to a given value upon the user interacting with the affected scope. + +* At the Monologue scope this is set when the monologue starts. +* At the Batch scope this is set when the user views the Batch. +* At the Line scope this is set iff the user chooses the Line. + +Example: + +``` +# Monologue scope +@set foo 1 +--- +# batch scope +@set bar true + +# Line scope +@set baz "value" +this line sets baz to "value" +--- +this batch... + +...has no directives +``` + +### `@if var op val` + +The `@if` directive is a constraint requiring `var op val` to return true for the scope to be visible. + +* At the Monologue scope this causes the monologue to either be or not be in rotation. +* At the Batch scope this causes the Batch to be included or skipped from a Monologue. +* At the Line scope this causes the line to be included or excluded from a Batch. + +### `@has var op val` + +The `@has` directive constrains which trees can deliver a given monologue. +For example if a tree has `family` set to `fir` it could deliver a monologue about being a fir tree. + +``` +@has family = "fir" +--- +man i love being a fir tree +``` + +At all scopes this operates similarly to `@if`, skipping/including Monologues/Groups/Lines based on tree properties. + +### Other possible directives + +The following directives are not strictly required but might be "nice to have": + +* `@after a.mono`: This monologue should happen _after_ `a.mono`. + * Could be achieved with `@set` and `@if` +* `@in scenario`: This monologue relates to a specific random scenario. + * Could be achieved with backend setting values and `@if` +* `@bump var`: Increases a variable's value by 1. + * Requires a specific use-case. + * Causes types headaches if `var` is not an integer. +* `@event event_name`: This Monologue/Batch/Line triggers an in-game event. + * Could be achieved with `@set` and `@if` + +### Monologue Templating + +With variables we can template monologues like so: + +``` +This is a regular line of dialog + +This line is templated, mentioning {{ some_event_outcome }} +``` + +Templated variables add an implicit constraint to that line, so the above is equivlent to: + +``` +This is a regular line of dialog + +@require some_event_outcome +This line is templated, mentioning {{ some_event_outcome }} +``` diff --git a/src/bin/trees/main.rs b/src/bin/trees/main.rs index 54961a3..f0189ec 100644 --- a/src/bin/trees/main.rs +++ b/src/bin/trees/main.rs @@ -431,6 +431,7 @@ fn dialog_box_visibility( }; } +/// Add the "script: path/to/file.mono" tooltip info fn monologue_asset_tooltip( mut over_events: EventReader>, mut out_events: EventReader>, @@ -516,8 +517,8 @@ fn scale_window(events: EventReader, mut window: Single<&mut Wind } fn delete_tree(trigger: Trigger>, mut commands: Commands) { - if matches!(trigger.event.button, PointerButton::Secondary) { - info!("Right Click -> Despawning {}", trigger.target()); + if matches!(trigger.event.button, PointerButton::Middle) { + info!("Middle Click -> Despawning {}", trigger.target()); commands.entity(trigger.target()).despawn(); } } @@ -559,7 +560,8 @@ fn spawn_debug_buttons( .observe(toggle_debug_button_color_over) .observe(toggle_debug_button_color_out); }); - // Spawn a tree too to make the game feel like it's doing something + + // Spawn a tree too to make the game feel like it's doing something at startup commands.spawn((Tree, TreeMonologue(handle.clone()))); } });