[SCRIPTING] [RMMV] DYNAMIC ECONOMY WITH RPG MAKER MV

Posts

Pages: 1
I have recently started working on a project involving the dynamic sale and purchase of items in the game world.

Basically, my objective is to have a mini-economy based on regions, and in-game events (I thought about including scarcity, but it started becoming a little hard to get a model together.)

My only issue is the shop processing portion.
As you all know, prices in RPG MAKER are preset and can't really be modified in-game. Truly, I would just want to replace all my prices by variables, which would make them easily manipulated with dynamic events and locations, but have yet to find a solution.
I lack programming experience, so I wouldn't know what to modify, or how to modify the scripts and replace the <price> parameter which had a set number by a variable.
I thought about creating an artificial menu, where all the possible in-game items are shown and can be selected to be sold, but it felt wrong, and I believe it would be both annoying for me to create, and for the player to use.
I was wondering if anyone had any experience with creating games with variables as prices, or knew how to do it.

Luckily, I can still work on most of the game without having any actual functioning shops, but it will be a key feature, if I ever get it working. I have been building models for the change in price in the different region along with the different process that can be done on items. It really looks neat and even without that, the game based on trading could turn pretty fun solely using the special trade opportunities (not processed through shop, but given in the shape of a quest).

Well that's where I'm at. If anyone had any suggestions, questions, or comments, I would be very happy for any feedback.
I'm also very new to this community, so I apologies if I forgot something in writing this post.
Marrend
Guardian Angel of the Description Thread
17400
I half-wonder if looking under the hood of Myriad Cypher's shop-system might be useful? I mean, that game was made with VX Ace rather than MV. However, various item prices in that game are programmed to fluctuate by a certain amount from the price as defined by the Call Shop event-command.


Also-also, welcome to RMN! Share your creativity with us!
Craze
purity or absolution
13128
If you learn enough JS to figure out how to store variables and adjust them based on an action happening, this wouldn't be very difficult to make work. You could even adjust some stuff based on switches and in-game variables if you wanted. I suggest poking around scripts in a new project and editing stuff to see what fucks up.
When you want to know what code is run for a certain event command, a good place to start is the Game_Interpreter. All your game's code is under the "js" directory, and the interpreter code is defined in "rpg_objects.js".

If we search that file for "Shop" we find this is the code that gets run when an event opens the shop menu:
// Shop Processing
Game_Interpreter.prototype.command302 = function() {
    if (!$gameParty.inBattle()) {
        var goods = [this._params];
        while (this.nextEventCode() === 605) {
            this._index++;
            goods.push(this.currentCommand().parameters);
        }
        SceneManager.push(Scene_Shop);
        SceneManager.prepareNextScene(goods, this._params[4]);
    }
    return true;
};


We can call similar code in a script event, and provide our custom "goods" for the shop. The format for the "goods" variable looks like:
goods = [
    // Shop item 1 (item 12 with a custom price of 400G)
    [
        0, // Item type: 0 for item, 1 for weapon, 2 for armor
        12, // id from database
        1, // A value of 1 means use a custom price
        400 // Custom price value
    ],
    // Shop item 2 (armor 30 with a custom price of 800G)
    [
        2,
        30,
        1,
        800
    ]
]


To put it all together we can create a script command inside an event with the code:
var goods = [
    [ 0, 12, 1, 400 ],
    [ 2, 30, 1, 800 ]
]

SceneManager.push(Scene_Shop);
SceneManager.prepareNextScene(goods, false); // Use 'true' for a purchase only shop


If any of this seems way confusing, taking an intro to JavaScript course online should help.
author=Ramshackin
When you want to know what code is run for a certain event command, a good place to start is the Game_Interpreter. All your game's code is under the "js" directory, and the interpreter code is defined in "rpg_objects.js".

