Best way to add custom stat parameters, and edit level ups

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
88
Reaction score
16
First Language
English
Primarily Uses
RMMV
What would be the best way for me to add additional stat parameters to my actors? Mainly, I want to add Strength, Vitality, Intelligence and Wisdom. I also want to edit the level up system to not use the parameter tables, but to add a random value pulled from a min, max range for each stat in the Class notetags. I also want to edit the built in Agility and Luck to do the same thing.

However, I would like for HP to only increase a small amount + a bonus based on Vitality gained that level, and the same to go for MP and Intelligence. I also want Int to affect the Mat and Wis to affect the Mdf of the actor. Attack I want to equal Strength and Defense to equal Vitality.

What would be the best way to write a plugin like this? Where would I need to start?
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
2,589
Reaction score
3,780
First Language
English
Primarily Uses
RMMV
Check out how Game_BattlerBase, Game_Battler, and Game_Actor are coded. It shouldn't be too complicated (pretty obvious when you read the code). Couple things though to achieve what you're looking for:
  • The moment you add random values to parameters during level up you'll have to redo how the parameter system and the level up system works. By default an actor's parameters aren't stored in save files since the parameters are functions (like y = 2.5x + 10, and x is equal the level, that function is called every time you call the parameter). So you'll have to change that.
  • You'll also have to re-write the parameter system since they are all independent from each other by default (one parameter doesn't affect another one), which isn't what you want since you want to have parameters like vitality which, if I understand correctly, affect other parameters.
  • Not sure if you want those change to also affect enemies. If so, you'll need a system to adapt the enemies to the new system.
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
1,510
Reaction score
992
First Language
EN
Primarily Uses
RMMV
I don't think it'll need a rework: I imagine you can define your new parameters much like the existing ones and simply store the random level-up increments in the appropriate _paramPlus slot (same thing as used by the Change Parameter command). :)

Note that the three different param types are treated differently: basic params (MHP, MMP, ATK, etc) are integers and multiple sources add together; extra/special params are percentages and add/multiply, respectively.

Some relevant snippets from rpg_objects.js for basic params:
JavaScript:
Object.defineProperties(Game_BattlerBase.prototype, {
//...
    // Maximum Hit Points
    mhp: { get: function() { return this.param(0); }, configurable: true },
//...
}

Game_BattlerBase.prototype.param = function(paramId) {
    var value = this.paramBase(paramId) + this.paramPlus(paramId);
    value *= this.paramRate(paramId) * this.paramBuffRate(paramId);
    var maxValue = this.paramMax(paramId);
    var minValue = this.paramMin(paramId);
    return Math.round(value.clamp(minValue, maxValue));
};

Game_BattlerBase.prototype.paramPlus = function(paramId) {
    return this._paramPlus[paramId];
};

Game_Actor.prototype.paramBase = function(paramId) {
    return this.currentClass().params[paramId][this._level];
};
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
2,589
Reaction score
3,780
First Language
English
Primarily Uses
RMMV
I don't think it'll need a rework: I imagine you can define your new parameters much like the existing ones and simply store the random level-up increments in the appropriate _paramPlus slot (same thing as used by the Change Parameter command). :)
That would literally be the same thing reworking the parameter system... since you're already adding a variable per parameter (or an array containing all the parameters) to store the random part of the parameter, why shouldn't you just store the entire parameter? It would require exactly the same amount of memory and it would save the engine the calculation of the paramBase everytime (since it calculates it everytime). Even if it doesn't really affect performance that much, it's still optimization.
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
88
Reaction score
16
First Language
English
Primarily Uses
RMMV
So, I could potentially define my new parameters much like mhp, mmp, atk are defined, making sure I don't overwrite any existing paramIDs? I'm brand new to Javascript, so in Javascript, how do I reference a function like this so I can define new parameters, and how do I overwrite it without editing the original game code
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
1,510
Reaction score
992
First Language
EN
Primarily Uses
RMMV
That would literally be the same thing reworking the parameter system... since you're already adding a variable per parameter (or an array containing all the parameters) to store the random part of the parameter, why shouldn't you just store the entire parameter? It would require exactly the same amount of memory and it would save the engine the calculation of the paramBase everytime (since it calculates it everytime). Even if it doesn't really affect performance that much, it's still optimization.
I guess we're using the word "rework" differently...to me the word means something along the lines of "remake", which seems totally unnecessary here. :kaoback:

