How to parse/evaluate a string? (Dialogue system with XML)


#1

Hi, Your Skookum script seems really interesting. I’ve read in FAQ it is possible to use it to parse a string as a piece of script, thou it is not usually best thing to do.
I plan to build a dialogue system which would store data in XML. To determine which questions and answers would be displayed, I need a way to retrieve values of variables and parse expressions stored in XML. For player answers to have some effect, I would also need to execute simple scripts stored with dialogues. From what I’ve learned it is usual practice to use interpreted scripting languages this way in games.
My question is how do I parse a piece of Skookum script stored in a string from C++, blueprint or Skookum itself? Alternatively, is there better way solve my problem?
Thanks.


#2

This is a good question and I’m glad you asked it. Embedding scripts can be very powerful.

To first get a little background, I recommend that you see this related post:

I recommend that you choose one of two possible paths:

  • Option A: Store all your dialog logic in SkookumScript lists with SkookumScript data structures storing the appropriate variables and logic and have named references to dialog entries from your XML. The logic could be a single call to a routine defined elsewhere (option 2 from above) or a closure with a chunk of code defined in-place (option 4). The XML would be fairly simple with a unique name/id and some data to go along with it: variant texts, different languages/locales, etc.
  • Option B: Store more in the XML structures and have named references to SkookumScript logic. The named references could be routines (option 2), or uniquely named/identified closures (using option 4 and some way to name them or ideally option 5 - which would need additional C++ coding or future SkookumScript features).

The key would be to ensure that the SkookumScript code and logic is converted to binaries by the compiler and also checked for correctness at the same time that the rest of the code is checked. I’ve been on many projects where failure to do so and instead interpret the code at some arbitrary point in the runtime leads to bugs, time lost and many tears.

SkookumScript is a compiled language which has many advantages - especially finding problems before the game runs. Likewise, while editing the code in the SkookumIDE you get a growing number of editing features such as auto-completion and invalid code gets pointed out (with a read wavy line) even as you are typing it. Since the SkookumIDE knows about the location of the code you can debug it – setting break points, step through it and look at the values of variables, etc. You can also change the code while the game is running making it easy to polish up your logic and have an fun workflow with a quick turn-around. Ensuring that the SkookumIDE knows and manages the code will get you all this and anything else that comes for free with the SkookumScript tools.

The tricky part in all this is to ensure that the SkookumScript dialogue data structures and code and the XML dialogue data are in sync. You would probably want to run some sort of integrity check to ensure that references are correct between the two and that nothing is misspelled, stale, missing, unused, etc. There is a future system in SkookumScript called “object ids” that is designed to solve this problem though it isn’t available in UE4 yet.

SkookumScript can describe arbitrarily complex data just like XML. There are plans to extend this area of SkookumScript even further for the future so that you could describe all your data with SkookumScript and not need XML, YAML, JSON, ini files, etc. For now though, there still could be an advantage with a mix.

Let me know if this makes sense and if you have additional questions. We can expand on it until you have a solution that works.


#3

Thank you very much for thorough answer.
To be honest I still find the idea of interpreting pieces of code stored as text at runtime quite attractive.
In option B I wonder how to use those named references to SkookumScript logic. Is there a way to call routine or closure by its name stored in string variable or do I have to use ‘case’ conditional maybe?