Tracking Player Data and Choices

frdbrick

Villager
Member
Joined
Sep 7, 2018
Messages
9
Reaction score
1
First Language
English
Primarily Uses
RMMV
Hi All,

I'm looking for help with a plugin that tracks player behavior and choices within an RPG game and then exports the file to txt file. Well, the file that it gets exported to isn't terribly important. The key is each time a player interacts with an event I get a timestamp associated with the event the player is interacting with, each time they receive dialogue I get a timestamp, each time they are presented with a choice I get the choice that they choose, and then finally, whenever they change maps I get a timestamp with the name of the new map. If at all possible it would also be nice to get a timestamp when a player enters the menu and selects and item but this is not at all necessary. Finally, once the player saves the game a file is exported either to a save file or to a cloud space. Ruiran has started a similar plugin that can be found here. However, this plugin only tracks movement and it has some major bugs, namely you can stop the game and continue without problem... but if you close out of the game and then re enter the game and hit continue the plugin crashes.

I have created a game that is designed to help people learn Chinese as a foreign language. I am hoping to use this plugin to collect data on player reading skills.

Any help with this would be greatly appreciated!

Cheers!
 

Aloe Guvner

Walrus
Veteran
Joined
Sep 28, 2017
Messages
1,628
Reaction score
1,115
First Language
English
Primarily Uses
RMMV

frdbrick

Villager
Member
Joined
Sep 7, 2018
Messages
9
Reaction score
1
First Language
English
Primarily Uses
RMMV
What format would the timestamp be? These are the options:

https://developer.mozilla.org/en-US...Global_Objects/Date#JavaScript_Date_instances


Just a timestamp?

Just the number of the choice? (like just the number 1 or 2)
Hi Aloe, Thanks so much for your help with this. But someone just came through on helping me fix a plugin that I had been working on. So, I now have my data tracker. You can see it in the spoiler below. It is almost complete, I have the events, player paths, dialogue, choices, and battle start and stop.... the only thing I'm missing now is the menu stuff (which would be great but not imperative). You'll notice that I have a sectino for menu access, but it's not working yet. I'll need to tinker with it a bit more. Then, I am also using the bbs_termwindow plugin to add an in-game dictionary for players. So, I'll need to find a way to add a call that timestamps every time they use that plugin and includes the vocabulary word. Though I think I can figure that out (fingers crossed).

Anyways, Thanks Again! I appreciate your response to this!


$testing = [];
$defaultSwitchId = Number(PluginManager.parameters("LudoSavePathing")["Default SwitchId"]) || 20;
$msaves = Number(PluginManager.parameters("LudoSavePathing")["Max Saves"]) || 20;
$titlesave = (PluginManager.parameters("LudoSavePathing")["Save on Title Screen"] == "true");

Scene_Map.prototype.onMapLoaded = function() {
if (this._transfer) {
$gamePlayer.performTransfer();
}
this.createDisplayObjects();
};

Scene_Load.prototype.reloadMapIfUpdated = function() {
$gamePlayer.reserveTransfer($gameMap.mapId(), $gamePlayer.x, $gamePlayer.y);
$gamePlayer.requestMapReload();
};


//=============================================================================
// Collecting Pathing Information
//=============================================================================

Game_Player.prototype.increaseSteps = function() {
Game_Character.prototype.increaseSteps.call(this);
if (this.isNormal()) {
$gameParty.increaseSteps();
if($msaves > 0 && $dataMap.meta.Track){
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Path", this._x, this._y]);
}
}
};

//=============================================================================
// Menu Access
//=============================================================================
Scene_Map.prototype.callMenu = function() {
SoundManager.playOk();
SceneManager.push(Scene_Menu);
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Menu On"]);
Window_MenuCommand.initCommandPosition();
$gameTemp.clearDestination();
this._mapNameWindow.hide();
this._waitCount = 2;
};

Scene_Menu.prototype.commandItem = function() {
SceneManager.push(Scene_Item);
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Item"]);
};

Scene_Skill.prototype.createSkillTypeWindow = function() {
var wy = this._helpWindow.height;
this._skillTypeWindow = new Window_SkillType(0, wy);
this._skillTypeWindow.setHelpWindow(this._helpWindow);
this._skillTypeWindow.setHandler('skill', this.commandSkill.bind(this));
this._skillTypeWindow.setHandler('cancel', this.popScene.bind(this));
this._skillTypeWindow.setHandler('pagedown', this.nextActor.bind(this));
this._skillTypeWindow.setHandler('pageup', this.previousActor.bind(this));
this.addWindow(this._skillTypeWindow);
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Skill"]);
};

Scene_Status.prototype.create = function() {
Scene_MenuBase.prototype.create.call(this);
this._statusWindow = new Window_Status();
this._statusWindow.setHandler('cancel', this.popScene.bind(this));
this._statusWindow.setHandler('pagedown', this.nextActor.bind(this));
this._statusWindow.setHandler('pageup', this.previousActor.bind(this));
this._statusWindow.reserveFaceImages();
this.addWindow(this._statusWindow);
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Status"]);
};
//=============================================================================
// Timestamps for Using/selecting Items,armor,weapons
//=============================================================================

Scene_ItemBase.prototype.useItem = function() {
this.playSeForItem();
this.user().useItem(this.item());
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Use_Item" ,this.item().name]);
this.applyItem();
this.checkCommonEvent();
this.checkGameover();
this._actorWindow.refresh();
};

Scene_ItemBase.prototype.showSubWindow = function(window) {
window.x = this.isCursorLeft() ? Graphics.boxWidth - window.width : 0;
window.show();
window.activate();
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Select_Item" ,this.item().name]);
};


