8

Given the following tree structure, where each player logged in can have data for current and completed levels, quests per level, NPCs per quest, and multiple tasks per NPC... I'm trying to figure out the best way to store the current and completed data per player.

enter image description here

I asked the question before, albeit with too much detail. It was requested that I generalize the question... So if you'd like more context, see here:

RPG - storing player data for semi-complex tree structure

Some information about my RPG structure:

  • Levels, Quests per Level, and Tasks per NPC are completed in chronological order.
  • NPC dialog and task dialog data is stored in a js object in a npc_dialog_1.js file in the following structure:

    var dialog = {
    quests : {
        questName : {   
            NPCName: {
                TaskName:  {
                     "english" : 
                      [
                          "Hello, here is some dialog",
                      ],//more items per task
                }, //more tasks per NPC
            }, //more NPCs per quest
        }, //more quests options per "quests"
    }, //more options in dialog besides "quests" if I want
    };
    

    I am storing each dialog object in a separate npc_dialog_n.js file per map, that I'm retrieving with requireJS. This will reduce clutter in a single npc_dialog file.

  • NPCs per Quest, however, can be started in any order... this is trying to mimic a GTA-style quest queue, as the game follows a general linear progression, yet for each quest you can talk to multiple NPCs and start, pause, and resume the NPC's tasks at any point.

Since the player can start, pause, and resume tasks per any NPC at a given time, I'm trying to figure out the best way to store the current and completed data per player.

mfirdaus recommended the following DB table with M:M relationship b/t user & npc... yet this would add up quickly as each player can have multiple NPCs per quest, and multiple tasks started per NPC... Any way around this set up?

enter image description here

My current db schemaenter image description here:

Thank you

Community
  • 1
  • 1
user3871
  • 12,432
  • 33
  • 128
  • 268
  • 1
    possible duplicate of [RPG - storing player data for semi-complex tree structure](http://stackoverflow.com/questions/23587430/rpg-storing-player-data-for-semi-complex-tree-structure) – Alex.Ritna May 12 '14 at 00:02
  • @Alex.Ritna Not exactly a duplicate. This is a simplified version of the original question. Not sure it was better to open a new question or edit the old one, however. – Jeremy J Starcher May 12 '14 at 00:03
  • @JeremyJStarcher Yes, I debated updating the original. But in the past people have ended up asking for more context, so I figured it would best to just start a simplified new question. – user3871 May 12 '14 at 00:04
  • @Growler you want to save the quest_progress per quest in each player right? then i suggest saving your quest_data as json_encoded data in a column in your **userstats** (or make one). – Viscocent May 12 '14 at 03:52
  • @Viscocent can you expound upon that plz? – user3871 May 12 '14 at 04:30
  • @Growler well first you need to make an extra column on your db(long text), then you can start storing json_encoded arrays(you can fetch it again later and convert it to arrays/objects) in the column(we use this tech in our games approx 200k players.) so i can at-least guarantee that it scales. – Viscocent May 12 '14 at 06:12
  • @Viscocent So you are saying I shouldn't be storing my dialog in JS objects at all? Can you provide everything you're saying as an answer? – user3871 May 12 '14 at 06:17
  • @Growler is this game designed for browser or mobile games? anyways you're JS objects are meta data's right? – Viscocent May 12 '14 at 06:28
  • If you're making heavy use of JSON in your data structures, which is a pattern I'm seeing a lot more of lately, you'd benefit considerably by using [Postgres](http://www.postgresql.org/) as a back-end because it has a very powerful [native JSON data-type](http://www.postgresql.org/docs/devel/static/datatype-json.html) which makes using this sort of data in queries really easy. – tadman May 12 '14 at 16:19
  • (sidenote: the RPG tag on this site refers to the RPG programming language, used primarily by professional programmers for business applications) – WarrenT May 12 '14 at 23:36

2 Answers2

2

Choosing the right method to use

suppose you have this array:

$player_quest_status = array("quest1" => 100,
                             "quest2" => 90,
                             "quest3" => 50); 

you can have 2 options on storing these array into the database.

  1. using PHP json_encode():

    $player_quest_status_json = json_encode($player_quest_status);
    //then you can store $player_quest_status_json variable using INSERT.UPDATE 
    

    statements //array when encoded: {"quest1":100,"quest2":100,"quest3":100}

    use json_decode to convert it back to array after retrieving the value from the database.

  2. using PHP serialize():

    $player_quest_status_json = serialize($player_quest_status);
    //array when encoded: a:3{s:6:"quest1";i:100;s:6:"quest2";i:100;s:6:"quest3";i:100;}
    

for more information which function you would like to use:
Preferred method to store PHP arrays (json_encode vs serialize)

though i still recommend json as it is more scalable.


Structuring your Arrays

$player_quest_status = array("player_id" => 1,
                             "level"     => 1,
                             "quests"    => array( 1/*quest_id*/ => array("percent_completed" => 100, 
                                                                          "quest_title"       => "the first quest"),
                                                   2/*quest_id*/ => array("percent_completed" => 80, 
                                                                          "quest_title"       => "the second quest"),
                                                   3/*quest_id*/ => array("percent_completed" => 50, 
                                                                          "quest_title"       => "the 3rd quest")
                                                  )
                             );

$player_npc_status = array("npc"  => array( 1 => array("name"  => "lawrence",
                                                       "tasks" => array( 1 => array("task_title"   => "title 1",
                                                                                    "is_completed" => 1),
                                                                         2 => array("task_title"   => "title 2",
                                                                                    "is_completed" => 1),
                                                                         3 => array("task_title"   => "title 3",
                                                                                    "is_completed" => 0))
                                                      ),
                                            2 => array("name"  => "viscocent",
                                                       "tasks" => array( 1 => array("task_title"   => "title 4",
                                                                                    "is_completed" => 1),
                                                                         2 => array("task_title"   => "title 5",
                                                                                    "is_completed" => 2),
                                                                         3 => array("task_title"   => "title 6",
                                                                                    "is_completed" => 0))
                                                      ),
                                         )

                           );
Community
  • 1
  • 1
Viscocent
  • 2,024
  • 2
  • 19
  • 26
  • Would the database look like the UserTasks table I showed above? – user3871 May 12 '14 at 19:32
  • @Growler you will probably add more tables like quests and npc to store meta data. these will be the once used to populate the array for first use. – Viscocent May 13 '14 at 07:18
1

I suppose independently from the Quest/Task tree stored, it is sufficient to store the progress of the game simply store the currentLevel, currentQuest and the number of tasks done for each NPC of the quest as you've mentioned. Depending on how you have stored it, I would have an array or object that stores the current quest. For example, for user 1, it would look something like

var currLevel = 2;
var currQuest = 2;
var currNpc   =2
var subquests = [3,1,3]; //or {"NPC1":3,"NP2":1,"NPC3":3}

//progress task
subquests[currNpc]= subquests[currNpc] ? subquests[currNpc]+1 : 1

//next quest
currQuest++
subquests=[]

So depending on your workflow, you can produce a JSON string from an array or object by doing

var str=JSON.stringify(subquests);  //javascript
$str=json_encode($array);           //PHP

Which you can store in the database. You can then restore the value either in javascript or php (depending on your workflow) with

var subquests=JSON.parse(json_string);  //javascript
$subquests=json_decode($json_string);   //PHP

The database would look something like this sqlfiddle I suppose http://sqlfiddle.com/#!2/8d436/1/0

mfirdaus
  • 4,574
  • 1
  • 25
  • 26