5
\$\begingroup\$

The game I'm developing is close to Pokemon. How should I store the data? I am currently thinking of text files where I save the map and have a corresponding textfile for the trainers and their teams on the "current" screen. However this leaves me with a LOT of textfiles.

At the moment I'm thinking of something like this, however I haven't coded this yet so I can still easily change this.

@Trainer;5;
@Pokemon;12;1;3;4;6;
@Pokemon;13;1;2;5;
@Pokemon;13;1;4;5;
@Pokemon;11;1;3;5;
@Pokemon;16;1;2;7;
@Trainer;3
@Pokemon;13;1;4;5;
@Pokemon;11;1;3;5;
@Pokemon;16;1;2;7;

Where the first column is the "type" of the entry. If the first is Trainer the second is his number of Pokemon. If the first is Pokemon the second is the level, the third the type, the fourth/fifth/sixth the IDs of his attacks. (How should I store the attacks? A seperate textfile where I just store the attacks?)

I am currently finding myself with having such a huge amount of data that I'm starting to wonder wether I should be using a Database instead?

Edit: Using Java(LWJGL).

\$\endgroup\$
2
  • \$\begingroup\$ You should mention what language or platform you're using, because that might dictate what's more ideal or worse for example. \$\endgroup\$
    – Mario
    Commented Apr 14, 2013 at 10:26
  • \$\begingroup\$ Oh god, can't believe I forgot. I'll edit it in. \$\endgroup\$ Commented Apr 14, 2013 at 10:32

4 Answers 4

3
\$\begingroup\$

I'd just use some simple binary Format, especially if you don't want users to easily edit the file (and also to remove some redundancy).

For example, for a new Trainer you just add the number of Creatures he got.

