RMMV Need decimal values in variables and calculate with them

Zion

Veteran
Veteran
Joined
Mar 12, 2018
Messages
81
Reaction score
31
First Language
German
Primarily Uses
RMMV
Hi there,

I have a very specific problem, it seems. Have been searching all over the internet for the last hours now, tried a plugin too but I can't get it to work.

I am in need of decimal values. For the aquarium in my game, the player will have to check the pH scale and the salinity of the water. These two come with decimal, for example the pH scale of saltwater is around 7.5 - 8.4 and the salinity is somewhere around 3.5%. The game will change these slowly over time, reducing or increasing them by 0.1 so the player has to take some actions against this.

Unfortunately, the maker rounds every number you store in a variable. I've been playing around with codes like

$gameVariables.setValue(42, 7.8)

or

$gameVariables.setValue(42, $gameVariables.value(42) + 0.1)

or just entering them into the script section of the variable, but it does not work. I even used a plugin for not rounding them - but it's not made for such calculations and therefore I get more and more errors.

Can anybody help me please? (using MV)
 

Htlaets

Veteran
Veteran
Joined
Feb 1, 2017
Messages
243
Reaction score
121
First Language
English
Primarily Uses
Game variables only hold whole numbers. The way you get around this is to use a very large number.

For example, if you want to add .1 to a variable, then when you want the variable value to be one you make the variable value 10. So, in this case, 10 would be 1.0. So if you wanted to add .1 you'd add 1 to the variable.
 

Lady_JJ

Veteran
Veteran
Joined
May 6, 2019
Messages
253
Reaction score
137
First Language
English
Primarily Uses
RMMZ
This was posted by @Lanzy, though I didn't write down the exact thread it was posted in. Write directly to the data file using script.

$gameVariables._data[1] = 1.75;

\v[1] will then display 1.75

Your calculations would, I think, need to be done within script, then output the result using $gameVariables._data[x]
 

Andar

Veteran
Veteran
Joined
Mar 5, 2013
Messages
33,349
Reaction score
8,390
First Language
German
Primarily Uses
RMMV
or do not use any functions or plugins at all but control variable to store a decimal number inside a variable.
I haven't tested it in MZ, but in all previous makers that was enough to switch that specific variable to using float point numbers - in fact there were hundreds of topics with the older makers where the variables were accidentally switched to float point...
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,708
Reaction score
2,813
First Language
English
Primarily Uses
RMMZ
Edit: nvm, I was looking at the wrong function.
 

Zion

Veteran
Veteran
Joined
Mar 12, 2018
Messages
81
Reaction score
31
First Language
German
Primarily Uses
RMMV
or do not use any functions or plugins at all but control variable to store a decimal number inside a variable.
I haven't tested it in MZ, but in all previous makers that was enough to switch that specific variable to using float point numbers - in fact there were hundreds of topics with the older makers where the variables were accidentally switched to float point...
Well I don't really know what you are talking about. This is about MV, not MZ, and I don't know how to switch to float.

$gameVariables._data[1] = 1.75;

\v[1] will then display 1.75

Your calculations would, I think, need to be done within script, then output the result using $gameVariables._data[x]
Thanks! But if I can't calculate with them and need an extra script for it, this is too much for me, knowing almost nothing about JS.

Game variables only hold whole numbers. The way you get around this is to use a very large number.

For example, if you want to add .1 to a variable, then when you want the variable value to be one you make the variable value 10. So, in this case, 10 would be 1.0. So if you wanted to add .1 you'd add 1 to the variable.
I see. Guess this will be the best solution then. Thanks for pushing me in the right direction, will go with that.
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
1,302
Reaction score
699
First Language
English
Primarily Uses
RMMV
Well I don't really know what you are talking about. This is about MV, not MZ, and I don't know how to switch to float.
Isn't MV then part of "all previous makers?" Andar said very plainly in his post that he believes using the Control Variables event button, instead of a script call, will do what you want. Did you try it?
Thanks! But if I can't calculate with them and need an extra script for it, this is too much for me, knowing almost nothing about JS.
If someone says "I think," don't treat it as absolute, do more researching or testing. As far as I know (without looking it up in the code), the only variable-related function that rounds numbers is setValue. If you bypass that by using $gameVariables._data, all of the calculation functions and event buttons should work properly.

