Configuring CSVs to hold nested data

I’m using as a guide to set up my CSVs to store character dialogue, and I’m having a little confusion on how I should be organizing things. The game needs to retrieve a line, in the form of an FString, based on a) who is speaking, and b) what the category of their speech is (greeting, insult, etc). That would be straightforward enough to do by searching column, then row, but the problem is that I want to add multiple variations for each category of speech: Bob might have four different ways of greeting someone for the game to choose between, and sixty ways to insult them. Is there any way I can add one extra dimension to the data structure, or use delimiters to store multiple strings in a single cell?

The simplest way would be another file. If you have all of Bob’s dialog in one CSV file, then you can now make each column a different action, such as greeting, and each row becomes a different string. You could also have all greetings be in one file, and each column can be the NPC’s Name. You don’t have to have everything in one CSV file.

Keep in mind, for performance, you would want to keep things together by how they are used, so if NPCs are often Greeting you, and you have a lot of NPCs, it makes sense to have a separate Greeting CSV that is kept loaded. This is essentially the same skill set SQL database structure designers use to increase performance of the database, by structuring the whole for often needed information to remain in memory. And it takes thinking about your use case and how it will grow to make it efficient.

If your game has just a few NPCs, and all your interactions result in a small CSV file, then multiple CSV files might be less performant than one large one, however.

CSV files are strictly two dimensional. However, how do you have it set up now? If you have a small set of NPCs, and you are the only one working on your project, and will always be the only one, then you can hard code some logic into you game to account for the fact you know how many responses Bob has.

Let’s say you have this table. (I am using the pipe symbol for readability, but in the CSV file, this is probably a comma.)

Action | Bob | Sue | Frank

Greeting | Bonjour | Good Day | Hello

Insult | **** | **** *** | *********

And so on.

You can switch your axis. So now, it looks like this.

Name | Greeting | Insult

Bob | Bonjour | *****
Sue | Good Day | *******
Frank | Hello | *** ****

Now, to add more of one thing for Bob, simply add a new row. And account for the difference in the number of lines between each action in your games logic. So, for greeting, you would use an algorithm like, Find Bob row number, then add random 0-2 and use column 2. Adding a new greeting would require changing the random to 0-3. For insults, you would use a random 0-59, and use column 3.

You would use random 0-x or you would end up skipping the first line every time.

Hope this gives you some ideas. And keep in mind, this is a simple implementation, and doesn’t really account for your particular game, so you will probably need to tweak each strategy for your own use.

Oh that’s interesting, I hadn’t thought of doing it by character. There are a lot of side characters who you’ll speak with infrequently enough to make organizing CSVs by character fairly performant, but the core cast is five people who you speak to constantly, which will result in flipping back and forth between those core files pretty frequently.

I’ll have to run some benchmarks to check, but due to the small number of NPCs with variable barks I’m fairly sure it’ll be more performant to maintain a single CSV loaded in memory for each of the common conversation categories. We’ve been using a single large CSV, but thus far that’s purely because it’s handy having a writing master that can be imported to the game- it’ll be pretty trivial to break it up by purpose and hook it into Articy. Thank you for the overview, this is really useful; I always feel like I’m typing with oven mitts when it comes to managing external data. :slight_smile:

Glad the idea was useful. You could manage it all in one file using multiple sheets, depending on the tool you are using to create the CSV. Excel, Google Sheets, and Libre Office all have the ability to export a specific sheet in a file by itself, I believe.