If we search that file for "Shop" we find this is the code that gets run when an event opens the shop menu:
// Shop Processing
Game_Interpreter.prototype.command302 = function() {
    if (!$gameParty.inBattle()) {
        var goods = [this._params];
        while (this.nextEventCode() === 605) {
            this._index++;
            goods.push(this.currentCommand().parameters);
        }
        SceneManager.push(Scene_Shop);
        SceneManager.prepareNextScene(goods, this._params[4]);
    }
    return true;
};

We can call similar code in a script event, and provide our custom "goods" for the shop. The format for the "goods" variable looks like:
goods = [
    // Shop item 1 (item 12 with a custom price of 400G)
    [
        0, // Item type: 0 for item, 1 for weapon, 2 for armor
        12, // id from database
        1, // A value of 1 means use a custom price
        400 // Custom price value
    ],
    // Shop item 2 (armor 30 with a custom price of 800G)
    [
        2,
        30,
        1,
        800
    ]
]

To put it all together we can create a script command inside an event with the code:
var goods = [
    [ 0, 12, 1, 400 ],
    [ 2, 30, 1, 800 ]
]

SceneManager.push(Scene_Shop);
SceneManager.prepareNextScene(goods, false); // Use 'true' for a purchase only shop

If any of this seems way confusing, taking an intro to JavaScript course online should help.

That helped out a lot! I don't know JavaScript, but I know enough of other languages to understand what's going on.

So now it's just a matter of calling an in-game variable instead of the custom price.

So something around
" 0, 1, 1, var 0001 "

(of course that doesn't work as of yet, I have to figure out what will call the in-game variable). I just hope there isn't some kind of fail-safe preventing me from calling an in-game variable.

I'll be playing around with that for a few hours to see if I can figure it out.
Alright!

Solved my issue: I changed my unknown by:

$gameVariables.value(x)

so the codes looks like:

 
var goods =
[
[ 0, 1, 1, $gameVariables.value(1) ],
[ 0, 2, 1, $gameVariables.value(2) ]
]
SceneManager.push(Scene_Shop);
SceneManager.prepareNextScene(goods, false);

and then created an event to set what x should be equal as, and now I can dynamically modify the price while in-game!

Thank you very much!

I'll give updates about the game development, now that I have the foundation for the store set up.
Update on:
author=winterlx
Alright!

Solved my issue: I changed my unknown by:

$gameVariables.value(x)

so the codes looks like:

 
var goods =
[
[ 0, 1, 1, $gameVariables.value(1) ],
[ 0, 2, 1, $gameVariables.value(2) ]
]
SceneManager.push(Scene_Shop);
SceneManager.prepareNextScene(goods, false);

and then created an event to set what x should be equal as, and now I can dynamically modify the price while in-game!

Thank you very much!

I'll give updates about the game development, now that I have the foundation for the store set up.



Though Buying price is working well, the selling price is not.
Due to RPG MAKERS assumption that I don't want to sell items at the same price than the player buys it. So the system is only half working as of now.

I also realized that if the item were originally priced at "0" in RPG MAKER, the script will not show the item's price until you buy it, but if you had any other value, the price would appear correctly.
A minor bug, but still relevant for aesthetics, and ease of use, so I put all prices at "1" instead of "0" and then modified the price within the event, it will show my variable price.

Was there some kind of known work around to make buying and selling price the same?

Because the selling price follows the price shown in RPGM MAKER, not my variable price in-game.
Marrend
Guardian Angel of the Description Thread
17400
The way it handles selling price is probably a different function entirely. Like, in VX Ace, it's...


class Scene_Shop < Scene_MenuBase
def selling_price
@item.price / 2
end
end

...right here. How that translates to MV, though, I have no idea! My guess would be the the location of the processing isn't terribly much changed. As for what to change it to, I can't really say for sure off the top of my head. Like, the logic in my head is telling me that, if the good in question has a custom price, it should use (half of?) that, and if it does not, use the standard price. However, how to refer to that custom price is what's not coming to me at the moment.


*Edit: The override I did in Myriad Cypher was...


class Scene_Shop < Scene_MenuBase
def selling_price
if @buy_window.price(@item) != nil
@buy_window.price(@item)
else
@item.price
end
end
end

...this. So, I figure it should be somewhat similar for MV, depending on what the function-call is for obtaining the buy-price.
author=Marrend
The way it handles selling price is probably a different function entirely. Like, in VX Ace, it's...


class Scene_Shop < Scene_MenuBase
def selling_price
@item.price / 2
end
end


...right here. How that translates to MV, though, I have no idea! My guess would be the the location of the processing isn't terribly much changed. As for what to change it to, I can't really say for sure off the top of my head. Like, the logic in my head is telling me that, if the good in question has a custom price, it should use (half of?) that, and if it does not, use the standard price. However, how to refer to that custom price is what's not coming to me at the moment.


*Edit: The override I did in Myriad Cypher was...


class Scene_Shop < Scene_MenuBase
def selling_price
if @buy_window.price(@item) != nil
@buy_window.price(@item)
else
@item.price
end
end
end


...this. So, I figure it should be somewhat similar for MV, depending on what the function-call is for obtaining the buy-price.




You pointed me in the right direction I found the math done for the sell price found in rpg_scenes.js:

 

Scene_Shop.prototype.buyingPrice = function() {
return this._buyWindow.price(this._item);
};

Scene_Shop.prototype.sellingPrice = function() {
return Math.floor(this._item.price / 2);
};


So all I did is replace the return for the sellingprice:


Scene_Shop.prototype.buyingPrice = function() {
return this._buyWindow.price(this._item);
};

Scene_Shop.prototype.sellingPrice = function() {
return this._buyWindow.price(this._item);
};


And voila!

It's now fully functional.

It may be unrealistic that the selling and buying have the exact same rate, so what I might do later is add a Math.floor at the buying side.

But then that would make it hard to have normal stores on top of brokers. So I might put a flat fee to use them instead.

Well as long as this works, the rest should be easy to work around or modify.
Glad you got your system working :)
Craze
purity or absolution
13128
and now you've broken the barrier and are ready to fiddle with scripts for the rest of your gam mak career :)
author=Marrend
The way it handles selling price is probably a different function entirely. Like, in VX Ace, it's...


