################################### # Untitled Storybook Game Project # ################################### This will be a project to create a system whereby "Choose Your Own Adventure" (CYOA) style stories can be easily written. Each page will read out story elements, and then prompt the user to select a new page based on a decision they would like to make. Making certain choices will also award ad-hoc stat bonuses i.e. +1 Knowledge or something, all stats are presumed to be 0 until points are awarded. This stat system also includes the ability to make checks when certain choices become available, or once they are selected. Requirements: 1. A language description and recognizer for creating CYOA-style stories. 2. An interpreter and interface for interacting with these stories. 3. Both story-writing and story-interaction tools need to be cross platform and relatively straightforwards for a non technical user to operate. Story language PEG: (with apologies, this is my first PEG) Story <- BlankLine* Page+ EndOfFile Page <- Header Body BlankLine* Header <- Identifier Newline BlankLine* Identifier <- [A-Z][A-Z0-9_]* Body <- Footer / TextLine Body TextLine <- (!Newline .)+ Newline Footer <- Ending / Goto / Choice+ Goto <- 'GOTO' Spacing Identifier Newline Ending <- 'THE END' Newline Choice <- [0-9]+ ')' Spacing (!Redirect .)+ Redirect Redirect <- StatCheck? Spacing '[' Identifier ']' Spacing StatChange? Newline StatCheck <- '<' StatName Spacing [0-9]+ ('+' / '-')? '>' StatChange <- '(' ('+' / '-') [0-9]+ Spacing StatName ')' StatName <- [A-Za-z]+ EndOfFile <- !. BlankLine <- Spacing Newline Spacing <- (' ' / '\t')* Newline <- '\r\n' / '\r' / '\n' Story language CFG: story : pages <> pages : pages page | <> page : ID FREETEXT footer footer : "THE END" | "GOTO" ID | choices choices : choices choice | choice choice : INT ')' FREETEXT maybe-skillcheck redirect maybe-skillchange redirect : '[' ID ']' maybe-skillcheck : '<' SKILL INT op '>' | <> maybe-skillchange: '(' op INT SKILL ') | <> Work log: 12/13/21 Right now I need to make a decision before any of the work has started on how the user would interact with the system. I think for a MVP it would be okay to just write a console application, but I think for the long term there needs to be a decision made on how this will work. I'm leaning towards one of three options. 1) We put the whole thing on the JVM and make it a library or something. Maybe in the future we can make a frontend for making and playing stories as a web interface, but we could make the interface pluggable as far as the backend is concerned. 2) I build this non-traditional game in a traditional game engine (Godot probably). This ensures cross-platform availibility. I'm not 100% sure about my ability to use parsers in Godot, but this looks like a good option. 3) I build this as a reactive web page. I know this sounds like a terrible idea, but there are actually a lot of cool image and text transition libraries out there. It does mean setting up something like React tho, which like, just kill me now Out of the three of these I think the Java thing would be the easiest and I think the Godot thing would be the best. 12/26/21 Merry Christmas! Forgot to update this for a bit, but let's talk turkey about what's been done so far. I decided to implement this as a C++ project for portibility. I know Java might have technically been more portible, but I'm thinking Godot is in the near future for this and Javascript has something like a FFI so I went for a C project called "peg/leg" (`man peg` weirdly...) to implement the language. I can't recommend the project, it is not copyleft and although the "leg" tool provides a lex/yacc-like interface but it does a terrible job of documenting the peg semantic actions, (like how the fuck the * operator works or how to properly use the predicates), and a lot of stuff is straight up missing (%nterm, $1, yyin). I like PEGs, but if I could do this again I'd just use flex/bison. Where to go from here? I could just start integrating this into a Godot project. Right now I'm making a little command line driver to test it out. Portibility? This project is gonna be small and I could just use submodules, or just little subprojects in the same project for each interface (Web/Godot/Whatever else). At this point I've written so little code that I think I could just port it to each project as well. For Godot I'm pretty sure I'll have to integrate it with the SCons build that they provide on their website, so I probably can't link to a .so file. 12/30/21 I tried to migrate to a library "pegtl", which is pegs implemented using the C++ standard template libray. It was a bit of a bust. The project was very deep, very academic and hard to pick up, especially since I'm not really a C++ guy. Guess I'll just keep chugging with what I've got. Next up is integrating with Godot for real this time. For real. This time... 1/1/22 I'm getting pretty frustrated with what I perceive to be bugs in the peg/leg parser. The project seems abandoned and I don't really feel like maintaining it. And GNU Bison is like right there. If I can write a cfg for my little language here I'll switch. I also can't shake the feeling that this is over-engineered, and I really don't need a parser for all this, but oh well. I could probably do it all with just lex actually. Maybe I need to spend some time rethinking this.