Skip to content

Commit

Permalink
Update narrative and event system
Browse files Browse the repository at this point in the history
**Added**

- Support for YAML and JSON configuration files for game setup.
- New fields in the Event struct:
   add_subject: Adds a new subject to the room when the event is triggered.
   remove_subject: Removes a subject from the room when the event is triggered.
   move_subject_to_location: Moves a subject to a different room when the event is triggered.
- Error handling for missing or invalid event data.
- Proper error messages for parsing errors and missing data.
- Serialization and deserialization support for game progress saving and loading.

**Changed**

- Refactored handle_event function to improve readability and maintainability.
- Updated process_subject_movement function to handle subject movement and removal separately.
- Modified return_formated_message function to simplify the logic and improve performance.
- Enhanced error handling in the parse_input and json_parse_input functions.
- Improved documentation and code comments for better understanding and usability.
- Updated wasm examples

**Fixed**

- Fixed issue with multiple mutable borrows in the on_submit function.
- Fixed incorrect behavior when processing subject movement and removal in events.

**Removed**

- Removed unused dependencies and code snippets.
- Removed redundant and obsolete documentation.
  • Loading branch information
aimerib authored Apr 5, 2024
1 parent 55d8a32 commit 85364c2
Show file tree
Hide file tree
Showing 44 changed files with 4,173 additions and 2,285 deletions.
14 changes: 5 additions & 9 deletions .github/workflows/deploy_to_crates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@ jobs:
CARGO_INCREMENTAL: 0
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: jetli/[email protected]
- uses: actions/checkout@v4
- name: Setup wasm-pack
run: cargo install wasm-pack
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
Expand All @@ -29,6 +25,6 @@ jobs:
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}
- uses: katyo/publish-crates@v1
- uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
14 changes: 5 additions & 9 deletions .github/workflows/deploy_to_npm.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,11 @@ jobs:
CARGO_INCREMENTAL: 0
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- uses: jetli/[email protected]
- uses: actions/checkout@v4
- name: Setup wasm-pack
run: cargo install wasm-pack
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
Expand All @@ -33,7 +29,7 @@ jobs:
- name: Package file
run: wasm-pack build --target web --scope nightrunner --release
- name: Deploy to NPM
uses: JS-DevTools/npm-publish@v1
uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
package: ./pkg/package.json
Expand Down
41 changes: 10 additions & 31 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,9 @@ jobs:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- uses: actions/checkout@v4
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
Expand All @@ -30,41 +24,26 @@ jobs:
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.lock') }}
- name: Build
uses: actions-rs/cargo@v1
with:
command: build
run: cargo build
- name: Test
uses: actions-rs/cargo@v1
with:
command: test
run: cargo test
- name: Check fmt
uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
run: cargo fmt --all -- --check
- name: Clippy
uses: actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
run: cargo clippy -- -D warnings
wasm:
needs: ci
name: Test WASM library
env:
CARGO_INCREMENTAL: 0
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
target: wasm32-unknown-unknown
override: true
- uses: jetli/[email protected]
- uses: actions/checkout@v4
- name: Setup wasm-pack
run: cargo install wasm-pack
- uses: browser-actions/setup-firefox@latest
- name: Cache dependencies
uses: actions/cache@v2
uses: actions/cache@v4
with:
path: |
~/.cargo/bin/
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/target
Cargo.lock
.DS_Store
pkg
20 changes: 12 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "nightrunner_lib"
version = "0.2.1"
version = "0.3.0"
edition = "2021"
resolver="2"
authors = ["Aimeri Baddouh <[email protected]>"]
description = "A parser library for making text adventure games"
license = "Apache-2.0"
Expand All @@ -11,27 +12,30 @@ categories = ["parsing"]
keywords = ["engine", "parsing", "wasm", "game"]
readme = "README.md"