class Scene_Shop < Scene_MenuBase
def selling_price
@item.price / 2
end
end

...right here. How that translates to MV, though, I have no idea! My guess would be the the location of the processing isn't terribly much changed. As for what to change it to, I can't really say for sure off the top of my head. Like, the logic in my head is telling me that, if the good in question has a custom price, it should use (half of?) that, and if it does not, use the standard price. However, how to refer to that custom price is what's not coming to me at the moment.


*Edit: The override I did in Myriad Cypher was...


class Scene_Shop < Scene_MenuBase
def selling_price
if @buy_window.price(@item) != nil
@buy_window.price(@item)
else
@item.price
end
end
end

...this. So, I figure it should be somewhat similar for MV, depending on what the function-call is for obtaining the buy-price.
author=winterlx
author=Marrend
The way it handles selling price is probably a different function entirely. Like, in VX Ace, it's...


class Scene_Shop < Scene_MenuBase
def selling_price
@item.price / 2
end
end

...right here. How that translates to MV, though, I have no idea! My guess would be the the location of the processing isn't terribly much changed. As for what to change it to, I can't really say for sure off the top of my head. Like, the logic in my head is telling me that, if the good in question has a custom price, it should use (half of?) that, and if it does not, use the standard price. However, how to refer to that custom price is what's not coming to me at the moment.


*Edit: The override I did in Myriad Cypher was...


class Scene_Shop < Scene_MenuBase
def selling_price
if @buy_window.price(@item) != nil
@buy_window.price(@item)
else
@item.price
end
end
end

...this. So, I figure it should be somewhat similar for MV, depending on what the function-call is for obtaining the buy-price.
author=Ramshackin
Glad you got your system working :)

