Search Unity

XML vs Database for quiz game

Discussion in 'Scripting' started by Yiorgos, Jun 5, 2013.

  1. Yiorgos

    Yiorgos

    Joined:
    Jun 5, 2013
    Posts:
    26
    I'm developing a quiz game and I'm at the point where I have to decide whether to store the questions in an XML file or in a database. Here are the requirements:

    1. Each entry/node will represent a question and will have 7 fields: question_text, answerA, answerB, answerC, answerD, category, diffuculty.
    2. The script must be able to query the list in order to pick a number of random entries (let's say 10), based on their category.
    3. The list may have a few thousand entries (questions).
    4. The list must be available offline (eg no connection needed to play the game)

    Needless to say, I'm looking for the optimal way in terms of memory and CPU usage, not ease of data entry etc.
     
  2. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Either would work and it largely depends on a number of technical factors. If you're dealing with a large number of questions, a database type solution might be best for you as it will likely offer better performance but this is going to depend on the package and you may also have trouble with support on mobile platforms (you'll want to be careful what package you use). If you're not dealing with a large amount of data, you could definitely use standard IO and file based storage for the questions. You may also want to think about encryption mechanisms for these to help prevent tampering or people just digging out your files to find the answers.

    Another thing you may consider, depending on your unity version, is using JSON.NET and do your serialization as JSON rather than XML as the resulting data will be more compact. Also, think about whether you will have categories for your questions. You'll want to come up with a scheme to store the relationships so you don't duplicate your questions. With this in place, you can deserialize your questions into your custom objects and collections and easily query them using LINQ. You could even create a custom comparer to randomize the order of the questions as you see fit.
     
  3. Yiorgos

    Yiorgos

    Joined:
    Jun 5, 2013
    Posts:
    26
    Thanks for your answer.

    I have one -maybe naive, since I'm new to Unity developing- concern: what if I want to port my game on iOS and Android? Will the exported game work ok on those platforms, if my c# scripts use JSON, LINQ etc?

    As for the number of entries, I assume it will be around 5.000 questions. Is this too much for an XML or JSON file?
     
  4. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I'm pretty new to Unity as well so I can't fully answer your question... I would assume LINQ would work fine but I can't make any guarantees on JSON.NET.

    As for the questions, 5,000 doesn't seem like a tremendous amount. It all depends on how you want to handle them. If there are no categories, you can store them all in once place. What you'll probably want to do is read in all of the questions and deserialize them to a collection, like IEnumerable<Question>

    So you might have a class that looks like this:

    Code (csharp):
    1.  
    2.     public class Question
    3.     {
    4.         public string QuestionText = "Why did the chicken cross the road?";
    5.  
    6.         public int AnswerIndex = 1;
    7.  
    8.         public string[] Answers = new[]
    9.                                       {
    10.                                           "To visit his grandma at KFC",
    11.                                           "To get to the other side"
    12.                                       };
    13.  
    14.          public int Difficulty = 4;
    15.     }
    16.  
    When you use JsonConvert.SerializeObject(myQuestion); You'd get a Json formatted representation of the object. You can even serialize a List<Question> so you'll have them all in one place. When you deserialize your object:

    Code (csharp):
    1. var questions = JsonConvert.Deserialize<List<Question>>(stringOfQuestionData);
    You'll end up with a List<Question> that you can work with. Now if you want to find all questions with a difficulty of 2 you could say:

    Code (csharp):
    1. var diff2 = questions.Where(q => q.Difficulty == 2);
    Or you could order them in order by difficulty:

    Code (csharp):
    1. var byDifficulty = questions.OrderBy(q => q.Difficulty);
    Maybe you want to order them by category (and you have a CategoryId property) and then difficulty:

    Code (csharp):
    1. var ordered = questions.OrderBy(q => q.CategoryId).ThenBy(q => q.CategoryId);
    Or find questions with a specific category:

    Code (csharp):
    1. var targetQs = questions.Where(q => q.CategoryId == 2);
    You could do any number of things. If you're going to have a lot of questions there are some considerations in how you'll want to store the data. IO is an expensive operation so you'll want to load in what you need and not load each on-demand unless performance isn't critical. If each question only has one category ever, you can just have a CategoryId property. You could store your questions in different files numbered with the correct category so you only load the ones you need, or you can store all of your categories in one file and all of your questions in another. Give each category its own id. To support multiple categories per question, store a List<int> in the Question that tells what categories it is in. Load all of your questions into one List<Question> and all of your categories into one List<Category>.

    So let's say your Question class has a CategoryList property that's a List<int> And your Category class has a CategoryId property that's of type int. Now you pick a Category that has a CategoryId of 3. Here's how you'd find all questions associated with that category:

    Code (csharp):
    1. var categoryQs = questions.Where(q => q.CategoryList.Contains(3));
    It really just completely depends on how you want to implement it.
     
  5. Yiorgos

    Yiorgos

    Joined:
    Jun 5, 2013
    Posts:
    26
    Yeah, similar deserialization can be done on XML too, I think. I will investigate a bit further the porting to mobile part and then decide which way to go.

    Thank you again for your time and effort, you helped me a lot :)
     
  6. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Not a problem. If you're not worried about storage space of the temporary memory used by loading the XML, then XML is probably the way to go. You're most likely only going to be doing the serialization in one shot.