Trending
Opinion: How will Project 2025 impact game developers?
The Heritage Foundation's manifesto for the possible next administration could do great harm to many, including large portions of the game development community.
Featured Blog | This community-written post highlights the best of what the game industry has to offer. Read more like it on the Game Developer Blogs or learn how to Submit Your Own Blog Post
A simple method of custom text parsing that is easy to understand and develop, for new programmers who want to experiment with text parsing but have been put off by the complexity of other methods.
As I first started coding, the thought of parsing text into variables was confusing and mysterious. I eventually grasped XML, but my current project forced me to make a custom format that was easy to both write and code. This post is explicitly for new programmers who want to play around with their own text implementation, but don't want to get into the weeds of learning a complex system. Feedback from experienced coders would be great, but the code below is designed to be easy to read and expanded upon.
Lets get some preliminary stuff out of the way, by opening up a file reader and our base object. I use an object called an Encounter to hold text and metadata, and each file I write has a list of them. We begin by reading the line, and trimming the whitespace:
public List LoadSet(string filepath)
{
StreamReader sr = new StreamReader(filepath);
Encounter encounter = new Encounter();
while ((line = sr.ReadLine()) != null)
{
line = line.Trim();
The meat of our code now is based on some simple methods, mostly string.Replace() and string.Trim(). We have a tag that designates which variable we're going to put the resulting data in, and then the data itself. All we do is find the thing we want, remove the tag, trim the data, and move on. If a line is empty or starts with a comment tag, we can ignore it. Note: the rest of the code below is inside the while block from above.
if (line.StartsWith(“//”)) { }
else if (string.IsNullOrEmpty(line)) { }
else if (line.StartsWith(“name:”))
{
encounter.Name = line.Replace(“name:”, “”);
encounter.Name = encounter.Name.Trim();
}
That's basically it. We can expand on this if we want with some debugging tools. Add a line counter inside the loop, and if we get something unexpected, just return the file name with the line and we can go hunt down the error. The debug line below throws a warning if the name of the Encounter object above isn't empty, meaning we didn't finalize the encounter.
else if (line.StartsWith(“name:”))
{
if (!string.IsNullOrEmpty(encounter.Name))
{
Debug.LogWarning(“Potential encounter overwriting at ” + lineNumber + “ in ” + path);
}
encounter.Name = line.Replace(“name:”, “”);
encounter.Name = encounter.Name.Trim();
}
else
{
Debug.LogWarning("Bad encounter formatting (" + line + ") at line " + lineNumber + " in " + path);
}
We can also have a final else tag that simply takes any loose text you haven't built a case for and tells you where it happened.
else if (line.StartsWith("end"))
{
if (!string.IsNullOrEmpty(encounter.Name) &&
!string.IsNullOrEmpty(encounter.LocationTag) &&
!string.IsNullOrEmpty(encounter.Text))
{
listEncounters.Add(encounter);
}
else
{
Debug.LogWarning("Minimum tags not met at line " + lineNumber + " in " + path);
}
encounter = new Encounter();
}
This is how we finalize the Encounter object, with just a single 'end' tag. You can also have other objects nested inside this one, using different starting and ending tags.
The primary benefit to all of this is for data files that is easily written by hand in exactly the format we want. This is an example of a simple encounter:
name: venus sunrise from orbit
tag: venus orbit
text: The sun emerges from the dark edge of Venus below, flooding the shipyards in sunlight. The thick atmosphere glows yellow-orange below you.
end
Its also very easy to implement new tags, just by adding another case in the method. Tags are also optional, and only need to appear as necessary in the file as its written. Here's a pastebin of a simplified but complete method. Once you have the base system down, its easy to have exactly what you need and be able to edit it quickly later on. Its allowed me to write for my game directly in the format it reads, and generally be much quicker at producing work and happier with the result.
You May Also Like