author=Craze
and now you've broken the barrier and are ready to fiddle with scripts for the rest of your gam mak career :)


Thank you all for your support! I hope to have a working prototype for the game's mechanic and story by the end of the month.
I'm trying to follow this but having trouble, I actually need to use the same sort of system where I have a variable that affects the prices of items.

I'm at this part
__________________________________________

Alright!

Solved my issue: I changed my unknown by:

$gameVariables.value(x)

so the codes looks like:


var goods =
{
{ 0, 1, 1, $gameVariables.value(1) },
{ 0, 2, 1, $gameVariables.value(2) }
}
SceneManager.push(Scene_Shop);
SceneManager.prepareNextScene(goods, false);

____________________________________________________

What is $gameVariables? Where and how do I define this?
I am not familiar with Javascript but I am with C# so it's familiar but I just can't figure it out exactly, any help would be wonderful. I had to change the brackets to {'s because it thinks it's forum formatting code and made the stuff between vanish.
Skid, you want to use the "code" forum tag to quote code blocks (4th icon from the right,
).

To answer your question, $gameVariables is a global that is defined by one of the engine scripts. So you can reference it from any plugin (also the javascript console for debugging - press F8 or F12 in test mode).

All the core scripts are in the js folder with names starting with rpg_ for the game systems part.
Normally you want to override (patch / alias) the core classes with a plugin script rather than editing the original. But you will want to *read* the original scripts when writing plugins.

The way to patch objects in javascript is simply to set the member name to a new function.
Scene_Shop.prototype.sellingPrice = function() {
    return this._buyWindow.price(this._item);
};


Often you want to preserve the original function to base call it, you do that by assigning to a local variable


var MYPLUGIN_Scene_Shop_sellingPrice = Scene_Shop.prototype.sellingPrice;
Scene_Shop.prototype.sellingPrice = function() {
return MYPLUGIN_Scene_Shop_sellingPrice.call(this) * 2;
};


If you look at the source of existing plugins, you'll find lots of variations on the above.

The code you were asking about looks like a replacement for the shop processing event command from the 4th post.

So you'd need to patch Game_Interpreter.prototype.command302 with your own version.
author=coelocanth
Skid, you want to use the "code" forum tag to quote code blocks (4th icon from the right,
).

To answer your question, $gameVariables is a global that is defined by one of the engine scripts. So you can reference it from any plugin (also the javascript console for debugging - press F8 or F12 in test mode).

All the core scripts are in the js folder with names starting with rpg_ for the game systems part.
Normally you want to override (patch / alias) the core classes with a plugin script rather than editing the original. But you will want to *read* the original scripts when writing plugins.

The way to patch objects in javascript is simply to set the member name to a new function.
Scene_Shop.prototype.sellingPrice = function() {
    return this._buyWindow.price(this._item);
};


Often you want to preserve the original function to base call it, you do that by assigning to a local variable


var MYPLUGIN_Scene_Shop_sellingPrice = Scene_Shop.prototype.sellingPrice;
Scene_Shop.prototype.sellingPrice = function() {
return MYPLUGIN_Scene_Shop_sellingPrice.call(this) * 2;
};


If you look at the source of existing plugins, you'll find lots of variations on the above.

The code you were asking about looks like a replacement for the shop processing event command from the 4th post.

So you'd need to patch Game_Interpreter.prototype.command302 with your own version.


I wasn't quite sure what you were talking about but I actually did figure it out, I put it like this.




 var goods = [     

[ 0, 4, 1, $gameVariables.value(0001) ],
[ 0, 3, 1, 10 ] ]

SceneManager.push(Scene_Shop);
SceneManager.prepareNextScene(goods, false);]


The 0001 is the variable I created within RPGMaker itself, I can't believe it actually worked but it's working. I was basically just trying to add exactly what is above and I had no idea how to reference in-game variables but that thing you mentioned with the $GameVariables.value was PERFECT, did the trick totally. Thanks so much.
Pages: 1