Skip to content

Project Data Structure

M. H. Golkar edited this page Mar 25, 2021 · 8 revisions

Arrow's saved data and exports has the same structure.

A project looks like this:

{
    "title": "The Project",
    "entry": 1, // The first node of the project to be played
    "meta": {
        // Metadata
    },
    "next_resource_seed": 112, // The next available UID
    // and where all the nodes are :
	"resources": {
        // ...
    }
}

resources are building blocks of projects.

Each resource is identified with a unique integer id (UID.)

Arrow doesn't recycle UIDs, and never reuses the same UID for resources of different types.

Resources are of the types:

  • scenes
  • macros
  • nodes
  • variables
  • characters

All the resources are sorted by UIDs, grouped under their types in the resources tree. For example, each character has two properties name and color, therefore the project::resources::characters is an object in which every pair has an unique integer UID as the key (character's id) and a value object having two string properties for the name and color of the character.

Following pseudocode shows the structure of the resources tree:

{
    // ...,
    "resources": {
        "scenes|macros" : {
            <scene-uid>:int {
                "name": string<display-name>,
                "entry": int<entry-node-uid>,
                "map": { // How nodes are connected in the parent scene
                    <child-node-uid>:int {
                        "offset": [x,y],
                        "skip": bool'optional,
                        "io": [ // list of the nodes connections on the scene
                            [ <from_uid>int, <from_slot>int, <to_uid>int, <to_slot>int ],
                            ...
                        ],
                        "macro": bool'optional
                    }, 
                    ...
                }
            },
            ...
        },
        "nodes" : {
            <node-uid>:int {
                "type": string,
                "name": string<display-name>,
                "skip": bool'optional,
                "data": { <depends-on-the-node-type> },
                "notes": string'optional
            },
            ...
        },
        "characters": {
            <character-uid>:int {
                "name": string<display-name>,
                "color": string<emphasis-color-code-hex> // e.g. ff00ff1c
            },
            ... 
        },
        "variables": {
            <variable-uid>:int {
                "type": string<num|str|bool>,
                "name": string<display-name>,
                "init": variant<initial-value>
            },
            ...
        }
    }
}

There can be an optional use property (array) for each resource, indicating which other resources rely on this one.

Another property ref complements use by listing all the used resources for any dependent resource.

use and ref are implemented to safeguard continuities during operations such as node removals.

At least one scene and one entry-node shall exist in every valid project, so the editor/interpreter knows where to start.

UIDs are set by Arrow and shall not be edited in the saved data (unless you really know what you're doing)

Projects are JSON-compatible, so complex data types are converted in textual saves, imports and exports.

e.g. Vector2(x,y) <-> Array[x,y]

Generally, only one side of each graph connection (between nodes on the grid,) needs to keep the io data.

Macros are scenes with macro = true property, which enjoy special treatments by the editor and runtimes.

Clone this wiki locally