Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
  • 0
AgentPaper

Easier Stat Editing

Question

So, I've spent a lot of time making up a huge spreadsheet in Excel, with all the stats for each character, for each level, all balanced out perfectly. Each of them uses a plethora of complicated formulas to make sure the progression is juuust right.

 

And now...to input those stats, I need to laboriously enter each and every stat for each and every character for each and every level, all by hand. With 99 levels, 6 stats, and 12 characters, that's 7,128 entries, or roughly 4-6 hours of non-stop entering. (assuming 2-3 seconds to enter each one) And of course, if I later realize that my formulas could use a little tweaking, I need to do it all over again.

 

There has got to be a better way of doing this. Is there a way to import values? Or maybe, a way to use a script to define the stats the characters get from leveling?

Share this post


Link to post
Share on other sites

11 answers to this question

Recommended Posts

  • 0

Convert the formulas to Ruby.

After you do that, it would be simple to run it, saving the values to a Table object, and manually editing the Actors.rxdata.

Share this post


Link to post
Share on other sites
  • 0

Convert the formulas to Ruby.

After you do that, it would be simple to run it, saving the values to a Table object, and manually editing the Actors.rxdata.

 

What would a script that does that look like? I tried rooting around to find where the data is saved, but I couldn't find it.

 

Edit: Also, I'm having another, semi-related problem.

 

I'm editing the combat formulas, and at one point I have this:

 

 

hit = attacker.dex / self.agi * (attacker.hit - self.eva)

 

With normal values:

 

hit = 52 / 54 * (100 - 0)

 

or

 

hit = 54 / 52 * (100 - 0)

 

Which you would expect to output ~96 or ~104, respectively. Then, if rand(100) < hit, that's a hit. I've tried doing this with manually setting hit to be 96/104/etc, and it works fine. However, when I try to use the above formula, it doesn't seem to give the right result. The first one will always miss, 100% of the time, while the second one always hits.

 

This is having a player with 52 dex/agi attack a ghost with 54 dex/agi. Hit and Eva are working fine, and I even tested it with replacing them with just 100. I've even tried testing it by replacing dex and agi with values, and I get the same results. If I use 54/52, the player and the ghost always hit, and the player also always crits. (crit = roll < hit - 100)

 

Any ideas for what might be causing this? Does Ruby do something weird with division or order of operations or something?

Edited by AgentPaper

Share this post


Link to post
Share on other sites
  • 0

Its saved by the editor, there is no visible script for it.

All it is an array of Game_Actor objects.

Share this post


Link to post
Share on other sites
  • 0

Its saved by the editor, there is no visible script for it.

All it is an array of Game_Actor objects.

 

Oh. Then, how would I do that? I haven't used Ruby for anything before, only C++ and RPGXP scripts.

 

Edit: Also, I figured out that the reason for my other bug was that the script was rounding everything into integers. I think I've fixed that now.

Edited by AgentPaper

Share this post


Link to post
Share on other sites
  • 0

im not entirely sure if i am correct but looking into how the information is retrieved i think this is how you should go about it,

so we have this method that gets the current strength in Game_Actor:

def base_str
n = $data_actors[@actor_id].parameters[2, @level]
end

so parameters is an array, and the strength array is an array within that array, which is number 2, then i think the @level gets the current value out of that array according to the level of the character, so if i am correct on the structure on the parameters you could replace them all like so:

$data_actors[@actor_id].parameters = [
[parameter 0], [parameter 1], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12.....], [ect]
                           #strength array
]

in the strength array i laid it out in levels so you would enter your value for the corisponding level, also if you didnt want to enter the value manually as that is still pretty tedious you could just make a loop, here ill do a loop for actors 1 to 4 and level 1 to 99:

for i in 1..4
for j in 1..99
equation = whatever your equation is
$data_actors[i].parameters[2, j] = equation
end
end

 

just look up all the other stats to find out how and where there stored,

i am not entirely sure but i think i must be close, hope this helps :D

Edited by diagostimo

Share this post


Link to post
Share on other sites
  • 0

Ok so I have this:

 

class Stat_Mod
 def main
   c = 1.055555
   base = 5
   for a in 2..5
  for level in 1..99
    equation = base * 0.25 * (level + 3 * (c ^ level))
    $data_actors[1].parameters[a, level] = equation
  end
   end
 end
end

 

But it doesn't seem to do anything. I specifically set my Dex stat to be 1 at level 28 so that it could be set to the correct value, but it stays at 1. Do I have to do something to make this run when the game starts?

Share this post


Link to post
Share on other sites
  • 0

yes, if you take a look at main, you will see $scene is set to $Scene_Title.new, that is the initialization of the game, then if you look into Scene_Title, you will see all the classes are created when an option is selected and all the $data values are loaded up on initialization, really you want to call your loops just after the $data values are set, in scene_title i would create the method : def stat_mod , with your loops inside that, then i would call that method just after the $data valus are loaded.

