Easy CSV Parsing in .Net
Working on getting a public build of my latest game jam game up, and one thing I'm experimenting with is using CSVs for certain types of data. There's a bunch of enemies in the game that all have different stats, and usually I just store this information in the class for each enemy. Storing this data on a CSV has the benefit of being able to see all the data next to each other.
While I could achieve the same thing by having a dictionary set up in the code itself, storing the data in a csv file makes it a little bit easier to view and edit. Tweaks can be made more easily, and storing a bunch of data in dictionaries in code can get a little crazy looking depending on how much data there is to store.
At first I was using OpenOffice Calc for my CSV editing, but there's a huge down side with that: file locking! OpenOffice thinks it's an awesome idea to put any file its editing into a crazy lock down mode, so I can't even read from the file while OpenOffice has it open. So I had to ditch it, and instead I'm using Ron's Editor. So far this is the best free csv editor I can find, even though it's a quite bit more strict about editing than a big spread sheet.
Now for loading the CSV data I'm using CsvHelper which makes parsing a csv as painless as possible. My enemies.csv looks like this:
And the code to parse that looks like this:
I'm using a tiny class called Record to store the data. Record looks like this:
I end up loading the csv data into a dictionary with the enemy Types as the key, and the Records as the values. When an enemy is created it can look into that dictionary by using its own type and get out a Record object that contains all the data it needs to initialize.
Pretty straight forward! I think I'm going to extend this to expose more fine tunings of things. It might also be fun to leave the files totally exposed for players to mess around with as well.
While I could achieve the same thing by having a dictionary set up in the code itself, storing the data in a csv file makes it a little bit easier to view and edit. Tweaks can be made more easily, and storing a bunch of data in dictionaries in code can get a little crazy looking depending on how much data there is to store.
At first I was using OpenOffice Calc for my CSV editing, but there's a huge down side with that: file locking! OpenOffice thinks it's an awesome idea to put any file its editing into a crazy lock down mode, so I can't even read from the file while OpenOffice has it open. So I had to ditch it, and instead I'm using Ron's Editor. So far this is the best free csv editor I can find, even though it's a quite bit more strict about editing than a big spread sheet.
Now for loading the CSV data I'm using CsvHelper which makes parsing a csv as painless as possible. My enemies.csv looks like this:
EnemyType,Supply,Mass,MaxHealth
BasicTest,1,1,10
BigSkeleton,10,0,-1
TestPart,0,0,5
And the code to parse that looks like this:
var csv = new CsvReader(File.OpenText(Assets.Data.Enemies));
while (csv.Read()) {
var record = new Record();
record.EnemyType = Util.GetTypeFromAllAssemblies(csv.GetField<string>("EnemyType"));
record.Supply = csv.GetField<int>("Supply");
record.Mass = csv.GetField<float>("Mass");
record.MaxHealth = csv.GetField<int>("MaxHealth");
Records.Add(record.EnemyType, record);
}
I'm using a tiny class called Record to store the data. Record looks like this:
public class Record {
public Type EnemyType;
public int Supply;
public float Mass;
public int MaxHealth;
}
I end up loading the csv data into a dictionary with the enemy Types as the key, and the Records as the values. When an enemy is created it can look into that dictionary by using its own type and get out a Record object that contains all the data it needs to initialize.
var r = Records[this.GetType()];
AddComponents(
new Team(TeamType.Enemy),
new Heart(r.MaxHealth),
new SpriteEffects()
);
Group = O.GroupGameplay;
if (r.Mass > 0) {
AddComponent(new PushAway(r.Mass, Tag.Enemy));
}
var h = GetComponent<Heart>();
h.OnDeath += () => {
Death();
};
h.OnDamage += (d) => {
};
Pretty straight forward! I think I'm going to extend this to expose more fine tunings of things. It might also be fun to leave the files totally exposed for players to mess around with as well.
1 Comment