I'm thinking you could alias the paramBase method, e.g.
JavaScript:
(function(alias) {
    Game_Actor.prototype.paramBase = function(paramId) {
        if (paramId < 8) return alias.apply(this, arguments);
        return parseInt(this.currentClass().meta["Initial param " + paramId], 10) || 0;
    };
})(Game_Actor.prototype.paramBase);
Then just define the new properties on Game_BattlerBase and you're done? (Well, apart from the level up stuff, that's another alias.) I'd hardly consider that a "rework". Maybe I'm missing something, though. :kaoswt:
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
88
Reaction score
16
First Language
English
Primarily Uses
RMMV
I guess we're using the word "rework" differently...to me the word means something along the lines of "remake", which seems totally unnecessary here. :kaoback:

I'm thinking you could alias the paramBase method, e.g.
JavaScript:
(function(alias) {
    Game_Actor.prototype.paramBase = function(paramId) {
        if (paramId < 8) return alias.apply(this, arguments);
        return parseInt(this.currentClass().meta["Initial param " + paramId], 10) || 0;
    };
})(Game_Actor.prototype.paramBase);
Then just define the new properties on Game_BattlerBase and you're done? (Well, apart from the level up stuff, that's another alias.) I'd hardly consider that a "rework". Maybe I'm missing something, though. :kaoswt:
So doing it this way. I can change the if(paramId < 8) to how many parameters I want, then it looks like currentClass().meta, that's reading from a note tag correct?
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
2,589
Reaction score
3,780
First Language
English
Primarily Uses
RMMV
@RedFoxGaming You'll get an error if you do that because the default parameter system reas the class parameter function to determine the value, and since there are no graph for your parameters in the database it will throw you an error.

Furthermore, as me and @caethyril pointed out (call it rework or whatever), since you want to incorporate some random boost for parameters during level up you'll need to store those values inside the object. By default the engine doesn't save the actor's parameters in the save file since the parameter is calculated from a fixed function, so the actor only needs to store his/her level into the save file. To put it in easier term, each parameter formed by a graph that you can modify in the database is like a mathematical function:
Code:
atk = growth * level + base;
So there is no need to save the value of atk into the save file since with the character's level you can easily calculate it (assuming that growth and base are constants, which they are in the default engine). Now, if you add a random element every time you level up you'll need to save that into the save file.
 

RedFoxGaming

Veteran
Veteran
Joined
Jan 14, 2018
Messages
88
Reaction score
16
First Language
English
Primarily Uses
RMMV
Well, while I am still very much a beginner in Javascript, maybe it would be best to just start with adding the custom parameters and using a function to calculate the stats first, like the regular parameters are calculated, and go from there once I figure out how to do it and get that working.
 

MushroomCake28

KAMO Studio
Global Mod
Joined
Nov 18, 2015
Messages
2,589
Reaction score
3,780
First Language
English
Primarily Uses
RMMV
That would be easier indeed, you would just need to follow the pre-existing format.
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
1,510
Reaction score
992
First Language
EN
Primarily Uses
RMMV
To clarify, just in case: _paramPlus (i.e. permanent bonus/malus to each basic parameter) is saved by default. That's mostly why I suggested it for the random level up stuff~

So doing it this way. I can change the if(paramId < 8) to how many parameters I want, then it looks like currentClass().meta, that's reading from a note tag correct?
No need to change the 8 or anything! If paramId is less than 8, then it's one of the existing basic params, e.g. MHP (paramId 0), MMP, (1), LUK (7), etc. So my example says "if it's a default basic param, return the original method, else return a value from a class notetag (or zero if that notetag doesn't exist)". (No explicit else is required here because the return statement ends the function.) :kaopride:

To answer your question, yes, notetag values are stored under the meta property on the appropriate database record. The currentClass method gets the $dataClasses entry corresponding to the actor's current class. If you put notetags like this in the notebox of class #1 in the database:
<Param 8 Base: 50>
<Param 8 Level-Up: 5 to 10>
...then you can access those notetag values at runtime like this:
JavaScript:
// Convert base value to integer
parseInt($dataClasses[1].meta["Param 8 Base"], 10)
// Convert level-up bonus to an array of integers, separated by the word "to"
$dataClasses[1].meta["Param 8 Level-Up"].split("to").map(function(n) { return parseInt(n, 10); });
Note that all meta values are stored as strings (i.e. text), which is why I've included type conversions here. Methods I've used here (including links to documentation): parseInt (use Number for non-integers), String.split, Array.map. :kaothx:
 

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

Latest Threads

Latest Posts

Latest Profile Posts

*Buys all the PVGames assets, ends up creating his own ground tiles.* At least I used the other types of graphics? Right? :kaoswt:
If you could fold a sheet of paper 42 times, the stack would reach from the earth to the moon. Do whatever you want with that information.
wishing that everyone stays safe at this time
Ami
4 days im not using my laptop to waiting someone to reinstall (sigh)
Stream will be live shortly with some Donkey Kong 64! Feel free to drop by!

Forum statistics

Threads
95,493
Messages
929,577
Members
125,744
Latest member
FoxStyle
Top