1. I suppose the original JSON data files won't be changed during the pre-load phase, because it'd involve database entries diffing and separating original and inherited data in the inherited database entries, which would be way too complicated and convoluted to worth the cost of doing so
2. If the original JSON data files really don't change one bit as expected, this probably means
the inherited data have to be stored in the memory, which can be quite sizeable when the database, and the average inheritance breadth(a database entry inherits from many other database entries)
and depth(A1 inherits from A2, A2 inherits from A3, A3 inherits from A4, ..., An-1 inherits from An, and n is the depth)
are large, and this memory consumption can be a problem in mobile platforms, like a low-end Android phone, where the "out of memory" risk can become pretty high
So, instead of database inheritance(inherited data are bound in the game starting time, just like OOP inheritance are on the compilation time), I'd suggest database composition(composite data uses its components upon having its composite data used, just like object compositions are on the run time):
1. For instance, let's say the damage formula of skill A is composed by that of skill B and C, instead of preloading the damage formula of skill A to be something like this:
JavaScript:
skillA.damage.formula = `(${skillB.damage.formula}) + (${skillC.damage.formula})`
How about changing the run time to be something like this?
JavaScript:
Game_Action.prototype.evalDamageFormula = function(target) {
try {
const item = this.item();
const a = this.subject(); // eslint-disable-line no-unused-vars
const b = target; // eslint-disable-line no-unused-vars
const v = $gameVariables._data; // eslint-disable-line no-unused-vars
const sign = [3, 4].includes(item.damage.type) ? -1 : 1;
// Edited to use the composed instead of the original formula if there are really composed ones
const value = Math.max(eval(item.composite.damage.formula.reduce((formula, skillId) => {
return `(${formula}) + (${$dataSkills[skillId].damage.formula})`;
}, item.damage.formula)), 0) * sign;
//
return isNaN(value) ? 0 : value;
} catch (e) {
return 0;
}
};
Where item.composite.damage.formula stores the list of id of skills to be inherited for the damage formula, and in this case, the list should be the id of skill B and C.
2. On the time consumption side, compared to having to pre-load everything upon game start, which causes the significant loading time increase with large database, and inheritance breadth and depth,
the composite item only has to compose its composite damage formula upon using it, and the extra time needed is nearly negligible per use, unless the formula's composed by those of hundreds of skills, in which pre-loading them all would be a disaster anyway
Of course, there will be times where some parts of a database entry will be accessed frequently, like being accessed per frame, and in this case, the time consumption can indeed become significant, leading to possible FPS drop in low-end mobile platforms, but for such parts, the inheritance approach can be used, meaning that:
i -
Parts of database entries being accessed per frame should be inherited
ii. -
Parts of database entries not being accessed this frequently should be composed
It's because,
the inheritance approach converges all the extra time consumptions on the pre-load phase, causing tons of small numbers to become a large number, whereas the composition approach diverges all the extra time consumptions on each use case, causing it to be still a small number per use, even when the sum of all those extra time consumptions will be much, much larger than that of the inheritance approach.
3. On the memory consumption side, compared to having to store all the pre-loaded data from inheritance,
the database composition approach only stores the notetag contents, and this part of the memory cost, which is a lot smaller in comparison, is the same as that of database inheritance, because those notetag contents have to be stored anyway