Open kodra-dev opened 1 year ago
I had a similar situation like this, but I couldn't find a solution using the API. My solution was I wrote a very basic reader for the raw ink files and I would run my processor over it right before I loaded the actual compiled JSON file. That way I could just find each line that matched my format or tag, validate it, and output a line number if there was a problem.
Yes, this is very possible using InkParser class. (which is part of the Ink Compiler project)
You create InkParser object passing the json content. Then call method Parse(). As a result you'll have the story class, which is the root Ink.Parsed.Object.
The primary interest is text property. Which needs to be parsed out for the name prefix. But you only need to parse it if the object is of Ink.Parsed.Text class.
Each Ink.Parsed.Object might have some "content" (which contents the sub-objects) and allows to go "deeper" into the story.
Here's the example of the code:
static void WalkObj(Ink.Parsed.Object obj, string pfx = "")
{
if (obj == null) return;
if (obj is Text t)
{
Console.Write(pfx);
Console.Write(obj.GetType().Name);
Console.Write(" \"{0}\"", t.text);
if (t.hasOwnDebugMetadata)
{
Console.Write(" (");
Console.Write(t.debugMetadata.fileName);
Console.Write(":");
Console.Write(t.debugMetadata.startLineNumber);
Console.Write(") *");
}
}
else
{
Console.Write(pfx);
Console.Write(obj.GetType().Name);
if (obj is Ink.Parsed.Choice ch)
{
Console.WriteLine();
Console.Write(pfx);
Console.WriteLine(" has start: {0}", (ch.startContent != null));
Console.Write(pfx);
Console.WriteLine(" has inner: {0}", (ch.innerContent != null));
Console.Write(pfx);
Console.WriteLine(" has choice: {0}", (ch.choiceOnlyContent != null));
}
}
Console.WriteLine();
if (obj.content != null)
{
foreach (Ink.Parsed.Object sub in obj.content)
WalkObj(sub, pfx + " ");
}
}
Here's how the code can be used
string js = File.ReadAllText(inputFn);
InkParser p = new InkParser(js, inputFn);
Ink.Parsed.Story flow = p.Parse();
WalkObj(flow);
I have a custom "sub-format" for my content.
I'll parse this
John
and check if John is a character in my game, so if I made a typo:I can show an error.
I already know how to do the above, with a caveat: the error only shows up when the player actually runs into
Jonh: Hello!
. If I have an ink script like this:and the player chooses
[good night]
, then it doesn't show errors. I'd like to make an editor button that catches these kinds of errors beforehand, before the player even plays the script.How could I do this? I think the simplest way is just to iterate over all the content and validate them, but I don't know how to do it with the API.