Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Project Config

The project manifest can be used as a simple schema root or as a full build description. It can be written as TOML, YAML, JSON, or Lua; examples on this page use TOML.

package = "game_config"
includes = ["schema/items.toml"]

[parsers]
scripts = ["tools/parsers.lua"]

[type_mappings]
scripts = ["tools/type_mappings.lua"]

[build]
default_source_format = "xlsx"
data_root = "data"
schema_lock = "generated/schema.lock"
excel_templates = "generated/excel"

[[build.codegen]]
target = "rust"
out = "rust/src/generated"
format = "auto"

[[build.exports]]
format = "binary"
out = "generated/config.sora"

Run every configured output:

sora build --project project.toml

data_root and excel_templates serve different purposes. data_root is the input directory used by export and build, so it contains edited table rows. excel_templates is an output directory for generated workbook templates, so it can be deleted and regenerated after schema changes. Do not point excel_templates at your edited data directory unless replacing those workbooks is intentional.

[parsers].scripts lists custom Lua cell parser scripts used by CLI commands that read the project. Paths are relative to the project file. See Cell Parsers for the script API.

[type_mappings].scripts lists Lua scripts that customize generated language types. Paths are relative to the project file. Type mappings are codegen-only: the schema still uses language-neutral Sora types such as struct<Vec3>, while the mapping script can map that named type to a target-specific type.

Localization is declared at the project root with [localization]. Its sources are independent from normal [[tables]]; see Localization.

Run one configured codegen target:

sora build --project project.toml --target rust

Target Options

Language-specific options live under [codegen.<target>]:

[codegen.rust]
runtime_format = "sora"

[codegen.typescript]
runtime_format = "json"
enum_repr = "string"

[codegen.lua]
runtime_format = "cbor"
lua_version = "5.4"

These options are consumed by the selected generator. The normalized IR stays language-neutral.

Type mapping scripts return a table with type_mappings. Each mapping targets one language and one named schema type:

return {
  type_mappings = {
    {
      target = "csharp",
      schema_type = "Vec3",
      type_name = "Vector3",
      nullable_type_name = "Vector3?",
      decode = "GameMappings.ToVector3({value})",
      value_decode = "GameMappings.ToVector3({value})",
      imports = { "UnityEngine" },
    },
  },
}

nullable_type_name is optional. Use it when optional<schema_type> needs a different target-language type expression from the backend’s default nullable wrapper.

decode wraps the normal binary runtime decode expression, and value_decode wraps JSON/CBOR/protobuf-style value decode. The {value} placeholder is replaced with the generated default expression.

The C target uses write-into decode functions, so C mappings should use decode_into instead of decode. The {target} placeholder is replaced with the output pointer expression. C mappings can also provide free, where {target} is replaced with the pointer that should be released:

{
  target = "c",
  schema_type = "Vec3",
  type_name = "game_vector3",
  decode_into = "game_vector3_decode(reader, {target})",
  free = "game_vector3_free({target});",
  imports = { "#include \"vector3.h\"" },
}

imports is target-specific and is only emitted by language generators that need it. C#, Java, Kotlin, and Scala expect an import namespace/path without the leading keyword. Go expects an import spec such as "example.com/game/vector". Python, TypeScript, JavaScript, Dart, Godot, C, C++, and Rust expect a complete import/include/use/preload line.

runtime_format can be sora, json, cbor, or sora-protobuf, but not every target supports every runtime format. See Runtime Formats for the support matrix.

Built-In Target Options

TargetOptions
rustruntime_format default sora; map_type = "std" or "fx_hash_map" default std; string_storage = "owned" or "arc" default owned.
kotlinruntime_format default sora.
csharpruntime_format default sora.
javaruntime_format default sora; nullable_annotation defaults to SoraNullable, set an annotation class such as org.jetbrains.annotations.Nullable, or set "" to disable annotations.
scalaruntime_format default sora; scala_version = "2.12", "2.13", or "3" default 3.
goruntime_format default sora.
dartruntime_format = "json", "cbor", or "sora-protobuf". Set this explicitly; sora is not supported for Dart.
godotruntime_format = "json". Set this explicitly; it is the only supported Godot runtime format.
cruntime_format = "sora"; c_standard = "c99", "c11", "c17", or "c23" default c11; prefix optional symbol prefix.
cppruntime_format = "sora"; cpp_standard = "c++11", "c++14", "c++17", "c++20", or "c++23" default c++17; namespace optional C++ namespace.
typescriptruntime_format default sora; enum_repr = "string" or "integer" default string.
javascriptruntime_format default sora; enum_repr = "string" or "integer" default string; emit_dts boolean default true.
erlangruntime_format default sora; enum_repr = "atom" or "integer" default atom.
luaruntime_format default sora; module optional require/import prefix; lua_version = "5.1", "5.2", "5.3", "5.4", or "luajit" default 5.4; enum_repr = "string" or "integer" default string.
pythonruntime_format default sora.
proto-schemaNo target options. Generates .proto schema files instead of a runtime loader.

Example with several language-specific options:

[codegen.rust]
runtime_format = "sora"
map_type = "fx_hash_map"
string_storage = "arc"

[codegen.cpp]
runtime_format = "sora"
cpp_standard = "c++20"
namespace = "game::config"

[codegen.javascript]
runtime_format = "json"
enum_repr = "integer"
emit_dts = true