Sofu
Introduction

Introduction to Sofu

The "o" in Sofu stands for object-based. A Sofu file is made up of three different kinds of objects: Values, Lists and Maps.

Sofu Objects

Value is the simplest type of object. It represents what might be a Scalar in Perl: A single piece of data, be it string, integer, or floating point number.

A List is an ordered list of objects. Note that lists can contain any type of object as an element, and its elements are not restricted having the same type.

A Map is similar to Perl's Hash data type, or Python's Dictionary. It consists of several name-value pairs, i. e. named attributes. Note that "value" in this context does not mean the Sofu object type Value: Similar to lists, these attributes are allowed to be any of the three types of Sofu objects.

File Layout

Value

A Value, if it doesn't contain any whitespace or characters that are special in Sofu, is easiest represented by itself. If a value does contain any of said characters, it needs to be quoted within double quotes (").

For quoted values, the following escape sequences are available:

Examples for values are:

"Some Text"
"Line 1\nLine 2\nLine 3"
Hello

The following don't work:

Some text  # not quoted, therefore two values
Bla\nBla\nBla\n  # escape sequences are only allowed in quotes

List

A list is represented in the file by a number of objects, surrounded by round parentheses (). No comma or other separating character is required (or even allowed) between the objects. (The exception is that, obviously, we need some whitespace between two unquoted values.)

The order of the list elements is retained by the parser.

Examples:

(a b c) # Contains three values
("Value 1" ("Value 2.1" "Value 2.2")) # Nested lists

Map

A Map consists of a number of name-value assignments of the form "name = value", surrounded by curly braces {}.

name can contain any characters that don't have a special use in Sofu; these characters are "(){}#= . Whitespace isn't allowed in an attribute name, either.

Specifically, attribute names may contain characters outside the 7-bit ASCII range.

value can be a Value, List or Map.

File Root

Every Sofu file has a Map as the root object (the object that contains every other object in the file). This means that at the topmost level, a Sofu file is similar to the popular INI file format.

The root map doesn't have braces around it.

Examples for maps:

{ a = b  c = d }  # attribute a is "b" and attribute c is "d"
{ attr = (a b c) attr2 = { attr2a = a attr2b = b} }  # you can nest maps and lists

Comments

Comments are defined in Sofu by a # ("Hash") character and run to the end of the line. All text following the # is ignored on this line.

Example

Let's imagine we want to create a computer game and use Sofu to store various game data. The game is supposed to be a game where the player can fly around in a space ship and fight other space ships.

We might want to have a data base that contains all types of space ships that exist in the game. Sure, we could hard code them, but by saving them in a data file, we have them easily accessible and are able to change them without recompiling.

We want to save every ship type's hit points (a number that indicates how many shots the ship can take before being destroyed), its mass and its firepower (how many hitpoints an enemy ship loses if hit by this ship's weapon).

To get these pieces of information into a Sofu file, we could create a Map for each ship type. Since each ship type has a number of attributes, these are the attributes the map should have.

Let's define two ship types:

Interceptor
Hit Points100
Mass50 t
Firepower15
Destroyer
Hit Points2500
Mass1000 t
Firepower50

Now here's how we could turn these ships into a Sofu file:

Interceptor = {
    HitPoints = 100
    Mass = 50
    Firepower = 15
}
Destroyer = {
    HitPoints = 2500
    Mass = 1000
    Firepower = 50
}

From the way we listed the data before, this feels pretty natural. We can now modify the ship attributes and add new ships whenever we want.

Another possibility for using Sofu is level design. We could have a Sofu file for each level that contains the space stations, planets etc. that are in the level. It might look like this:

SpaceStations = {
    DeepSpaceTen = {
        Location = (100 -20 30) # x y z
        ModelFile = "models/DeepSpaceTen.mdl" # The 3D model file used for the station
    }
    AnotherStation = {
        Location = (0 0 0)
        ModelFile = "models/AnotherStation.mdl"
    }
}

Planets = {
    Earth = {
        Location = (200 100 200)
        ModelFile = "models/Earth.mdl"
        Population = {
            Race = "Human"
            Number = 10000000000
        }
    }
    AlphaCentauri = {
        Location = (4000 -100 -1000)
        ModelFile = "models/AlphaCentauri.mdl"
        Population = {
            Race = "Centaur"
            Number = 5000000
        }
    }
}

Note that we used lists for the coordinates. This is less verbose than using maps with attributes called x, y and z.

Of course, there are many other possible uses for Sofu in this game, including scripting (of a somewhat clumsy sort, I'll admit) and save games. This example should have given you an idea of two typical ways in which Sofu can help you in your application.