Try before you give up. :wink:
I see. Guess this will be the best solution then. Thanks for pushing me in the right direction, will go with that.
This can work, also, but it requires more conversions back and forth on your end.
 

gstv87

Veteran
Veteran
Joined
Oct 20, 2015
Messages
2,419
Reaction score
1,434
First Language
Spanish
Primarily Uses
RMVXA
can't you set the variable contents to *script* and use a decimal number?
 

caethyril

^_^
Veteran
Joined
Feb 21, 2018
Messages
2,610
Reaction score
1,991
First Language
EN
Primarily Uses
RMMZ
RMMV's Control Variables command automatically floors numeric values.

The reason for keeping everything integers is mostly precision. JavaScript (RMMV) uses the common IEEE 754 format for its floating-point arithmetic, but it has limited resolution so you may find oddities like this:
  • 0.3 - 0.2 = 0.09999999999999998
...and the workaround for that is ultimately to scale up to an integer, round off, then scale back down:
  • Math.round(10 * (0.3 - 0.2)) / 10 = 0.1

One option is to mimic decimals with text for display purposes. Let's say you need to show a maximum of 2 decimal values per message. You can set aside 2 game variables for these display values. Let's say you have a value 123 in game variable 1 and you want to display that as 12.3 (1 decimal place). You can use this in Control Variables > Script:
JavaScript:
var v = $gameVariables.value(1); '' + Math.trunc(v/10) + '.' + v.mod(10)
The result will be a string of text:
  • The integer part of 1/10 of the value of game variable 1,
  • ...then a . (decimal separator),
  • ...then the remainder after dividing the value of game variable 1 by 10.
 

Andar

Veteran
Veteran
Joined
Mar 5, 2013
Messages
33,349
Reaction score
8,390
First Language
German
Primarily Uses
RMMV
OK, I have to admit that I was wrong.
I finally had time and tested it and the old trick to override the variable format from previous makers does not work in MV, control variable really floors all inputs. Might have been changed in one of the updates because I'm really sure that it originally worked...

so the OP has to use one of the other options, like only having the display be decimal like the post above shows while working with larger numbers internally to prevent the flooring of the numbers.
 

Restart

Veteran
Veteran
Joined
Mar 15, 2019
Messages
832
Reaction score
671
First Language
English
Primarily Uses
RMMV
How about converting it into a string before storing?

2 digit precision good enough for you?
Code:
//this function returns a string version of the input number with 2 digit precision.
//for instance 0 -> '0.00'
//or 1 -> '1.00'
//or 0.00002 -> '0.00'
make2String= function (oldValue)
{
    var oldValue=oldValue||0
    var temp = Math.round(oldValue*100).toString()
    temp = temp.padStart(3,'0')
    return temp.slice(0,temp.length-2)+'.'+temp.slice(temp.length-2,temp.length)
}

//this turns a 2 digit string back to a normal number.  Or you can just use eval() directly
2digitNum= function (oldValue)
{
return eval(oldValue)

}

Just remember to convert back when grabbing the variable, because adding strings to numbers appends them in a new string. So 1 + '0.1' = '10.1'
 

ImaginaryVillain

High Cultist of the Sporkle
Veteran
Joined
Jun 22, 2019
Messages
933
Reaction score
5,718
First Language
Absurdism
Primarily Uses
RMMZ
Ah yes... this. I keep a plugin where I stuff function overwrites for stuff like this garbage...

JavaScript:
Game_Variables.prototype.setValue = function(variableId, value) {
    if (variableId > 0 && variableId < $dataSystem.variables.length) {
        if (typeof value === "number") {
            value = Math.floor(value);
        }
        this._data[variableId] = value;
        this.onChange();
    }
};

You'll find that offender in rpg_objects.js... Or if you're using MZ it's in rmmz_objects. Change it to...

JavaScript:
Game_Variables.prototype.setValue = function (variableId, value) {
  if (variableId > 0 && variableId < $dataSystem.variables.length) {
    this._data[variableId] = value;
    this.onChange();
  }
};

And live a life free of variables automatically flooring themselves.

Personally I advocate just copy and pasting that into "overwrites.js" and having your own overwrites plugin versus directly overwriting the base code. Mostly so you don't forget the changes you've made.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,708
Reaction score
2,813
First Language
English
Primarily Uses
RMMZ
Ah yes... this. I keep a plugin where I stuff function overwrites for stuff like this garbage...

JavaScript:
Game_Variables.prototype.setValue = function(variableId, value) {
    if (variableId > 0 && variableId < $dataSystem.variables.length) {
        if (typeof value === "number") {
            value = Math.floor(value);
        }
        this._data[variableId] = value;
        this.onChange();
    }
};

You'll find that offender in rpg_objects.js... Or if you're using MZ it's in rmmz_objects. Change it to...

JavaScript:
Game_Variables.prototype.setValue = function (variableId, value) {
  if (variableId > 0 && variableId < $dataSystem.variables.length) {
    this._data[variableId] = value;
    this.onChange();
  }
};

And live a life free of variables automatically flooring themselves.

Personally I advocate just copy and pasting that into "overwrites.js" and having your own overwrites plugin versus directly overwriting the base code. Mostly so you don't forget the changes you've made.
The other advantage to keeping a separate overwrites file is that if you edit the base code directly, you'll lose your changes every time a new version comes out.
 

Restart

Veteran
Veteran
Joined
Mar 15, 2019
Messages
832
Reaction score
671
First Language
English
Primarily Uses
RMMV
Ah yes... this. I keep a plugin where I stuff function overwrites for stuff like this garbage...

JavaScript:
Game_Variables.prototype.setValue = function(variableId, value) {
    if (variableId > 0 && variableId < $dataSystem.variables.length) {
        if (typeof value === "number") {
            value = Math.floor(value);
        }
        this._data[variableId] = value;
        this.onChange();
    }
};

You'll find that offender in rpg_objects.js... Or if you're using MZ it's in rmmz_objects. Change it to...

JavaScript:
Game_Variables.prototype.setValue = function (variableId, value) {
  if (variableId > 0 && variableId < $dataSystem.variables.length) {
    this._data[variableId] = value;
    this.onChange();
  }
};

And live a life free of variables automatically flooring themselves.

Personally I advocate just copy and pasting that into "overwrites.js" and having your own overwrites plugin versus directly overwriting the base code. Mostly so you don't forget the changes you've made.
The potential issue with doing it this way is if you're referencing the variable in a textbox; floating points won't always hit round numbers and I could see a text box saying the pH is 7.029999999999998 instead of 7.03 or whatever. (which is why I went with the string approach instead)
 

ImaginaryVillain

High Cultist of the Sporkle
Veteran
Joined
Jun 22, 2019
Messages
933
Reaction score
5,718
First Language
Absurdism
Primarily Uses
RMMZ
@Restart
String conversion is fairly heavy, as opposed to simply removing an operation as I've done which actually speeds up MV/MZ. Depending on how often your method is used, you will create serious resource requirements, where as mine will always yield a positive gain on performance.

You are right though, it does come with the caveat that you now have full control of your variables, and all that entails. However if someone has asked for that, that's what I give them. I will assume if they are asking for that they have some idea on what they want to do with them.

Also I advise heavily against Eval, not only is it a massive security risk, it's extremely resource intensive as it must call the JavaScript Interpreter upon execution. Which is also the reason why I have taken to putting my script commands into plugins, as MV/MZ actually uses Eval to parse script commands.

Anyway, it's far more sensible to free up the variables and let people make the occasional mistake of learning they need to occasionally round numbers, than to introduce incorrect numerical results as MV/MZ did, or add in expensive conversions.
 

Zion

Veteran
Veteran
Joined
Mar 12, 2018
Messages
81
Reaction score
31
First Language
German
Primarily Uses
RMMV
Thank you all!

Andar said very plainly in his post that he believes using the Control Variables event button, instead of a script call, will do what you want. Did you try it?
Of course. I tried before I made the post here.

If you bypass that by using $gameVariables._data, all of the calculation functions and event buttons should work properly.
You mean this one:
$gameVariables._data[1] = 1.75;

\v[1] will then display 1.75

Your calculations would, I think, need to be done within script, then output the result using $gameVariables._data[x]
Tbh, I don't know how to test this because I don't know the JS syntax for the calculations within the script. I have almost no knowledge about JS.

can't you set the variable contents to *script* and use a decimal number?
I tried, but MV always rounds the value.

You can use this in Control Variables > Script:
var v = $gameVariables.value(1); '' + Math.trunc(v/10) + '.' + v.mod(10)​
This seems great!
But I don't get it to work :(
This is how I tried:
1.png
It starts with a decimal:

2.png
But if I click on increase, this is the result:

3.png


JavaScript:
Game_Variables.prototype.setValue = function (variableId, value) {
  if (variableId > 0 && variableId < $dataSystem.variables.length) {
    this._data[variableId] = value;
    this.onChange();
  }
};
This seems great, too, but I have a problem.
I tried it with this:

4.png

At first, it's correct. If I increase one time, it's still ok. But if I increase the second time...

5.png
String conversion is fairly heavy, as opposed to simply removing an operation as I've done which actually speeds up MV/MZ. Depending on how often your method is used, you will create serious resource requirements, where as mine will always yield a positive gain on performance.
This might be a problem for me, as the calculations are made in the background at all times. So I need a method to not slow down the performance.
 

ImaginaryVillain

High Cultist of the Sporkle
Veteran
Joined
Jun 22, 2019
Messages
933
Reaction score
5,718
First Language
Absurdism
Primarily Uses
RMMZ
@Zion
That's why I suggested the method I did. It actually speeds up MV/MZ because by default MV/MZ is doing an extra operation to round the variables. My solution simply removes that, so every time you declare a variable it's doing one less operation. :LZSwink:
 

Andar

Veteran
Veteran
Joined
Mar 5, 2013
Messages
33,349
Reaction score
8,390
First Language
German
Primarily Uses
RMMV
This is how I tried:
your problem there is the double equation as you read the event command.

most answers above gave you the full javascript syntax to be used in a script command box as is.
the script line of the control variable command adds a first half of an equation to that, so this part of the full line is no longer needed.
the line should now read
control variable #0014 ph test = $gameVariables.value(1); '' + Math.trunc(v/10) + '.' + v.mod(10)

without the var v= that is only needed in a full script box.
 

Trihan

Speedy Scripter
Veteran
Joined
Apr 12, 2012
Messages
3,708
Reaction score
2,813
First Language
English
Primarily Uses
RMMZ
Thank you all!


Of course. I tried before I made the post here.


You mean this one:

Tbh, I don't know how to test this because I don't know the JS syntax for the calculations within the script. I have almost no knowledge about JS.


I tried, but MV always rounds the value.


This seems great!
But I don't get it to work :(
This is how I tried:
View attachment 192074
It starts with a decimal:

View attachment 192075
But if I click on increase, this is the result:

View attachment 192076



This seems great, too, but I have a problem.
I tried it with this:

View attachment 192078

At first, it's correct. If I increase one time, it's still ok. But if I increase the second time...

View attachment 192079

This might be a problem for me, as the calculations are made in the background at all times. So I need a method to not slow down the performance.
Your issue is that after assigning a decimal to it, you're using the control variables command to add 1. Adding uses the same function as setting does so it's still going to get rounded after you do that.
 

Latest Threads

Latest Posts

Latest Profile Posts

just when I thought one of the greatest game of all time couldn't get any better, they announce a new dlc for it.
For anyone interested: there's another huge humble bundle with JRPG assets + a game jam starting next month - it's for a good cause, so check it out <3
Turning a specific vibe into reality is incredibly difficult. For instance, this song is one of the ones I listen to when working on my post apocalyptic project, and getting it's "feeling" into the game has been a real challenge.

I don't just wanna regurgitate the numbers I see, I wanna actually understand the calculations I'm making so I'm probably gonna make a post later with some calculations and what I THINK they mean to get some advice and corrections.

Edit: All (Most) of these will be tested in game prior. I just wanna make sure I understand what's going on under the hood if you will.
my girlfriend calls all my little chibi art cute lol... funny considering that wasn't the original art style of the game.

Forum statistics

Threads
113,780
Messages
1,077,393
Members
147,815
Latest member
TsumiYZ
Top