basicly you are manipulating the values that are loaded and not the real values in the .rxdata files :)

Share this post


Link to post
Share on other sites
  • 0
class Scene_Title

 alias stat_change_main main
 def main
   stat_change_main
   base, c = 5, 1.055555	  
   (1...$data_actors.size).each {|i| (2..5).each {|param| (1..99).each {|lvl|
  $data_actors[i].parameters[param, lvl] = base * 0.25 * (lvl + 3 * (c ** lvl))
   }}}
 end
end

Share this post


Link to post
Share on other sites
  • 0

@ForeverZer0: I think that script is a bit above my head, haha. I'd prefer to use a script I understand, even if it's not the best one, just so I can change it if I need to. Thanks anyways, though.

 

@diagostimo: Thanks, I think I'm on the right track now. I've actually got SDK up, and I'd eventually like to be able to release this as a script for others to use as well, basically a unified stats and combat mod, since the default stat system seems pretty terrible.

 

With that in mind, I made the following:

 


class Scene_Title

def main_database
# Load database
$data_actors = load_data("Data/Actors.rxdata")
$data_classes = load_data("Data/Classes.rxdata")
$data_skills = load_data("Data/Skills.rxdata")
$data_items = load_data("Data/Items.rxdata")
$data_weapons = load_data("Data/Weapons.rxdata")
$data_armors = load_data("Data/Armors.rxdata")
$data_enemies = load_data("Data/Enemies.rxdata")
$data_troops = load_data("Data/Troops.rxdata")
$data_states = load_data("Data/States.rxdata")
$data_animations = load_data("Data/Animations.rxdata")
$data_tilesets = load_data("Data/Tilesets.rxdata")
$data_common_events = load_data("Data/CommonEvents.rxdata")
$data_system = load_data("Data/System.rxdata")
# Calculate actor stats
calc_stats
# Make system object
$game_system = Game_System.new
end

def calc_stats
# Constant used to determine rate of inflation.
# EXTREMELY sensitive. Do not increase above 1.1.
c = 1.055555
# Cycles through each actor
for actor in 1..$data_actors.size
# Cycles through each stat
for stat in 0..5
# Calculates each level's value based on the level 1 value of the stat.
# Set initial stats to 1-999, with 500 being midline (starts at 5).
base = ($data_actors[1].parameters[stat, 1] / 100)
for level in 1..99
equation = base * 0.25 * (level + 3 * (c ** level))
$data_actors[1].parameters[stat, level] = equation
end
end
end
end

end

 

However, this just ends with all of my characters stats being set to 1. The initial value of my character's stats is around 500, or 5000 for HP, which should result in a base of 5, or 50 for HP. It's definitely running though, because my character, who is starting at level 28 for now, has their stats set to 1 when their default level 28 stats should be 52.

 

Any idea what might be causing this? Did I get the formula wrong? Also, any tips on making this more compatibility-friendly, in case I do end up sharing it? I'll most likely be releasing a SDK and non-SDK version, so tips for each would be great.

 

 

Edit: Ok, turns out the problem was that I needed to divide the level 1 stat by 10, rather than 100. No idea why that is, but it's working perfectly so oh well. :P I still would like help with making this more compatibility-friendly, but for my purposes at least this is working great. Thanks for all the help, guys. Once I get the numbers set up a bit better, I'll post the scripts in case anyone else wants to replace the old combat system too.

Edited by AgentPaper

Share this post


Link to post
Share on other sites
  • 0

no problem, ForeverZer0's script is actually pretty understandable, i actually didnt understand how those methods worked fully until i saw him do it just now in a bulk proccess:

class Scene_Title

alias stat_change_main main
def main
stat_change_main
base, c = 5, 1.055555	
(1...$data_actors.size).each {|i| (2..5).each {|param| (1..99).each {|lvl|
 $data_actors[i].parameters[param, lvl] = base * 0.25 * (lvl + 3 * (c ** lvl))
}}}
end
end

basicly whats going on there is three loops, with ().each being the value to loop through, the {} contains the loop proccess and the |i| is the key used when refering to the value of the loop proccess, so take this for example:

for i in 1...$data_actors.size

end

is the exact same as this:

(1...$data_actors.size).each {|i| }

the reason for using the container is so that you can write it all in one segment rather than breaking it all up into lines, and also to save size on code.

also on a note you can put the loop right at the end of the main method, just like forever zero did, basicly what an alias does is copies the old method then you can use that within the method to call the old method without re writing it, and as for the sdk its pretty basic, the sdk just breaks all the methods into more methods, making them easier to allias and manage

Edited by diagostimo

Share this post


Link to post
Share on other sites
  • 0

Ah, that's simpler than I thought. I got thrown off because of the multiple lines. Anyways, I still prefer the other method, just because it's easier to see what's going on, and where. I'm not really worried about the length of my code right now.

 

Thanks again for all the help, the code is working perfectly now. It might be nice to know why I need to divide by 10 instead of by 100 to get the correct result, but that's not really a big deal.

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...