Config File Guide
Config File Guide
Config files - Knowing how to use these is essential if you want a shard that performs well, uses less memory and is easy to make changes to.
This guide primarily targets 097 and up. If you're older, its seriously time to upgrade.
POL config files are FAST. Really fast. It only reads a path in once and caches it until unloaded.
To read a config file in the pol/config/ area you would use the path "::somefile". The "::" means go to the POL root directory.
If you want to read a config file from a single package use ":packagename:somefile" this will look for the file either in the package's root directory or the package's config subdirectory.
If you want to read in every config file in all the packages and the POL root config folder use ":*:somefile"
Note: The way you read in a config file, is how you must also unload it. Take this into consideration when you read a config file in.
":*:itemdesc" and ":pkgname:itemdesc" would have that package's itemdesc.cfg loaded twice in the cache repository. This means UnloadConfigFile(":*:itemdesc") and UnloadConfigFile(":pkgname:itemdesc")
This guide primarily targets 097 and up. If you're older, its seriously time to upgrade.
POL config files are FAST. Really fast. It only reads a path in once and caches it until unloaded.
To read a config file in the pol/config/ area you would use the path "::somefile". The "::" means go to the POL root directory.
If you want to read a config file from a single package use ":packagename:somefile" this will look for the file either in the package's root directory or the package's config subdirectory.
If you want to read in every config file in all the packages and the POL root config folder use ":*:somefile"
Note: The way you read in a config file, is how you must also unload it. Take this into consideration when you read a config file in.
":*:itemdesc" and ":pkgname:itemdesc" would have that package's itemdesc.cfg loaded twice in the cache repository. This means UnloadConfigFile(":*:itemdesc") and UnloadConfigFile(":pkgname:itemdesc")
What a Config File Looks Like
Once you have a config file reference made from ReadConfigFile() you can use it to retrieve config elements.
A config file and its elements look like this:
myFile.cfg
Some parts of the core require 'ElemType' be named something else like 'Armor' 'Item' 'Container'; However, in a script this isn't used - all you will care about is the element name. Most the time you can just use 'Elem' or something meaningful to you for the elem type.
A config file and its elements look like this:
myFile.cfg
Code: Select all
ElemType Example
{
PropertyName Value
PropertyName Value
PropertyName2 Value
SomeOtherProperty value
}
ElemType Example2
{
Amount 1
ItemColor Blue
ItemName Sock
}
ElemType Story
{
Food sandwich
Drink beer
WhoMakes WOMAN
}
ElemType WhatIWant
{
Ingredient Cheese 1
Ingredient Bread 2
Ingredient Meat LOTS! I dont eat what food eats!
Ingredient SpicyMustard 1
}
Read A Config & Get An Elem
Code: Select all
var config_file := ReadConfigFile(":*:myFile");
Method 1: Use the function in cfgfile.em
Code: Select all
var config_elem := FindConfigElem(config_file, "Name");
Code: Select all
var config_elem := config_file["Name"];
Get A Single Property From an Elem
In this example, it will retrieve the element "Story" from myFile.cfg and output it to the console.
Console output.. omitted in this example.
Code: Select all
use cfgfile;
program SomeScript()
var config_file := ReadConfigFile(":somepackage:myFile");
if ( !config_file )
Print("Could not read in myFile.cfg ->"+config_file.errortext);
return 0;
endif
var config_elem := FindConfigElem(config_file, "Story");
var food := GetConfigString(config_elem, "Food");
var drink := GetConfigString(config_elem, "Drink");
var from := GetConfigString(config_elem, "WhoMakes");
Print("My "+from+" should get naked, then happily serve me a cold "+drink+" with a "+food+"!");
return 1;
endprogram
GetConfigStringArray
Sometimes a config file will list a property name more than once. The functions in cfgfile.em: GetConfigInt, GetConfigString and GetConfigRealm only return the first property.
To retrieve all of them you must use GetConfigStringArray(). This example will pull some information from the elem "Example" and output it to the console.
Output is
To retrieve all of them you must use GetConfigStringArray(). This example will pull some information from the elem "Example" and output it to the console.
Code: Select all
use cfgfile;
program SomeScript()
var config_file := ReadConfigFile(":somepackage:myFile");
if ( !config_file )
Print("Could not read in myFile.cfg ->"+config_file.errortext);
return 0;
endif
var config_elem := FindConfigElem(config_file, "Example");
var first_set := GetConfigStringArray(config_elem, "PropertyName");
var second_set := GetConfigStringArray(config_elem, "SomeOtherProperty");
ShowContents(first_set);
ShowContents(second_set);
return 1;
endprogram
function ShowContents(byref some_array)
foreach value in ( some_array )
Print("Index["+_value_iter+"] == "+value);
endforeach
return 1;
endfunction
Code: Select all
Index[1] == ValueA
Index[2] == ValueB
Index[1] == valueD
GetConfigStringDictionary
Sometimes a config element has a property, a unique identifier and a little more information after it.
In the old days you could do GetConfigStringArray() to get all of the property names then SplitWords() to parse each line.
POL097 added the feature to read in an associative array or dictionary.
This example will read in the elem 'WhatIWant' and show information about how that sandwich needs to be made.
Console Output
If GetConfigStringArray() was used, the output would look like this:
In the old days you could do GetConfigStringArray() to get all of the property names then SplitWords() to parse each line.
POL097 added the feature to read in an associative array or dictionary.
This example will read in the elem 'WhatIWant' and show information about how that sandwich needs to be made.
Code: Select all
use cfgfile;
program SomeScript()
var config_file := ReadConfigFile(":somepackage:myFile");
if ( !config_file )
Print("Could not read in myFile.cfg ->"+config_file.errortext);
return 0;
endif
var config_elem := FindConfigElem(config_file, "WhatIWant");
var ingredients := GetConfigStringDictionary(config_elem, "Ingredient");
foreach amount in ( ingredients )
Print("Ingredient name:"+_amount_iter+" Amount="+amount);
endforeach
return 1;
endprogram
Code: Select all
Ingredient name:Bread Amount=2
Ingredient name:Cheese Amount=1
Ingredient name:Meat Amount=LOTS! I dont eat what food eats!
Ingredient name:SpicyMustard Amount=1
If GetConfigStringArray() was used, the output would look like this:
Code: Select all
Ingredient name:1 Amount=Cheese 1
Ingredient name:2 Amount=Bread 2
Ingredient name:3 Amount=Meat LOTS! I dont eat what food eats!
Ingredient name:4 Amount=SpicyMustard 1
Re: Config File Guide
This last bit will cover one alternative to using GetConfigString() GetConfigInt() and GetConfigReal() and is frequently seen in scripts.
The lines inside a config file are described as properties. This example should demonstrate why! (They can be used as properties of the config elem object)
POL will automatically determine the type as string, integer or a double.
Console output
The lines inside a config file are described as properties. This example should demonstrate why! (They can be used as properties of the config elem object)
POL will automatically determine the type as string, integer or a double.
Code: Select all
use cfgfile;
program SomeScript()
var config_file := ReadConfigFile(":commands:myFile");
if ( !config_file )
Print("Could not read in myFile.cfg ->"+config_file.errortext);
return 0;
endif
var config_elem := FindConfigElem(config_file, "Example2");
var amount := config_elem.Amount;
var color := config_elem.ItemColor;
var name := config_elem.ItemName;
Print("I am still looking for "+amount+" "+color+" "+name+".");
return 1;
endprogram
Code: Select all
I am still looking for 1 Blue Sock.
Re: Config File Guide
Now lets put this into something more practical.
Someone wants every sword of object type 0x1000 to have a flag on it called 'CanBeMadeMagical' that will exist for all swords of this type.
The wrong approach is to add a cprop to the itemdesc.cfg elem such as
Then doing
Why is this the wrong approach? Because you are storing a value for every instance of that object that will exist in your world.
Instead it would be better to approach it like this:
Add to the itemdesc.cfg elem for the item 'CanBeMagical 1' (note there is no CProp before CanBeMagical and its just 1 rather than i1)
Someone wants every sword of object type 0x1000 to have a flag on it called 'CanBeMadeMagical' that will exist for all swords of this type.
The wrong approach is to add a cprop to the itemdesc.cfg elem such as
Code: Select all
CProp CanBeMagical i1
Code: Select all
if ( GetObjProperty(item, "CanBeMagical") )
//...code
endif
Instead it would be better to approach it like this:
Add to the itemdesc.cfg elem for the item 'CanBeMagical 1' (note there is no CProp before CanBeMagical and its just 1 rather than i1)
Code: Select all
var itemdesc_cfg := ReadConfigFile(":*:itemdesc");
var itemdesc_elem := FindConfigElem(itemdesc_cfg, sword.objtype);
if ( itemdesc_elem.CanbeMagical )
// Code here
endif
-
- Distro Developer
- Posts: 2825
- Joined: Thu Feb 02, 2006 1:41 pm
- Location: San Antonio, Texas
- Contact:
Re: Config File Guide
Austin,
Are element names case sensitive? I had trouble with the day/night cycle and discovered that light.cfg had LightRegion Background but my script was looking for "background" with a lowercase "b" and so my day/night cycle wasn't working.
Are element names case sensitive? I had trouble with the day/night cycle and discovered that light.cfg had LightRegion Background but my script was looking for "background" with a lowercase "b" and so my day/night cycle wasn't working.
-
- New User
- Posts: 19
- Joined: Wed Sep 15, 2010 9:47 pm
Re: Config File Guide
It´s easier write a test-textcmd than to askYukiko wrote: Are element names case sensitive? I had trouble with the day/night cycle and discovered that light.cfg had LightRegion Background but my script was looking for "background" with a lowercase "b" and so my day/night cycle wasn't working.
For a file containing something like:
Code: Select all
elem Alpha
{
blah 123
}
elem alpha
{
blah 321
{
FindConfigElem(cfgfile, "Alpha"); >>>> points to "Alpha"
FindConfigElem(cfgfile, "ALPHA"); >>>> points to "Alpha"
FindConfigElem(cfgfile, "alPHa"); >>>> points to "Alpha"
GetConfigStringKeys(cfgfile); >>>>>> returns "Alpha", ignoring the other element
So we could say it´s not case-sensitive, and the first element in the file takes priority if there are two elems with the same name. At least in 098 (but I don´t see any changes in the log)
-
- Distro Developer
- Posts: 2825
- Joined: Thu Feb 02, 2006 1:41 pm
- Location: San Antonio, Texas
- Contact:
Re: Config File Guide
Thanks Polytropon.
Yep. I took a look at the day cycle script again. I had misunderstood the way regions are handled. Being they are controlled by the core I guess I was confused because the regions are defined in *.cfg files. Since the SetRegionLightLevel passes a string literal to the core specifying the region to be lit it makes sense that there is case sensitivity there but not in normal cfg handling.
Anyway, this series of guides is great.
Yep. I took a look at the day cycle script again. I had misunderstood the way regions are handled. Being they are controlled by the core I guess I was confused because the regions are defined in *.cfg files. Since the SetRegionLightLevel passes a string literal to the core specifying the region to be lit it makes sense that there is case sensitivity there but not in normal cfg handling.
Anyway, this series of guides is great.