[lib]
crate-type = ["cdylib", "rlib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.8"
serde_json = "1.0"
regex = "1"
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
wasm-bindgen = { version = "0.2.92", features = ["serde-serialize"] }
serde-wasm-bindgen = "0.6.5"
rand = "0.8.5"
getrandom = { version = "0.2.12", features = ["js"] }
serde_yaml = "0.9.33"
console_error_panic_hook = "0.1.7"

[dev-dependencies]
pretty_assertions = "1.1.0"
wasm-bindgen-test = "0.3.29"
pretty_assertions = "1.4.0"
wasm-bindgen-test = "0.3.42"


[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
cursive = { version = "0.17.0", default-features = false, features = [
"crossterm-backend",
] }
cursive = { version = "0.20.0", default-features = false, features = ["crossterm-backend"] }
cursive-aligned-view = "0.6.0"

[[example]]
Expand Down
20 changes: 13 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ assert_eq!(json_result,
);
```

To run a rust example run
```shell
cargo run --example cursive_example
```

This example should give you a good idea on how to consume the library in rust, and how to structure you front-end for your game.

## Using the Wasm library

Add the nightrunner_lib package from npm to your repository:
Expand All @@ -50,7 +57,8 @@ yarn add @nightrunner/nightrunner_lib

You will need a bundler to use this package. Currently I recommend using
Vite. For examples on how to use Vite with this library check out the
`examples/wasm` folder in the repository.
`examples/wasm` folder in the repository. Another popular and well supported
bundler is webpack.

---

Expand All @@ -63,17 +71,15 @@ of the game when creating a new instance of the `NightRunner` class in JavaScrip

### Example:

```js
```ts
// This data can also be retrieved from an api endpoint with the browser
// fetch API.
import data from "./data.json";
import init, { NightRunner } from "@nightrunner/nightrunner_lib";

await init();
import { NightRunner } from "@nightrunner/nightrunner_lib";

// Load the NightRunner library.
// The NightRunner class expects stringified JSON data.
const nr: NightRunner = await new NightRunner(JSON.stringify(data));
let result = nr.parse("look");
const engine: NightRunner = new NightRunner(JSON.stringify(data));
let result = engine.parse("look");
// {"messageType":"look","data":"first room\n\nHere you see: \nan item1\nan item2\nsubject1"}
```
161 changes: 106 additions & 55 deletions examples/cursive_example/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,65 +89,116 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
fn on_submit(siv: &mut Cursive, query: &str) {
let nr = siv.user_data::<NightRunner>().unwrap();

let result = nr.parse_input(query);
match result {
Ok(parsing_result) => match parsing_result {
ParsingResult::NewItem(item_message) => siv
.call_on_name("room_text", |view: &mut TextView| view.append(item_message))
.unwrap(),
ParsingResult::DropItem(drop_message) => siv
.call_on_name("room_text", |view: &mut TextView| view.append(drop_message))
.unwrap(),
ParsingResult::Look(text) => siv.add_layer(
Dialog::around(TextView::new(text))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
),
ParsingResult::Inventory(inventory) => siv.add_layer(
Dialog::around(TextView::new(inventory))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
),
ParsingResult::EventSuccess(event_message) => {
let EventMessage {
message,
message_parts,
templated_words: _,
} = event_message;
siv.call_on_name("room_text", |view: &mut TextView| {
view.set_content(message);
view.append(&message_parts.get(&MessageParts::EventText).unwrap().clone());
})
.unwrap();
if query == "!rewind" {
match nr.rewind_state() {
Ok(rewind_message) => {
siv.add_layer(
Dialog::around(TextView::new(rewind_message.to_string()))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
);
}
ParsingResult::SubjectNoEvent(subject_text) => siv
.call_on_name("room_text", |view: &mut TextView| {
view.append("\n".to_owned() + &subject_text);
})
.unwrap(),
ParsingResult::Help(help_text) => {
siv.add_fullscreen_layer(ResizedView::with_full_screen(
Layer::new(
Dialog::around(TextView::new(help_text))
Err(e) => {
siv.add_layer(
Dialog::around(TextView::new(format!("{}", e)))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
);
}
}
} else if query == "!advance" {
match nr.fast_forward_state() {
Ok(fast_forward_message) => {
siv.add_layer(
Dialog::around(TextView::new(fast_forward_message.to_string()))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
);
}
Err(e) => {
siv.add_layer(
Dialog::around(TextView::new(format!("{}", e)))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
);
}
}
} else {
match nr.parse_input(query) {
Ok(parsing_result) => match parsing_result {
ParsingResult::NewItem(item_message) => {
siv.call_on_name("room_text", |view: &mut TextView| view.append(item_message))
.unwrap();
}
ParsingResult::DropItem(drop_message) => {
siv.call_on_name("room_text", |view: &mut TextView| view.append(drop_message))
.unwrap();
}
ParsingResult::Look(text) => {
siv.add_layer(
Dialog::around(TextView::new(text))
.dismiss_button("OK")
.h_align(HAlign::Center)
.fixed_height(28)
.fixed_width(90),
)
.align_center(),
))
.align_center(),
);
}
ParsingResult::Inventory(inventory) => {
siv.add_layer(
Dialog::around(TextView::new(inventory))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
);
}
ParsingResult::EventSuccess(event_message) => {
let EventMessage {
message,
message_parts,
templated_words: _,
} = event_message;
siv.call_on_name("room_text", |view: &mut TextView| {
view.set_content(message);
view.append(&message_parts.get(&MessageParts::EventText).unwrap().clone());
})
.unwrap();
}
ParsingResult::SubjectNoEvent(subject_text) => {
siv.call_on_name("room_text", |view: &mut TextView| {
view.append("\n".to_owned() + &subject_text);
})
.unwrap();
}
ParsingResult::Help(help_text) => {
siv.add_fullscreen_layer(ResizedView::with_full_screen(
Layer::new(
Dialog::around(TextView::new(help_text))
.dismiss_button("OK")
.h_align(HAlign::Center)
.fixed_height(28)
.fixed_width(90),
)
.align_center(),
));
}
ParsingResult::Quit => {
siv.quit();
}
},
Err(e) => {
siv.add_layer(
Dialog::around(TextView::new(format!("{}", e)))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
);
}
ParsingResult::Quit => siv.quit(),
},
Err(e) => siv.add_layer(
Dialog::around(TextView::new(format!("{}", e)))
.dismiss_button("OK")
.h_align(HAlign::Center)
.align_center(),
),
};
}
}

siv.call_on_name("input", |view: &mut EditView| view.set_content(""));
siv.call_on_name(
"scroll_area",
Expand Down
Loading

0 comments on commit 85364c2

Please sign in to comment.