- Joined
- Jul 22, 2014
- Messages
- 5,635
- Reaction score
- 5,116
- First Language
- English
- Primarily Uses
- RMVXA
First of all, thank you to everyone for all the helpful responses! 
To give a hopefully clearer example of why I feel there's a widespread need for not only documentation but additional information to tie all of the code together: assume a moderately competent JS programmer opens up his game's Script Base for the first time because she wants to make a couple of very simple changes to the Sell Window (perhaps a small layout adjustment to the position of each column, and an extra requirement for having an item appear on this screen).
1) First off, she has to find that window. She can't search for "Sell Window" or even "WindowSell", although opening the correct file (rpg_windows) and searching "Sell" will eventually get her there. Here's the code for that Window:
Well. That's not super helpful.
2) The first pain point is going to be the "arguments" parameter. A good guide would explain that the screen x, screen y, window width, and window height are being passed in here from the createSellWindow method. It might go on to explain the basics of how it gets those values, or link to the more thorough documentation on that particular method.
3) Rather than being able to see how the sellable items are processed and written to the screen, all that our neophyte MV scripter will see from this section is that the window is inheriting some of its behavior from Window_ItemList. Okay, let's check out that window:
This is getting intimidating...
4) Some elements on this window are pretty clear; for example it should be clear what _category is doing (though it would take a lot of additional searching to understand how and when it's changed). But there are other methods that are going to be big obstacles for someone who's not already intimately familiar with MV's code base:
What a disaster.
5) Skill and Item conditions now? How do these work? Why is the behavior being checked from the Sell window? There's a reason for this apparent irrationality, of course (see #6), but surely you can see how confusing this would be to a beginning scripter, no matter how well they understand the syntax and logic of JS?
6) Back to the original Window_ShopSell window, let's check out the last function. Woops! Looks like this child window has its own isEnabled() method, which simply checks whether there is an item and its price is greater than 0 (and our scripter might wonder whether "price" is the shop's sell price, the base price of the item from the Database, or what). All that tracing she did to the Actor's "canUse" function and beyond was wasted time - those functions are actually for Item Lists made from Usable Item (skill/item) windows. A short initial explanation of what the window was doing (looking for items with a base price above 0 and listing them at the screen x/y, width, and height provided) would have saved hours of confused searching and parsing of method calls.
None of this is to say that MV's code base is poorly written or constructed; I think it serves as a good illustration as to how some acquired expertise could go a really long way toward saving newer MV scripters a ton of time and frustration, and helping them make simple changes to their game without needing to become experts themselves (or make request after helpless request from scripters who have put in the time).
Thanks so much for offering this, it is very kind of you! The sticking points I've had in the past month have mostly been figuring out Battle Flow (under which conditions stages of battle transition to one another, when/how those conditions are actually checked, and what is used to actually apply a skill's effect to a battler) and Animations (how each frame is processed and the viewports, etc., needed to show an Animation's pictures onscreen, how to force an Animation to appear onscreen from any given scene).
With that being said, my point in posting this topic was not to ask for help about the things I'm personally having trouble with, but to express what I feel is a larger, community-wide need for a holistic guide to understanding everything in the script base and how each method/object relates to the others. I agree with @DoubleX that such guides to specific elements of the game are quite helpful (a few tidbits from Hime's ATB walkthrough actually got me off the ground trying to figure out the battle system back in January), but I'm certain that an entire, consistent guide would do even more good than these disparate one-off guides about specific elements.
To give a hopefully clearer example of why I feel there's a widespread need for not only documentation but additional information to tie all of the code together: assume a moderately competent JS programmer opens up his game's Script Base for the first time because she wants to make a couple of very simple changes to the Sell Window (perhaps a small layout adjustment to the position of each column, and an extra requirement for having an item appear on this screen).
1) First off, she has to find that window. She can't search for "Sell Window" or even "WindowSell", although opening the correct file (rpg_windows) and searching "Sell" will eventually get her there. Here's the code for that Window:
Code:
function Window_ShopSell() {
this.initialize.apply(this, arguments);
}
Window_ShopSell.prototype = Object.create(Window_ItemList.prototype);
Window_ShopSell.prototype.constructor = Window_ShopSell;
Window_ShopSell.prototype.initialize = function(x, y, width, height) {
Window_ItemList.prototype.initialize.call(this, x, y, width, height);
};
Window_ShopSell.prototype.isEnabled = function(item) {
return item && item.price > 0;
};
Well. That's not super helpful.
2) The first pain point is going to be the "arguments" parameter. A good guide would explain that the screen x, screen y, window width, and window height are being passed in here from the createSellWindow method. It might go on to explain the basics of how it gets those values, or link to the more thorough documentation on that particular method.
3) Rather than being able to see how the sellable items are processed and written to the screen, all that our neophyte MV scripter will see from this section is that the window is inheriting some of its behavior from Window_ItemList. Okay, let's check out that window:
Code:
//-----------------------------------------------------------------------------
// Window_ItemList
//
// The window for selecting an item on the item screen.
function Window_ItemList() {
this.initialize.apply(this, arguments);
}
Window_ItemList.prototype = Object.create(Window_Selectable.prototype);
Window_ItemList.prototype.constructor = Window_ItemList;
Window_ItemList.prototype.initialize = function(x, y, width, height) {
Window_Selectable.prototype.initialize.call(this, x, y, width, height);
this._category = 'none';
this._data = [];
};
Window_ItemList.prototype.setCategory = function(category) {
if (this._category !== category) {
this._category = category;
this.refresh();
this.resetScroll();
}
};
Window_ItemList.prototype.maxCols = function() {
return 2;
};
Window_ItemList.prototype.spacing = function() {
return 48;
};
Window_ItemList.prototype.maxItems = function() {
return this._data ? this._data.length : 1;
};
Window_ItemList.prototype.item = function() {
var index = this.index();
return this._data && index >= 0 ? this._data[index] : null;
};
Window_ItemList.prototype.isCurrentItemEnabled = function() {
return this.isEnabled(this.item());
};
Window_ItemList.prototype.includes = function(item) {
switch (this._category) {
case 'item':
return DataManager.isItem(item) && item.itypeId === 1;
case 'weapon':
return DataManager.isWeapon(item);
case 'armor':
return DataManager.isArmor(item);
case 'keyItem':
return DataManager.isItem(item) && item.itypeId === 2;
default:
return false;
}
};
Window_ItemList.prototype.needsNumber = function() {
return true;
};
Window_ItemList.prototype.isEnabled = function(item) {
return $gameParty.canUse(item);
};
Window_ItemList.prototype.makeItemList = function() {
this._data = $gameParty.allItems().filter(function(item) {
return this.includes(item);
}, this);
if (this.includes(null)) {
this._data.push(null);
}
};
Window_ItemList.prototype.selectLast = function() {
var index = this._data.indexOf($gameParty.lastItem());
this.select(index >= 0 ? index : 0);
};
Window_ItemList.prototype.drawItem = function(index) {
var item = this._data[index];
if (item) {
var numberWidth = this.numberWidth();
var rect = this.itemRect(index);
rect.width -= this.textPadding();
this.changePaintOpacity(this.isEnabled(item));
this.drawItemName(item, rect.x, rect.y, rect.width - numberWidth);
this.drawItemNumber(item, rect.x, rect.y, rect.width);
this.changePaintOpacity(1);
}
};
Window_ItemList.prototype.numberWidth = function() {
return this.textWidth('000');
};
Window_ItemList.prototype.drawItemNumber = function(item, x, y, width) {
if (this.needsNumber()) {
this.drawText(':', x, y, width - this.textWidth('00'), 'right');
this.drawText($gameParty.numItems(item), x, y, width, 'right');
}
};
Window_ItemList.prototype.updateHelp = function() {
this.setHelpWindowItem(this.item());
};
Window_ItemList.prototype.refresh = function() {
this.makeItemList();
this.createContents();
this.drawAllItems();
};
This is getting intimidating...
4) Some elements on this window are pretty clear; for example it should be clear what _category is doing (though it would take a lot of additional searching to understand how and when it's changed). But there are other methods that are going to be big obstacles for someone who's not already intimately familiar with MV's code base:
- The window's construction inherits from Window_Selectable which in turn inherits from Window_Base. Starting with Window_ShopSell, we're now at 4 levels of inheritance.
- You can't search for "Column" - you'd have to find it under maxCols(). This isn't a problem if you're already here, but searching through the entire project to find "how are columns demarcated in general" will be problematic.
- The changePaintOpacity() method is passed a boolean, and is passed an integer three lines later. Confusing. Wouldn't it be nice to know, at a glance, why we are calling this method and what we need to pass in?
- The makeItemList() method is probably the most important thing our scripter needs to follow for modifying the Sell window, as it displays everything that's appropriate from the player's inventory. It's referencing several other methods without an immediately clear reason why, and it's evaluating whether the object includes "null", in which case it will push a null value into the data list. Not only do I think our scripter is confused, but after a bit of searching, I have no idea why it's doing this!
- The "isCurrentItemEnabled" method isn't used directly anywhere on this window at this child level... what do we do with it? Is it important as our scripter tries to make her change?
- That same method references isEnabled() ... okay, that's an easy find, just a few lines down. That method references the party's canUse() method. The party's canUse() method, in turn, references the actor's canUse() method so our scripter would need to figure out that Actor is a grandchild of BattlerBase. Fine, so let's check out BattlerBase's version of this method...
Game_BattlerBase.prototype.canUse = function(item) {
if (!item) {
return false;
} else if (DataManager.isSkill(item)) {
return this.meetsSkillConditions(item);
} else if (DataManager.isItem(item)) {
return this.meetsItemConditions(item);
} else {
return false;
}
};
if (!item) {
return false;
} else if (DataManager.isSkill(item)) {
return this.meetsSkillConditions(item);
} else if (DataManager.isItem(item)) {
return this.meetsItemConditions(item);
} else {
return false;
}
};
What a disaster.
5) Skill and Item conditions now? How do these work? Why is the behavior being checked from the Sell window? There's a reason for this apparent irrationality, of course (see #6), but surely you can see how confusing this would be to a beginning scripter, no matter how well they understand the syntax and logic of JS?
6) Back to the original Window_ShopSell window, let's check out the last function. Woops! Looks like this child window has its own isEnabled() method, which simply checks whether there is an item and its price is greater than 0 (and our scripter might wonder whether "price" is the shop's sell price, the base price of the item from the Database, or what). All that tracing she did to the Actor's "canUse" function and beyond was wasted time - those functions are actually for Item Lists made from Usable Item (skill/item) windows. A short initial explanation of what the window was doing (looking for items with a base price above 0 and listing them at the screen x/y, width, and height provided) would have saved hours of confused searching and parsing of method calls.
None of this is to say that MV's code base is poorly written or constructed; I think it serves as a good illustration as to how some acquired expertise could go a really long way toward saving newer MV scripters a ton of time and frustration, and helping them make simple changes to their game without needing to become experts themselves (or make request after helpless request from scripters who have put in the time).
What part in particular are you wanting a guide on?
There is lots of code but if you narrow it down I could probably help out.
Thanks so much for offering this, it is very kind of you! The sticking points I've had in the past month have mostly been figuring out Battle Flow (under which conditions stages of battle transition to one another, when/how those conditions are actually checked, and what is used to actually apply a skill's effect to a battler) and Animations (how each frame is processed and the viewports, etc., needed to show an Animation's pictures onscreen, how to force an Animation to appear onscreen from any given scene).
With that being said, my point in posting this topic was not to ask for help about the things I'm personally having trouble with, but to express what I feel is a larger, community-wide need for a holistic guide to understanding everything in the script base and how each method/object relates to the others. I agree with @DoubleX that such guides to specific elements of the game are quite helpful (a few tidbits from Hime's ATB walkthrough actually got me off the ground trying to figure out the battle system back in January), but I'm certain that an entire, consistent guide would do even more good than these disparate one-off guides about specific elements.



