yarnspinnertool / yarnspinner-rust Goto Github PK
View Code? Open in Web Editor NEWThe friendly tool for writing game dialogue in Rust
Home Page: https://janhohenheim.itch.io/yarnspinner-rust-demo
License: Apache License 2.0
The friendly tool for writing game dialogue in Rust
Home Page: https://janhohenheim.itch.io/yarnspinner-rust-demo
License: Apache License 2.0
I'm not sure if this is a bug in the original impl (the line handling is the same in the relevant places imo) or if there is a (+1) that will be done at some point that we have not implemented yet.
See c127343
(#38)
The same trick might apply on other places as well
The C# code was autogenerated. I heavily suspect we can entirely replace it with the icu_plurals
crate.
For the difference between CLDR and ICU, see https://unicode-org.github.io/icu/userguide/icu_data/#icu-and-cldr-data
In StringTableManager
Per https://github.com/blyxyas/no-rust-policy-change, the word "rusty" would infringe upon the Rust foundation's proposed new trademark regulations.
This is kinda stupid and already received a ton of backlash, so I doubt the revisions will pass as-is. The feedback form is up until tomorrow if you want to add your input as well.
Hey Mafii! I know this is a wierd way to send a message, but this is the only way I found as I am not on any socials. My name is Brooks, and I am a Developer from Montana who also worked on a project just like this. Here is the repo for that project: https://github.com/MrVintage710/bevy-yarn-spinner
This was a very fun project to tackle, and I dont want to dissuade you from working on it. But, there are some problems that I ran into later in development that I thought that you may want to think about.
First and foremost, Yarnspinner was designed to fit into the Unity game engine, so when developing certain language features you may have a hard time integrating that for the rust ecosystem. There are features of the language that would require alot of work for the runtime, mainly because you are trying to implement systems from the Unity game engine. Things like defining custom functions or commands. In my crate, I took a macro aproach that is tricky, but definately the most user friendly in rust. Make sure you think about how this will tie into your chosen frame work (Bevy).
Second, there are some problems with the syntax of the language that make it difficult to be able to package with bevy when using wasm builds. This is a minor complaint, but there are some parts of the language that can be very ambiguos unless the correct spacing is given. for example:
Companion: Hi there! What do you feel like doing today?
-> Player: I want to go swimming.
Companion: Okay, let's go swimming.
-> Player: I'd prefer to go hiking.
Companion: Cool, we'll go hiking then.
Player: Sounds good!
This is an example from their docs. Without the information of the tabs, you wouldn't be able to tell what block that last line is a part of. This means that whitespace is important in the language. If you want to do compression for the language in cases where file size matters (AKA Wasm builds of Bevy) There can be alot of bloat with more dialog heavy games.
Third, Yarn spinner requires alot of static states. This goes against rust's manifesto, however this can be mitigated but the Bevy ECS. This isn't game ending, but it sure does make some features annoying to add in.
Fourth, and probably the most challenging aspect, Yarn Spinner doesn't have a language spec to follow. This is important to have, as even the smallest desitions on your end could make older scripts not work. To make your compiler accurate, there would need to be alot of test to make sure every aspect of the language is the same (ltr evaluation vs rtl, float accuaracy, comparing ints and floats, ect)
This last is what ultimately made me give up on transfering this language to rust.
However, I hope that this project is fruitful! Solve all the problems I couldn't / didn't want to. If you have any questions, leave them here and I will answer them to the best of my ability. Bonne chance!
PS: I didn't quit completely. I still think that nartive tools are important for the bevy community. So I made my own language! It is called Libretto script, and it are working on that project here: https://github.com/MrVintage710/libretto. If that sounds interesting to you, give it a quick glance!
Idea: go to parent -> child and pick the one with the same unique hashtag that we generated before hand (or use the same logic)
Be careful with the submodule, maybe needs to be a subtree.
For my previous attempt, see 08182bd
(#43)
This resulted in out-of-bounds tokens being requested. I suspect this is related to the lexer producing less whitespace tokens than the reference implementation and thus the accessed string containing too little whitespace to fulfill the correct indices.
That, or just passing the entire input stream is not equivalent to what the C# implementation of ANTLR does.
Maybe we could pass the entire file as a string instead? Because I think we have the right indices already in the linked commit.
Would be more idiomatic
Just tracking so we don't forget
See https://github.com/YarnSpinnerTool/YarnSpinner/releases for changes between versions.
Update: Nope, it can safely be replaced by Option::None
note to self regarding the implementation of CheckOperation
:
fn visit_expAddSub(&mut self, ctx: &ExpAddSubContext<'input>) -> Self::Return {
use crate::prelude::generated::yarnspinnerparser::ExpValueContext;
for term in ctx.expression_all() {
if let Ok(value) = term.clone().downcast_rc::<ExpValueContext<'input>>() {
unreachable!();
} else if term.get_rule_index() == RULE_value {
unreachable!();
} else {
println!(
"The term somehow never ends up being a value, but an `expression`. Value: {}, rule: {}",
term.get_text(),
yarnspinnerparser::ruleNames[term.get_rule_index()]
); // for {1 + 2} prints Value: 1, rule: expression
for child in term.get_children() {
println!(
"Child: {} with rule: {}",
child.get_text(),
yarnspinnerparser::ruleNames[child.get_rule_index()]
);
if let Ok(value) = child.clone().downcast_rc::<ExpValueContext<'input>>() {
unreachable!();
} else if let Ok(value) =
child.clone().downcast_rc::<ExpValueContextExt<'input>>()
{
unreachable!();
} else if child.get_rule_index() == RULE_value {
let func_call = child
.get_children()
.find(|c| c.get_rule_index() == yarnspinnerparser::RULE_function_call);
if let Some(func_call) = func_call {
let func_id =
func_call.get_token(yarnspinnerparser::FUNC_ID, 0).unwrap();
let id = func_id.get_text();
println!("This should cover the functionality of the original implementatioN!");
}
}
}
}
}
}
Current State: Incomplete, many missing parts. Let's call it a proof of concept.
Careful, everything except the diagnostics is dead code. Don't implement the rest.
Don't forget to remove the dead code allow from ConstantValueVisitor
Only the analytic scopes from CLion add any value :)
egui
already autogenerates this somehow, yoink their code
I had an epiphany. So, we want to keep yarn
but not necessarily spinner
, but it should be obvious that the tools are related. Also, Rust is faster than C#. Sooooo, how about...
👏👏👏👏👏👏
Thank you, thank you, I'm here all week
All visitors currently write into the diagnostics in general. They could however directly create the Err
variant of the result and write there.
Something like:
if we_have_an_error_already || the_visitor_just_returned_an_error {
write_our_diagnostics_into_the_err_variant()
} else {
write_out_diagnostics_into_the_state_diagnostics()
}
tags = header_value
.split_whitespace()
.map(ToOwned::to_owned)
.collect();
This seems to always take the last tags, idk if that is intended
Original splits by spaces exclusively, this splits by any whitespace -> Check if this is okay
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.