Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Story generation #8

Open
Kinrany opened this issue Apr 12, 2021 · 2 comments
Open

Story generation #8

Kinrany opened this issue Apr 12, 2021 · 2 comments
Labels
enhancement New feature or request

Comments

@Kinrany
Copy link

Kinrany commented Apr 12, 2021

Hi! I'm trying to convert stories written in another tool into stories written in ink.

I wondered if I could use your crate. I assume it is not intended for this purpose, but I wonder how hard it would be to change that.


This is not exactly the feedback you asked for, but I have an idea of what the high-level API could look like and I thought you might want to hear it:

  1. Source code representation struct Source: represents an .ink text file. Implements From<&str> for parsing and Display for printing. Allows errors.
  2. High-level story representation struct Story: has all the content of the story, but without the details. Implements TryFrom<Source> and Into<Source>. Does not allow errors. Can be used to start playing a story.
  3. Runtime representation enum Playthrough { Text, Choice }: tracks the current state of the story being played. Stops at either a text line or a choice. Basically a state machine.

The implementation of the runtime representation is a lower level detail than the overview and less important. I'll just present the API that I think seems the most obvious (after thinking about it for like 20 minutes) for embedding the crate as a story engine in another program.

The most common flow would look like this:

// read the text
let source: Source = "hello world".into();
// compile the story
let story: Story = text.try_into()?;
// create an active instance of the story
let mut playthrough = story.start();

loop {
    match playthrough {
        Text { line, next } => {
            // show the paragraph and
            // proceed to the next step
            println!("{}", line);
            playthrough = next;   
        },
        Choice(choice) => {
            // show the options, let the reader choose one,
            // pass the chosen option to the state machine,
            // proceed to the step determined by the chosen option
            println!("{}", choice.options);
            playthrough = choice.choose(get_chosen_option());
        },
        End => {
            println!("FIN");
            break;
        }
    }
}

This would neatly split the implementation into three smaller reusable parts that would allow a range of different. It would allow using the crate for editing ink files and for publishing finished stories in various formats.

Any or all of this might be overengineering though 🙂

@Kinrany Kinrany added the enhancement New feature or request label Apr 12, 2021
@pjohansson
Copy link
Owner

Hi!

Sorry for the late reply, My actual work keeps most of my attention these days.

  1. You are of course welcome to use inkling in any way you like, including converting stories from other tools if you want to -- as long as you follow the Parity license terms for this project if it is used.
  2. Thank you for your thoughts on the API. While I haven't actively worked on the code over the past year, I've largely landed on something similar to your suggestion about a Playthrough struct, or something similar to it. It would allow a more granular structure, like explicitly calling attention to when new story sections (knots) are jumped to, not just when choices are hit.
  3. I'm not sure what a Source struct would add if its mostly wrapped text content. I could see the use of separately parsing text and checking for errors, and creating the Story from that object. But in the end, the same errors would be raised, no? But I'll admit that I'm an amateur who does not have any real experience with dealing with these sorts of issues in real-life contexts.

Regards,
Petter

@Kinrany
Copy link
Author

Kinrany commented Dec 4, 2021

Thanks for the reply!

I have the same problem. Perhaps another half a year later I'll find the time to revisit that project and send a PR, haha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants