Skip to content

Instantly share code, notes, and snippets.

@Shadows-of-Fire
Last active May 2, 2022 00:23
Show Gist options
  • Save Shadows-of-Fire/d49786dbf836d4c08135a0ec2219b2eb to your computer and use it in GitHub Desktop.
Save Shadows-of-Fire/d49786dbf836d4c08135a0ec2219b2eb to your computer and use it in GitHub Desktop.
PCFG File Specification

The PCFG (Placebo Configuration) File Format is a configuration format that supports categorized key-value pairs where the keys are strings, but the values are valid JSON embedded within the document.

The file specification is as follows:

Comments

A comment is marked by a #. For any line, any text following a # will be ignored. Comments are not valid within JSON-values, but are valid after termination of those JSON-values.

Examples:

  • # A commented line
  • general < # The general category
  • Test Double=3.14 # A valid comment

Categories

A category is the main source of organization within PCFG files. Each category can contain child categories, or Elements. A category is declared by <. Any text preceeding this symbol on the line where it is declared becomes the category name. A category is completed by >.

Example:

  • general <

Elements

Elements represent key-value pairs. Each element has a specific delared type, and the JSON value will be parsed according to the specified type. If ANY element fails to parse within a config file, the entire file becomes invalid, as the parser will not know how many lines to skip to continue parsing other values. Elements may fail to parse for either having an invalid type name, or having invalid JSON as decided by the type's parser.

Elements begin with a Type declaration, started by @. The syntax @ type specifies that the next non-commented line will be treated as a key-value pair of type type.

The key-value pairs must follow a type declaration to be valid, and take the form Key=Value, where Key is a string, and Value is a valid JSON value (not necessarily a full JSON object). Examples:

  • An element with type bool, key Example Bool, and Default value false
    # An example flag.
    # Common | Locked
    # Default=false
    @ bool
    Example Bool=true
  • An element with type str_list, key Example List, and Default value [ "strings! ]
    # Example List
    # Common | Locked
    # Default=[
    #     "strings!"
    # ]
    @ str_list
    Example List=[
        "Example Element 1",
        "Example Element 2"
    ]

Config Flags

On elements, there is a specific comment that takes the form # Side | Loadability which specifies the side and loadability of the attached Element. An element will always have one side and one loadability declared, which notes where the value is relevant, and if it can be reloaded at runtime or not.

Side:

  • Common - Relevant in all cases, but is not synced from client to server. On a dedicated server, these values should match in both the client and server config files.
  • Synced - Relevant in all cases, and is synced on login to the client, so it is server-authorative. Servers may change these elements without updating client files.
  • Server - Relevant only on a dedicated server. Its value is not transmitted to the client.
  • Client - Relevant only on a physical client. Its value does not impact server side (integrated or dedicated) functionality.

Loadability:

  • Locked - This element cannot be reloaded at runtime. New values will not have any effect until a full game restart.
  • Restartable - This element will be read when a new save file is loaded. On dedicated servers, this is equivalent to Locked, as servers cannot load new worlds.
  • Reloadable - This element will be reloaded when the /reload command is executed (and resynced, if applicable). As a client on a dedicated server, reloads will occur during F3+T (resource reloads).
# Configuration File
general <
# A test list of ints
# with so many
# lines of
# text!
# Common | Locked
# Default=[
# 22,
# 95
# ]
@ int_list
My Int List=[
13,
87
]
# If the testing has been done or not.
# Second line.
# Common | Locked
# Default=false
@ bool
Test Bool=true
# Some number that does something
# Common | Locked
# Default=13.31
@ double
Test Double=3.14
# Common | Locked
# Default=null
@ int
Test Int=99
# List
# Common | Locked
# Default=[
# "22"
# ]
@ str_list
Test List=[
"my test list",
"item number 2"
]
# A test value?
# Common | Locked
# Default={
# "str": "My Test Str",
# "integer": 129
# }
@ test_obj
Test Obj={
"str": "My Json String",
"integer": 0
}
# its a string
# Common | Locked
# Default="stuff"
@ string
Test Value="a string"
child <
# If the testing has been done or not.
# Second line.
# Common | Locked
# Default=true
@ bool
Test Value=true
>
>
public static void loadConfig() {
Config cfg = new Config(new File("test.pcfg"));
cfg.load();
myBool = cfg.get(ElementTypes.BOOL, "Test Bool", "general", false, "If the testing has been done or not.\nSecond line.");
childBool = cfg.get(ElementTypes.BOOL, "Test Value", "general.child", true, "If the testing has been done or not.\nSecond line.");
myObj = cfg.get(ElementTypes.TEST_OBJ, "Test Obj", "general", new TestValue("My Test Str", 129), "A test value?");
myIntList = cfg.get(ElementTypes.INT_LIST, "My Int List", "general", Arrays.asList(22, 95), "A test list of ints\nwith so many\nlines of\ntext!");
myDouble = cfg.get(ElementTypes.DOUBLE, "Test Double", "general", 13.31, "Some number that does something");
myStrList = cfg.get(ElementTypes.STR_LIST, "Test List", "general", Arrays.asList("22"), "List");
myString = cfg.get(ElementTypes.STRING, "Test Value", "general", "stuff", "its a string");
cfg.save();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment