-
-
Notifications
You must be signed in to change notification settings - Fork 16
InkCPP Compiler
The InkCPP compiler converts InkJSON generated by Inkelcate or exported from Inky into InkCPP's binary InkBIN format.
The InkCPP runtime can only execute InkBIN files, so any JSON or Ink files must be converted using the InkCPP compiler documented below.
You may be familiar with Ink's Inkelcate compiler shipped with their runtime. Inklecate compiles ink script into a JSON format used by their C# runtime. This process converts complex structures such as weave, shuffles, conditional text, choices, etc. into a simple "assembly" like language encoded in JSON.
As InkCPP aims to have no dependencies, (almost) no dynamic allocations, and maximum speed, JSON introduces a number of limitations. It requires an external library to parse and iterate, frequent allocations to convert between numbers, strings, and other data types, and the need to store various pieces of state to keep track of where in the JSON hierarchy the current instruction is.
InkCPP eliminates the need for this complexity by pre-compiling the Ink JSON format (hereafter called InkJSON) into a compact binary format (hereafter called InkBIN). InkBIN encodes all numbers, booleans, flags, etc. in raw binary, meaning no parsing or processing needs to happen on the runtime. It also flattens the JSON hierarchy, inserting extra instructions to handle the various flow control that would normally be implied by the hierarchy (see Containers for more information on the hierarchy in InkJSON vs InkBIN).
For more information on the format and structure of InkBIN files, see InkBIN File Structure.
All the compiler code is organized into the inkcpp_compiler
project which compiles into a static library which can be included in your build pipeline. The public interface is exposed in compiler.h and can compile to and from files, streams, or nlohmann::json
objects if INK_EXPOSE_JSON
is defined.
Alternatively, the inkcpp_cl executable also includes the compiler and can be executed from the command line .
If inklecate.exe
is present in the same directory or your machine's PATH variable, you can also pass in an ink fire directly and it will be preprocessed by inklecate: inkcpp_cl -o output.bin myInkFile.ink
.
// Include exposed compiler.h from the include directory
#include <compiler.h>
int main()
{
// Read json from stdin and save the binary into out.bin
ink::compiler::run(std::cin, "out.bin");
// Read json from in.json and write the binary into standard out
ink::compiler::run("in.json", std::cout);
// Compile in.json to out.bin and record any compilation errors
ink::compiler::compilation_results errors;
ink::compiler::run("in.json", "out.bin");
}
Compiling an InkJSON file into the InkBIN format.
inkcpp_cl -o output.bin myInkFile.json
If inklecate.exe
is present in the same directory or your machine's PATH variable, you can also pass in an ink fire directly and it will be preprocessed by inklecate automatically.
inkcpp_cl -o output.bin myInkFile.ink
.
You can also play your ink file in the command line with the -p
flag.
inkcpp_cl -o -p output.bin myInkFile.ink
.
Lines will be printed directly into the terminal and you'll be able to select choices by index.
The compiler depends on json.hpp which is included in the project as a standalone .hpp file. Once built, you no longer need this .hpp file unless you want to feed a nlohmann::json
object directly into the compiler, at which point you should define INK_EXPOSE_JSON
before including compiler.h
.
This dependency is not included in the InkCPP runtime, as the runtime only needs the final binary file outputted by the compiler.