Then, for every creature, you just add the creature data/stats (assuming they're fixed length or you can determine their length).

From your example above, the first trainer's dataset would just be something like this:

5,              12, 1, 3, 4, 6, 13, 1, 2, 5, 13, 1, 4, 5,  11, 1, 3, 5,  16, 1, 2, 7
↑Number of sets ↑ Start of #1    ↑Start of #2 ↑ Start of #3 ↑ Start of #4 ↑ Start of #5

Note that these would be bytes rather than actual textual numbers written to the file (might depend on the min/max values as well).

\$\endgroup\$
1
\$\begingroup\$

It depends on how you're storing things internally.

Here's an example, though it's not terribly efficient, that uses your format:

public Vector<Trainer> loadData(BufferedReader in) throws IOException {
  Vector<Trainer> trainers = new Vector<Trainer>();

  String line = in.readLine();
  String[] split;
  while (line != null) {
    split = line.split(";");
    if (split[0].equals("@Trainer")) {
      int count = Integer.parseInt(split[1]);
      Trainer t = new Trainer();
      for (int i=0; i < count; i++) {
        t.add(Pokemon.createMonster(in.readLine().split(";")));
      }
      trainers.add(t);
    }
    line = in.readLine();
  }
  return trainers;
} // end loadData()

I'm also sidestepping the issue of the varying parameter counts for each type of pokemon by passing the split array on to the creation method.

Strictly speaking, you don't really need the "@Trainer" and "@Pokemon" bits, because the system will automatically differentiate between trainers and monsters. That's how helpful the monster-count information is.

If you'd rather, you could also store things in a database, like SQLite, and pack things into tables instead.

Here are some example tables:

CREATE TABLE Trainers (
  id INTEGER PRIMARY KEY,
  name TEXT NOT NULL
);
CREATE TABLE Monsters (
  id INTEGER PRIMARY KEY,
  type INTEGER NOT NULL,
  owner INTEGER FOREIGN KEY (Trainers.id),
  parameters TEXT NOT NULL
);

By using a parameters column, you're avoiding the need for individual columns for each parameter for each monster type. Formatting would be whatever you want, including the semicolon-separated method you mention.

\$\endgroup\$
5
  • \$\begingroup\$ Very helpful, thank you. However I was asking more in the direction of "what should i use" and not "how do i use it". Considering I have approximately 200-300 trainers this will bulk me up on text files a lot. (And give users the ability to edit my textfiles I think) \$\endgroup\$ Commented Apr 14, 2013 at 12:50
  • \$\begingroup\$ Using databases like SQLite is an option. By storing data in a database, it'll be stored a bit more efficiently, plus you won't have to deal with all those files. \$\endgroup\$ Commented Apr 14, 2013 at 12:59
  • \$\begingroup\$ I am still unsure about this. Which do you think is better to use? Or is this a case of "feel free to use what you want"(which in my case would be textfiles, since I've never worked with SQLite). \$\endgroup\$ Commented Apr 14, 2013 at 13:06
  • \$\begingroup\$ It's always a good idea to stretch yourself and see what working with other technologies does for you. If you learn how to use databases, you'll be a more effective programmer because you'll have more tools in your toolbox. I would recommend using SQLite, though you'll need to pick a Java wrapper to use. \$\endgroup\$ Commented Apr 14, 2013 at 13:20
  • \$\begingroup\$ It really depends on what you want to achieve. SQLite will allow easier mass editing like "update all creatures which have a Maximum of 50 hp"; while text files are more readable (easier to mod for Players). \$\endgroup\$
    – Mario
    Commented Apr 14, 2013 at 13:21
0
\$\begingroup\$

I'll offer an alternative strategy here which might be effective and lets you tack on data fairly easily.

Consider the following object:

public class SaveGame
{

   private ArrayList<EventFlags> _eventFlags;
   private TrainerInfo _trainerInfo;
   private SomeBlob _someBlob;
}

You'll have to forgive me for it not being explicit Java; but this is a basic "SaveGame" class that just contains a bunch of pointers to various game data. You store things like your story flags, variables and other persistent world information things here.

Then, just use Java serialization to save this file to the disk when you need to save. You'll be modifying these things in-game as you play anyway, so in a game like Pokemon it makes sense to just flush the state to the disk when you're done.

Nice and simple.

\$\endgroup\$
0
\$\begingroup\$

If you want a format that's easy to edit, read and write, XML or JSON are great choices.

They are not very efficient - they use a LOT more space than the format you suggested - but they are supported by many tools, and having labels on the fields makes it easy to change the format later without any confusion about what each value means.

example file:

{ 
trainers: [
    { "level":5
      pokemons: [
        {"level":12,"attack1":1,"attack2":3,"attack3":4},
        {"level":13,"attack1":1,"attack2":2}
         ]
    }
    { "level":2
      pokemons: [
        {"level":2,"attack1":1,"attack2":2,"attack3":3},
        {"level":2,"attack1":1,"attack2":2,"attack3":3}
         ]
    }
    ]
}

Java

import java.util.List;

import com.google.gson.Gson;

public class JsonTest {

    public static void main(String[] args) {
        new JsonTest().start();
    }

    private void start() {
        Gson gson = new Gson();

        // Pretend this was read from a file
        String examplePokemonsString = "{ trainers: [{ level:3, pokemons: [{level:3,attack1:1,attack2:2,attack3:3},{level:3,attack1:1,attack2:2,attack3:3}]}]}";

        DataFile data = gson.fromJson(examplePokemonsString, DataFile.class);

        List<Trainer> trainers = data.trainers;
        Trainer firstTrainer = trainers.get(0);
        Pokemon firstPokemon = firstTrainer.pokemons.get(0);
        System.out.println(firstTrainer.pokemons.size()); //This trainer has 2 pokemon
        System.out.println(firstPokemon.level); // First pokemon is at level 3
    }

    class DataFile {

        List<Trainer> trainers;
    }

    class Pokemon {
        int level;
        int attack1;
        int attack2;
        int attack3;
    }

    class Trainer {
        int level;
        List<Pokemon> pokemons;
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .