- Joined
- May 14, 2020
- Messages
- 7
- Reaction score
- 4
- First Language
- English
- Primarily Uses
- RMMV
Ahoy! Just picked up RMMV on the recent HumbleBundle sale, and tried making a little plugin to get my feet wet with this newfangled system. I'd like to make a game where the skills used by the main hero changes their class over time - specifically based off of the elemental properties of the skills that they're using and possibly also what they're getting hit with. Step 1 of getting that kind of system set up is to set up some tracking, which brings us to today's plugin!
Not sure if anyone else has already made something like this before - I'm totally new here and didn't look around for an existing solution before whipping something up myself. If it's something that you might find useful, I'd love to know what you would use it for and what kinds of commands or additional information you would like to flesh this out a bit more!
Currently, this plugin tracks the following data for each actor:
Some ideas that I had that you might be able to use this kind of information for (*may require extra scripts or plugins to execute):
Not sure what the preferred way to share code here is yet - Here it is behind a spoiler tag, and I've also tried attaching it as a file to this post:
Making nice plugin commands is still on the TODO list - will hopefully get some time to flesh that bit out this weekend or next - so if you're interested in using this tracker and would like certain commands please let me know and I'll try to work 'em in!
Feel free to use this for your projects if it's helpful. I would love to hear what you end up using it for, and if you get to the point where you need to thank the little people I can be credited with as this username.
Not sure if anyone else has already made something like this before - I'm totally new here and didn't look around for an existing solution before whipping something up myself. If it's something that you might find useful, I'd love to know what you would use it for and what kinds of commands or additional information you would like to flesh this out a bit more!
Currently, this plugin tracks the following data for each actor:
- Count of how many times each skill has been used
- For each element defined in the game:
- Count of how many times the actor has used skills of this element
- Count of how many times the actor has been hit by skills of this element
- Total HP damage inflicted by this element
- Total HP damage received from this element
- Total HP healing given through this element
- Total HP healing received through this element
- Total MP spent on skills of this element by the actor
- Total MP spent by others when targeting the actor with this element
- Total TP spent by the actor on this element
- Total TP regained by using skills of this element
- Total TP spent by others targeting the actor
Some ideas that I had that you might be able to use this kind of information for (*may require extra scripts or plugins to execute):
- Use to collect player data to find which skills are overused/underused
- Unlock new skills when the prerequisite skills have been used a certain number of times
- Set status conditions on heroes if they have been subjected to certain types of elements or attacks too many times between rests
- Let characters get better at using skills with practice
- Penalize characters for 'stale moves' if they spam a single action type
- Create branching class paths based on character tactics
- Create a nemesis/rival recurring NPC that tries to counter the player's dominant strategy
Not sure what the preferred way to share code here is yet - Here it is behind a spoiler tag, and I've also tried attaching it as a file to this post:
Code:
/* ************************************************************************************************
SKILL TRACKER - SkillTracker.js
Collect information about the skills and elements used by and against each hero
************************************************************************************************ */
/*:
* @plugindesc Automatically collect and save skill usage data.
* Use for analytics, usage-based skill progression, etc. This plugin just gives the data, how to use that knowledge is up to you!
* Usage ideas (*may require extra scripts or plugins to execute):
* - Use to collect player data to find which skills are overused/underused
* - Unlock new skills when the prerequisite skills have been used a certain number of times
* - Set status conditions on heroes if they have been subjected to certain types of elements or attacks too many times between rests
* - Let characters get better at using skills with practice
* - Penalize characters for 'stale moves' if they spam a single action type
* - Create branching class paths based on character tactics
* - Create a nemesis/rival recurring NPC that tries to counter the player's dominant strategy
*
* @author David Bilsky ("Ironskink")
*
* @help This plugin does not provide any commands yet (TODO!)
*
* @param skillSummaryId
* @desc Variable ID where the Skill Summary object is to be saved (or 0 to not save a skill summary).
* The skill summary object provides the following tracking info for each hero:
* skillUseCount: Count of how many times each skill has been used by a hero (or 'undefined' if a skill has never been used), tracked by skill ID
* [element name/element id]: Breakdown of each hero's interactions with all of your game's elemental types, tracked by element ID and element name, including:
* useCount # of times the hero used elemental skills of this type
* useTotalTP Total TP spent on skills of this elemental type
* useTotalMP Total MP spent on skills of this elemental type
* useTotalDmg Total damage inflicted on targets using skills of this elemental type
* useTotalHeal Total damage healed by targets when using skills of this elemental type
* gainedTotalTP Total TP gained by using skills of this elemental type
* endureCount # of times the hero has been hit with attacks of this type
* endureTotalTP Total TP spent on skills of this element that target this hero
* endureTotalMP Total MP spent on skills of this element that target this hero
* endureTotalDmg Total amount of elemental damage this hero has endured
* endureTotalHeal Total amount of elemental healing this hero has received
*
*
* @param actionVarId
* @desc Variable ID where the most recently used action object should be stored (or 0 to not save to game variables)
* @default 0
*
* @param actorVarId
* @desc Variable ID where the most recent character object (hero or enemy) should be stored (or 0 to not save to game variables)
* @default 0
*
* @param targetsVarId
* @desc Variable ID where the array of targets for the most recent action should be stored (or 0 to not save to game variables). This will be an array containing Game_Actor and/or Game_Enemy objects
* @default 0
*
*
*/
//$dataSystem.elemenets
//$dataSkills[11].damage.elementId
//action._item._dataClass, action._item._itemId
(function(){
const params = PluginManager.parameters('SkillTracker');
const original_pluginCommand = Game_Interpreter.prototype.pluginCommand;
const original_startAction = Window_BattleLog.prototype.startAction;
const original_makeDamageValue = Game_Action.prototype.makeDamageValue; //function(target, critical)
let elementSummary = null;
Game_Interpreter.prototype.pluginCommand = function(command, args){
original_pluginCommand.call(this, command, args);
if(command !== 'SkillTracker'){
return;
}
const cmdName = args[0];
switch(cmdName){
case 'get':
// TODO
break;
case 'set':
// TODO
break;
case 'reset':
// TODO
break;
case 'snapshot':
//TODO
break;
default:
console.error('SkillTracker: Unknown command "' + cmdName +'"');
}
}
Window_BattleLog.prototype.startAction = function(subject, action, targets){
const returnVal = original_startAction.call(this, subject, action,targets);
saveInfoToGameVars(subject, action, targets)
saveElementSummary(subject, action, targets)
params.skillSummaryId && $gameVariables.setValue(params.skillSummaryId, elementSummary)
return returnVal;
}
Game_Action.prototype.makeDamageValue = function(target, critical){
const damage = original_makeDamageValue.call(this, target, critical);
const subject = this.subject();
const action = this;
saveElementDamage(subject, action, target, damage)
return damage;
}
function saveInfoToGameVars(subject, action, targets){
params.actionVarId && $gameVariables.setValue(params.actionVarId, action)
params.actorVarId && $gameVariables.setValue(params.actorVarId, subject)
params.targetsVarId && $gameVariables.setValue(params.targetsVarId, targets.map( (t) => t ))
}
function saveElementSummary(subject, action, targets){
if(params.skillSummaryId && action._item._dataClass == 'skill'){
elementSummary = elementSummary || $gameVariables.value(params.skillSummaryId) || {};
let skill = $dataSkills[action._item._itemId];
const elementId = skill.damage.elementId;
const elementName = $dataSystem.elements[elementId] || getGenericName(elementId);
const actionId = action._item._dataClass + '_' + action._item._itemId;
if(subject instanceof Game_Actor){
let summary = elementSummary[subject._name] = elementSummary[subject._actorId] = elementSummary[subject._actorId] || initializeSummary(subject)
summary[elementName] = summary[elementId] = summary[elementId] || initializeElement(elementId);
summary[elementId].useCount ++;
summary[elementId].useTotalTP += skill.tpCost;
summary[elementId].useTotalMP += skill.mpCost;
summary[elementId].gainedTotalTP += skill.tpGain;
summary.skillUseCounts[actionId] = (summary.skillUseCounts[actionId] || 0) + 1;
}
for(let t=0; t<targets.length; t++){
let target = targets[t];
if(target instanceof Game_Actor){
let summary = elementSummary[target._actorId] = elementSummary[target._actorId] || initializeSummary(target)
summary[elementName] = summary[elementId] = summary[elementId] || initializeElement(elementId);
summary[elementId].endureCount ++;
summary[elementId].endureTotalTP += skill.tpCost;
summary[elementId].endureTotalMP += skill.mpCost;
}
}
}
}
function saveElementDamage(subject, action, target, damage){
if(params.skillSummaryId && action._item._dataClass == 'skill'){
elementSummary = elementSummary || $gameVariables.value(params.skillSummaryId) || {};
let skill = $dataSkills[action._item._itemId];
const elementId = skill.damage.elementId;
const elementName = $dataSystem.elements[elementId] || getGenericName(elementId);
if(subject instanceof Game_Actor){
let summary = elementSummary[subject._name] = elementSummary[subject._actorId] = elementSummary[subject._actorId] || initializeSummary(subject)
summary[elementName] = summary[elementId] = summary[elementId] || initializeElement(elementId);
if(damage > 0){
summary[elementId].useTotalDmg += damage;
}
else{
summary[elementId].useTotalHeal -= damage;
}
}
if(target instanceof Game_Actor){
let summary = elementSummary[target._actorId] = elementSummary[target._actorId] || initializeSummary(target)
summary[elementId] = summary[elementId] || initializeElement(elementId);
if(damage > 0){
summary[elementId].endureTotalDmg += damage;
}
else{
summary[elementId].endureTotalHeal -= damage;
}
}
}
}
function initializeSummary(actor){
return {
actor: actor,
skillUseCounts: {}
}
}
function initializeElement(elementId){
return{
name: $dataSystem.elements[elementId] || getGenericName(elementId),
useCount: 0,
useTotalTP: 0,
useTotalMP: 0,
useTotalDmg: 0,
useTotalHeal: 0,
gainedTotalTP: 0,
endureCount: 0,
endureTotalTP: 0,
endureTotalMP: 0,
endureTotalDmg: 0,
endureTotalHeal: 0
}
}
function getGenericName(elementId){
switch(elementId){
case -1:
return 'Normal Attack';
case 0:
return 'None';
default:
return 'Unnamed-' + elementId
}
}
})()
Making nice plugin commands is still on the TODO list - will hopefully get some time to flesh that bit out this weekend or next - so if you're interested in using this tracker and would like certain commands please let me know and I'll try to work 'em in!
Feel free to use this for your projects if it's helpful. I would love to hear what you end up using it for, and if you get to the point where you need to thank the little people I can be credited with as this username.
Attachments
-
8.8 KB Views: 6


