JSON module

Reading and writing JSON, both as text and as a file on disk. The API dump the reference is generated from goes through this, so what a script writes out is encoded the way the engine's own data is.

Functions

  • trx.json.encode(value)
    Writes a value out as JSON, on one line. Keys come out in sorted order, so the same value encodes the same way twice and a file that is committed and diffed only moves when its JSON changes.

    A table is written as a list when entry 1 is present, or when the table is empty, and as an object otherwise. A number an object is keyed by comes out as text, and a key of any other kind is left out. A function, a handle and anything else with no JSON form is left out of an object, and stands as null in a list, which keeps the entries after it where they were. A number that is not finite, and a table that contains itself, raise.

    Parameters:

    • value (any). What to write out.

    Returns: string. The JSON text.

    Example:

    trx.json.encode({ name = "wolf", ids = { 7, 8 } })
    -- {"ids":[7,8],"name":"wolf"}
    
  • trx.json.decode(text)
    Reads a value out of JSON text, as the game reads its own data files: a comment, a trailing comma and an unquoted key are all taken. Text that does not parse raises with the line and the column.

    Text nested deeper than 100 levels raises as well.

    An object comes back as a table keyed by name and an array as a table keyed from 1, which is what trx.json.encode writes back out. null comes back as nil, so a key with null reads the same as an absent key, and an array entry with null ends the list there.

    Parameters:

    • text (string). The JSON to read.

    Returns: any or nil. The decoded value.

    Example:

    local held = trx.json.decode('{"hp": 6, "seen": ["vilcabamba"]}')
    print(held.hp, held.seen[1])
    
  • trx.json.read_file(path)
    Reads a file as JSON, which is trx.path.Path.read_text and trx.json.decode in one call. A file that is not there answers nil, and one that does not parse raises with the file, the line and the column.

    Every table read from a file carries where it was written, which trx.json.where reads back. A path outside the directories a script may reach raises rather than being read.

    Parameters:

    Returns: any or nil. The decoded value, or nil where there is no such file.

    Example:

    local found = trx.path.resolve("common_config", "weapons.json5")
    local weapons = found ~= nil and trx.json.read_file(found) or {}
    for key, spec in pairs(weapons) do
      print(key, spec.damage)
    end
    
  • trx.json.write_file(path, value)
    Writes a value as JSON and saves it to the file, which is trx.json.encode and trx.path.Path.write_text in one call.

    A value trx.json.encode has no JSON for raises, and nothing is written. A path outside the directories a script may reach raises as well, so trx.path.config_dir is where a script's own file belongs.

    Parameters:

    Example:

    local kept = trx.path.config_dir / "mymod" / "state.json"
    trx.json.write_file(kept, { seen = { "vilcabamba" } })
    
  • trx.json.where(value)
    Says where a table read from a file was written: the file, the line and the column. Use it when a script must report the source line for bad file data. A table a script built itself, and anything that is not a table, answer nil.

    Parameters:

    Returns: string or nil. Where the table was written, or nil without file location data.

    Example:

    local weapons = trx.json.read_file("weapons.json5")
    for key, spec in pairs(weapons) do
      if spec.damage == nil then
        error(("%s: '%s' says no damage"):format(trx.json.where(spec), key))
      end
    end