Scene_Equip.prototype.onItemOk = function() {
SoundManager.playEquip();
this.actor().changeEquip(this._slotWindow.index(), this._itemWindow.item());
this._slotWindow.activate();
this._slotWindow.refresh();
this._itemWindow.deselect();
this._itemWindow.refresh();
this._statusWindow.refresh();
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Equip_Item" ,this.item().name]);
};

//$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Menu Off"]);

//=============================================================================
// Collects All EVent Info
//=============================================================================
Game_Player.prototype.startMapEvent = function(x, y, triggers, normal) {
if (!$gameMap.isEventRunning()) {
$gameMap.eventsXy(x, y).forEach(function(event) {
if (event.isTriggerIn(triggers) && event.isNormalPriority() === normal) {
event.start();
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Event_Start",event.event().name]);
}
});
}
};
//=============================================================================
// Battle Start and Stop Times
//=============================================================================
BattleManager.setup = function(troopId, canEscape, canLose) {
this.initMembers();
this._canEscape = canEscape;
this._canLose = canLose;
$gameTroop.setup(troopId);
$gameScreen.onBattleStart();
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Battle_Start",troopId]);
this.makeEscapeRatio();
};

BattleManager.endBattle = function(result) {
this._phase = 'battleEnd';
if (this._eventCallback) {
this._eventCallback(result);
}
if (result === 0) {
$gameSystem.onBattleWin();
} else if (this._escaped) {
$gameSystem.onBattleEscape();
}
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Battle_End", result]);
};

//=============================================================================
// All Text Info and Choices (n = choices, 0 is first choice)
//=============================================================================
Game_Message.prototype.allText = function() {
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(), "Text", this._texts]);
return this._texts.join('\n');
};

Game_Message.prototype.onChoice = function(n) {
if (this._choiceCallback) {
this._choiceCallback(n);
$testing.filter(function(test){ return test.id === $gameMap._mapId })[0].pathing.push([$gameSystem.playtimeText(),"Respond", this._choices,n]);
this._choiceCallback = null;
}
};

//=============================================================================
// Map Transfer Info
//=============================================================================

Game_Player.prototype.performTransfer = function() {
if (this.isTransferring()) {
this.setDirection(this._newDirection);
if (this._newMapId !== $gameMap.mapId() || this._needsMapReload) {
$gameMap.setup(this._newMapId);
this._needsMapReload = false;
}
this.locate(this._newX, this._newY);
if($dataMap.meta.Track && $msaves > 0){
console.log("runs");
var Ludoexample = $testing.filter(function(test){ return test.id === $gameMap._mapId });
if(Ludoexample.length == 0){
var b = {
id : this._newMapId,
pathing : [[$gameSystem.playtimeText(), "Transfer", this._newX,this._newY]],
}
$testing.push(b);
}
else Ludoexample[0].pathing.push([$gameSystem.playtimeText(), "Transfer", this._newX, this._newY]);
}

this.refresh();
this.clearTransferInfo();
}
};

Game_Switches.prototype.onChange = function() {
$gameMap.requestRefresh();
Game_Switches.saveFile(this._data[$defaultSwitchId]);
};

Game_Switches.saveFile = function(sw) {
if($msaves > 0 && sw){
console.log("Outputting file");
json = "";
$testing.forEach(function(element){
json += "{\n";
json += "\t" + '"Map_id" : "' + element.id + '",\n';
json += "{\t" + '"Pathing" : ' + '[\n';
element.pathing.forEach(function(array){
if(element.pathing.indexOf(array) == element.pathing.length-1){
json += "\t\t[" + '"' + array[0] + '"' + ", " + array[1] + ", " + array[2] + "," + array[3] + "]";
}
else json += "\t\t[" + '"' + array[0] + '"' + ", " + array[1] + ", " + array[2] + "," + array[3] + "],\n";
});
json += '\n\t]\n';
json += "}";
json += "\n";
});

StorageManager.saveToTestFile(json);

$msaves--;
}
}

StorageManager.saveToTestFile = function(json) {
var fs = require('fs');
var dirPath = this.localFileDirectoryPath();
var ref = Number(PluginManager.parameters("LudoSavePathing")["Max Saves"]) - $msaves + 1;
var playername = $gameActors.actor(1).name();
var filePath = this.localFileDirectoryPath() + playername + ref + ".txt";
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
fs.writeFileSync(filePath, json);


};

Scene_Menu.prototype.commandSave = function() {
if($titlesave) Game_Switches.saveFile(true);
Scene_GameEnd.clearTrackInfo();
SceneManager.push(Scene_Save);
};

/**
Scene_GameEnd.prototype.commandToTitle = function() {
if($titlesave) Game_Switches.saveFile(true);
Scene_GameEnd.clearTrackInfo();
this.fadeOutAll();
SceneManager.goto(Scene_Title);
};

Scene_Gameover.prototype.gotoTitle = function() {
if($titlesave) Game_Switches.saveFile(true);
Scene_GameEnd.clearTrackInfo();
SceneManager.goto(Scene_Title);
};
*/
Scene_GameEnd.clearTrackInfo = function(){
for(var i of $testing){
i.pathing = [];
}
}
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Posts

Latest Profile Posts

Couple hours of work. Might use in my game as a secret find or something. Not sure. Fancy though no? :D
Holy stink, where have I been? Well, I started my temporary job this week. So less time to spend on game design... :(
Cartoonier cloud cover that better fits the art style, as well as (slightly) improved blending/fading... fading clouds when there are larger patterns is still somewhat abrupt for some reason.
Do you Find Tilesetting or Looking for Tilesets/Plugins more fun? Personally I like making my tileset for my Game (Cretaceous Park TM) xD
How many parameters is 'too many'??

Forum statistics

Threads
105,867
Messages
1,017,062
Members
137,575
Latest member
akekaphol101
Top