Java-Gaming.org Hi !
 Featured games (90) games approved by the League of Dukes Games in Showcase (736) Games in Android Showcase (224) games submitted by our members Games in WIP (814) games currently in development
 News: Read the Java Gaming Resources, or peek at the official Java tutorials
Pages: [1]
 ignore  |  Print
 Working with YAML: Configuration Files  (Read 25736 times) 0 Members and 1 Guest are viewing this topic.
actual

JGO Coder

Medals: 25

 « Posted 2013-06-22 23:16:27 »

In game programming it's generally considered good practice to specify game information in external configuration files.
1. It gathers parameters that may be scattered across the code base into a couple of small files.
2. The external files can be easier to read, understand, and modify.
3. Modifications can be made without changing (and having to rebuild) the source.

In the Java world XML is the typical choice although JSON, properties, INI, and other formats are also used. Another, less well known format, is YAML(YAML Ain't Markup Language). YAML is a structured text format which provides a viable alternative to XML and JSON as means of specifying configuration data, particularly when the files are being edited by hand.

This article gives a brief overview of YAML, with a focus on using it as a means for writing configuration files.

There are two main libraries for working with YAML in Java; snakeYAML and YamlBeans. Both have fairly equivalent functionality, and at the bottom of this article is a simple class that uses snakeYAML to read in a yaml file, convert the YAML result tree into a simple set of nested maps, and write the output to the console. Both snakeYAML and YamlBeans provide additional functionality such as loading YAML data directly into POJOs and walking the YAML parse result tree.

Here is a simple YAML file:

# Properties and values are separated by a colon.
# There has to be at least one space between the colon and the value.

menuFontColor: blue       # Blue is my favorite color

Reading this in via the code at the end of the post gives us the following following simple map:

So for cases where all you need is a simple set of key/value pairs, a YAML file is not any more verbose than a properties file. Imagine what the equivalent XML might look like.

Maps

YAML uses indentation to specify hierarchical data. If we change the file to:

font:
family: Arial
color: blue
size: 14pt

# Font and BackgroundImage need to be indented the same amount.
backgroundImage:
tile:  true

...and run the code again we get a series of nested maps:

It does not matter how many spaces you indent, as long as it is consistent within a map. Try adding a space in front of "color: blue" and see what happens. You cannot use tabs for indentation.

YAML also allows you to define multiple keys on the same line. The previous example could also be written as:

font: { family: Arial, color: blue, size: 14pt }

backgroundImage:
{ image: menu.png, tile: true }

Lists

Let's say we want to add to our configuration a list of sound files to load at start up. All of the files are in the same directory, and for each sound we want to specify both the name of the file and the name to be used to get the sound from the library (something like soundLibrary.getSound("PlayerDied")).

font: { family: Arial, color: blue, size: 14pt }

backgroundImage:
{ image: menu.png, tile: true }

audio:
# Path is relative to the main game directory
base-path: .\sounds\raw\

# Each entry in the list starts with a "-" and must be at the same level of indentation.
sounds:
- name: Hit
file: hit_1.ogg

- name: PlayerDied
file: player_death.ogg

- { name: Miss, file: miss_target.ogg }  # We can also define a sound on one line.

This results in the following output:

{menu={font={family=Arial, color=blue, size=14pt}, backgroundImage={image=menu.png, tile=true}}, audio={base-path=.\sounds\raw\, sounds=[{name=Hit, file=hit_1.ogg}, {name=PlayerDied, file=player_death.ogg}, {name=Miss, file=miss_target.ogg}]}}

Like maps, lists can be defined on one line with list items separated with a comma and space.

sounds: [ {name: Hit, file: hit_1.ogg}, { name: playerDied, file: player_death.ogg}, { name:Miss, file:miss_target.ogg}]

There is more to YAML than what I have shown such as:
1. Support for multi-line strings
2. Anchors and References which allow nodes to reference previous nodes in the document
3. Specifying the type of values
4. Automated mapping of YAML data to POJOs.
5. Serialization of objects to YAML.

Some scattered, closing thoughts

Personally I like YAML. It keeps the simple things simple. When all I need is a flat list of properties, a YAML file has no more overhead than a .properties file. I can then add a bit of hierarchy for convenience without having to switch to a new format.

I find YAML to be easier to read and modify than either XML or JSON.

YAML's use of whitespace may welcome or annoying depending on your preference.

XML and JSON have much larger communities with much richer toolset available.

Like JSON, YAML is not as self describing as XML and more care may be required to ensure that your format is understandable from a semantic standpoint.

Unlike XML, YAML has no standard way of defining a schema and validating a document against it, although projects such as Kwalify have been developed to meet that need.

References
Official YAML site

snakeYAML
YamlBeans

Simple class to run example files

 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29 import java.io.*;import java.util.Map;// Download the snakeYaml jar at: http://code.google.com/p/snakeyaml/downloads/listimport org.yaml.snakeyaml.Yaml;public class SimpleYAMLMain {         public static void main(String[] args) {            // The path of your YAML file.      final String fileName = "path\\to\\yaml\\file\\test.yaml";            Yaml yaml = new Yaml();         try {         InputStream ios = new FileInputStream(new File(fileName));                  // Parse the YAML file and return the output as a series of Maps and Lists         Map result = (Map)yaml.load(ios);         System.out.println(result.toString());               } catch (Exception e) {         e.printStackTrace();      }   }}

sproingie

JGO Kernel

Medals: 202

 « Reply #1 - Posted 2013-06-23 00:55:25 »

It's probably worth mentioning that Jackson supports YAML with an extension library, so add this to the list of links:

jackson-dataformat-yaml
gimbal

JGO Knight

Medals: 26

 « Reply #2 - Posted 2013-07-10 07:23:41 »

If you are in the position where you need data for an in-memory database (or unit tests), I have used Fixy for that purpose which is incredibly easy and built on top of SnakeYAML too.

https://github.com/sberan/Fixy

That quote on the site is actually from me by the way

Not many people will actually utilize an embedded database in their game, but I thought I'd mention it all the same for the rare case where someone does want to play with it.
Pages: [1]
 ignore  |  Print

You cannot reply to this message, because it is very, very old.

 cybrmynd (139 views) 2017-08-02 12:28:51 cybrmynd (160 views) 2017-08-02 12:19:43 cybrmynd (154 views) 2017-08-02 12:18:09 Sralse (170 views) 2017-07-25 17:13:48 Archive (649 views) 2017-04-27 17:45:51 buddyBro (768 views) 2017-04-05 03:38:00 CopyableCougar4 (1302 views) 2017-03-24 15:39:42 theagentd (1267 views) 2017-03-24 15:32:08 Rule (1238 views) 2017-03-19 12:43:22 Rule (1313 views) 2017-03-19 12:42:17
 List of Learning Resourcesby elect2017-03-13 14:05:44List of Learning Resourcesby elect2017-03-13 14:04:45SF/X Librariesby philfrei2017-03-02 08:45:19SF/X Librariesby philfrei2017-03-02 08:44:05SF/X Librariesby SkyAphid2017-03-02 06:38:56SF/X Librariesby SkyAphid2017-03-02 06:38:32SF/X Librariesby SkyAphid2017-03-02 06:38:05SF/X Librariesby SkyAphid2017-03-02 06:37:51
 java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org