Ruby/RGSSx questions that don't deserve their own thread

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,136
Reaction score
805
First Language
Hungarian
Primarily Uses
RMVXA
Thanks for the answers guys, it was very educative to read them!


I guess, I will need to learn to use procs from now on, the difference is huge it seems. o.o


As for what is better from the script user's side, here is what I think:


Telling random script users that they can use eval formulas for whatever in the script is exactly the same as telling them that they can use procs.


Most of the time, the users of public scripts don't know how to write a formula anyway, so whichever you choose to tell them (eval or proc), they won't have any idea how to do what you just told them.


So, if I could choose (and I can, at least in my scripts :p ), I would use procs instead, and make up a good few examples of how to make a functional proc in the settings (or even in a separate manual/user's guide).


Performance is the biggest issue in most of the games made with RPG Makers. If someone wants to make something that looks good, it will cost a huge performance loss in 99.9% of the time from the start (just look at the more advanced lighting scripts). I wouldn't want to make that worse if I can avoid it, not even by only 0.01%. Nobody wants to play a game which goes with 10 FPS max and slows down after each action performed by the player.


I made a test with combining two scripts. One was Blackmourning's Advanced Status menu, the other was Crystal's Extra Stats script. The status menu uses eval to get the correct chart and gauge display for the stats. The extra stats use eval formulas to get the value of the stats.


After adding 6 extra stats to the status menu, opening the status menu took me 15+ seconds. I thought my game froze, lol.


I guess, an eval calling another eval in it can and will hurt the performance by a lot, especially when it is called a lot of times in a short time-frame.


And I found a way to shorten my method without using any evals, yay! :D


Extra thanks for the note-tag grabber method explanation, Enelvon!


I learned a lot from that!
 

Enelvon

Slumbering Goddess
Veteran
Joined
Nov 29, 2012
Messages
240
Reaction score
134
First Language
English
Primarily Uses
That looks interesting...

but how about something like this?

#Notetag on object

<tag>

formula

<end_tag>

 class A

  def a(object)

    eval($1) if object.note =~ /<tag>(.*)<end_tag>/m

  end

end

how would the tag and the actual code look like if I convert that to using procs?

Also, from what I've read from your link, a return call in the proc becomes the return call of the method that calls the proc. So I can't use procs in cases where I still need to process things afterwards, right?
Sorry for the late reply, but this is also something that you can learn more about by checking out my Enhanced Events script--the way that it handles extra conditions is by taking the key of the condition in a hash as well as a set of parameters, then executes the proc and passes it said parameters, which get converted from Strings into other types based on whatever they should be for the proc. Procs, like methods, will implicitly return whatever is present at their end, so no, you absolutely can use them when you need to process things afterwards. If you feel the need to explicitly return, use a lambda--check out the tutorial that I linked.

Thanks for the answers guys, it was very educative to read them!

I guess, I will need to learn to use procs from now on, the difference is huge it seems. o.o

As for what is better from the script user's side, here is what I think:

Telling random script users that they can use eval formulas for whatever in the script is exactly the same as telling them that they can use procs.

Most of the time, the users of public scripts don't know how to write a formula anyway, so whichever you choose to tell them (eval or proc), they won't have any idea how to do what you just told them.

So, if I could choose (and I can, at least in my scripts :p ), I would use procs instead, and make up a good few examples of how to make a functional proc in the settings (or even in a separate manual/user's guide).

Performance is the biggest issue in most of the games made with RPG Makers. If someone wants to make something that looks good, it will cost a huge performance loss in 99.9% of the time from the start (just look at the more advanced lighting scripts). I wouldn't want to make that worse if I can avoid it, not even by only 0.01%. Nobody wants to play a game which goes with 10 FPS max and slows down after each action performed by the player.

I made a test with combining two scripts. One was Blackmourning's Advanced Status menu, the other was Crystal's Extra Stats script. The status menu uses eval to get the correct chart and gauge display for the stats. The extra stats use eval formulas to get the value of the stats.

After adding 6 extra stats to the status menu, opening the status menu took me 15+ seconds. I thought my game froze, lol.

I guess, an eval calling another eval in it can and will hurt the performance by a lot, especially when it is called a lot of times in a short time-frame.

And I found a way to shorten my method without using any evals, yay! :D

Extra thanks for the note-tag grabber method explanation, Enelvon!

I learned a lot from that!
Glad I could help!
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,642
Reaction score
2,972
First Language
Tagalog
Primarily Uses
yeah, I've read that over and over... I was hoping there was a faster way to go about it than the users needing to make some kind of list then still doing notetags... I'm also still a bit puzzled as to how you actually ran the conditions, since I've just been reading it without testing anyway, and honestly, I couldn't really understand it that much. That is also why I was asking how the code I posted would look when converted to using procs. :)

actually could we do something like this? (not with my maker right now)

<tag>ADIK.sample(1)<end_tag>

then on the code

Code:
 module ADIK  def self.sample(value)  endend $1.call if obj.note =~ /<tag>(.*)<end_tag>/m
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
4,635
Reaction score
5,278
First Language
Indonesian
Primarily Uses
RMVXA
Use the eval + proc I posted in previous page

class RPG::SomeItem def some_eval_script unless @eval_script # Do your notetag grabber logic here. You can still load the string and put them as proc @eval_script = eval("proc #{ formula } ") end @eval_script.call endendThe eval only executed once. And for the rest, it will be called as proc. That would not be a real problem

If you really hate eval, then you might hate the damage formula and script call in eventing as well
 
Last edited by a moderator:

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,642
Reaction score
2,972
First Language
Tagalog
Primarily Uses
what happens if we remove the eval?

@eval_script = proc { formula } Oh wait, read the long post from you... so if we remove the eval, this proc wouldn't be able to use the simple call for instance variables?

Anyway that seems good, nothing would change from the user side, and only a minor change in the script side (the scripts do save the formula anyway already in a variable per script so that it won't always need to be read from the tags)
 
Last edited by a moderator:

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
4,635
Reaction score
5,278
First Language
Indonesian
Primarily Uses
RMVXA
what happens if we remove the eval?

@eval_script = proc { formula } Oh wait, read the long post from you... so if we remove the eval, this proc wouldn't be able to use the simple call for instance variables?

Anyway that seems good, nothing would change from the user side, and only a minor change in the script side (the scripts do save the formula anyway already in a variable per script so that it won't always need to be read from the tags)
It will be considered as string. Not a piece of code
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,642
Reaction score
2,972
First Language
Tagalog
Primarily Uses
ah I see... Thanks! That seems to be a really good solution... I'll test it when I get the time and see if it runs without problems. :)
 

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,271
Reaction score
2,329
First Language
Binary
Primarily Uses
RMMV
I'm not too great with string manipulation, is anyone able to give me a better alternative for this lil snippet?

    def methodname      aRay = []      index = 0      @aStr.each_byte do |string|        aRay << index if @aStr2[index] != string        index += 1      end      aRay    end
Essentially, I wish to compare two strings and then for each byte that is different I wish for the index of that byte to be added into an array.

Any advice would be appreciated. :)
 

Solistra

Veteran
Veteran
Joined
Aug 15, 2012
Messages
593
Reaction score
244
Primarily Uses
I'm not too great with string manipulation, is anyone able to give me a better alternative for this lil snippet?
I'm not particularly good with text manipulation myself, honestly (at least not as good as I'd like to be), but hopefully this example will help:

Code:
module StringExtensions  # Returns an array of indexes which contain byte values which are not the  # same as those present at the same index in this string.  #   # @param other [#bytes] the string to compare against  # @return [Array<Fixnum>] an array of indexes from `other` which differ from  #   this string  def diff_indexes(other)    # Convert `other` directly into an array of bytes.    other = other.bytes.to_a        # Collect indexes from `other` which differ from the values in this string.    value = each_byte.with_index.each_with_object([]) do |(byte, index), array|      array << index if other[index] != byte    end        # Presence is not the same as absence! Add the remaining indexes from    # `other` if it is longer than this string.    size.upto(other.size - 1) { |i| value << i }    return value  endend
Example usage:

Code:
string1 = 'hi. this is a test'.extend(StringExtensions)string2 = 'Hi, this is a test!'string3 = 'Hi! This is a ' # cut off because reasons.p string1.diff_indexes(string2) # => [0, 2, 18]p string1.diff_indexes(string3) # => [0, 2, 4, 14, 15, 16, 17]
I commented this fairly heavily so that you have a good idea of what I'm doing, and -- hopefully -- why I'm doing it. I hope you find it useful.
 

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
536
Reaction score
249
First Language
German
Primarily Uses
Wow, this thread has grown a lot for the last few days... :)

@Sixth:
Without wanting to encourage the use of eval I doubt it was because of it that you experienced a 15 seconds lag.

@TheoAllen:

You might consider adding a newline character after the formula, otherwise you will face syntax errors when a formula ended with a comment.

@Dekita:

I didn't do much in this direction either, but if you know your strings have the same length this might be a possibility:
(0...string1.bytesize).select { |i| string1.getbyte(i) != string2.getbyte(i) }
 
Last edited by a moderator:

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,136
Reaction score
805
First Language
Hungarian
Primarily Uses
RMVXA
@Sixth:


Without wanting to encourage the use of eval I doubt it was because of it that you experienced a 15 seconds lag.
I changed nothing else in the scripts, just added the extra stats to the status chart and gauge display in the code, extended the math with the added stats (which means just adding the values of the extra stats and dividing the final result with a higher number in the end).
Without the extra stats, the status scene opens within 1 second, but as soon as I enable the extra stat display, it takes around 10-15 seconds to open it.


I don't know what else could cause this much difference, but I gave up on displaying my extra stats that way. :D
 

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,200
Reaction score
1,256
First Language
English
Primarily Uses
RMXP
The benchmark in the other thread had for the particular eval code ran a speed of around 2000-3000 calls per frame. (Assuming the standard 60 FPS)

While that most certainly is slower than the 40000-85000 calls per frame the other call types ran with at the same time eval itself being the cause is very unlikely.

What code you are evaluating does of course matter. Maybe you accidentally call some refresh/redraw method 20 times instead just once.

*hugs*

 - Zeriab
 

Sixth

Veteran
Veteran
Joined
Jul 4, 2014
Messages
2,136
Reaction score
805
First Language
Hungarian
Primarily Uses
RMVXA
I used the way what Blackmourning used initially, just added 6 extra stats to the calculation.


Those stats use eval to get their values too.


If there was any other thing that could affect the delay, that is not caused by me, I guess.


Printing a random text in the method itself results in a LOT of text in the console repeating for a while, so I think it is calling some things multiple times somewhere. Whether is that necessary or not, I have no idea, I haven't made those scripts.


Also, I have a PC from the stone-age, my max FPS is 30 on any scenes, if this matters at all. :D
 

Solistra

Veteran
Veteran
Joined
Aug 15, 2012
Messages
593
Reaction score
244
Primarily Uses
Also, I have a PC from the stone-age, my max FPS is 30 on any scenes, if this matters at all. :D
This is a good thing, in my opinion. Personally, I run RPG Maker in a VM with the processor, memory, and video memory capped to low values in order to see how things perform with few resources. Performance issues become much more visible that way.
 

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,642
Reaction score
2,972
First Language
Tagalog
Primarily Uses
Printing a random text in the method itself results in a LOT of text in the console repeating for a while, so I think it is calling some things multiple times somewhere. Whether is that necessary or not, I have no idea, I haven't made those scripts.
Then there's the problem, it was probably redrawing multiple times. and drawing stuff in RM is slow. 
 

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,271
Reaction score
2,329
First Language
Binary
Primarily Uses
RMMV
@Solistra - That looked really nice; however, its actually less efficient than what I had :'(

I must say though...

  each_byte.with_index.each_with_object([]) { |(byte, index), array|   }^ that is lovely. I assume this is working similar to inject_each_byte_with_index would (if such a method was available :p )

would doing such things work on any enumeration method? (adding the .with_index prior .reduce() for example? )

Anyway here's a cheeky comparison using Benchmark.ips.compare!

(the method I posted above is labeled as 'one')

Calculating -------------------------------------                 one     1.226k i/100ms                 two   828.000  i/100ms-------------------------------------------------                 one     12.701k (± 1.8%) i/s -     63.752k                 two      8.395k (± 1.5%) i/s -     42.228kComparison:                 one:    12700.7 i/s                 two:     8394.9 i/s - 1.51x slower@Another Fen- Same deal, looked good, thought it may improve efficiency somewhat...

Calculating -------------------------------------                 one     1.183k i/100ms                 two     1.083k i/100ms-------------------------------------------------                 one     12.389k (± 2.2%) i/s -     62.699k                 two     11.150k (± 1.6%) i/s -     56.316kComparison:                 one:    12389.4 i/s                 two:    11149.6 i/s - 1.11x slowerReally wasn't expecting my method to be more efficient there. Kinda disappointed now :/

Thanks anyway though. It is appreciated. :)

Edit:

Uploaded what I had. It was for an addon to my input system to allow for a change in all keycodes. Can check for triggers, presses, releases etc. In case anyone is curious it can be seen from here : https://github.com/Dekita/Dekyde-Ace/blob/master/Input::KeyChangeDetection.rb
 
Last edited by a moderator:
Joined
Jan 16, 2015
Messages
6
Reaction score
0
Primarily Uses
Hi!
I want to implement minor changes to the Standard RMVXA Equip Menu:

- No helmet. Only 4 equipment slots: weapon, shield, armor, and accessory.

- No equipment command window (the one that contains equip/optimize and remove). Equipment should be equipped or removed
instantly when enter is pressed.

- The text of equipment items looks clinched when it's too long. How to fix that?


Thanks!
SunriseStudios
 

Another Fen

Veteran
Veteran
Joined
Jan 23, 2013
Messages
536
Reaction score
249
First Language
German
Primarily Uses
Well, I didn't benchmark my solution. Since it actually follows the same strategy as your method with a bit more overhead it might actually make sense. It should be fast enough for most purposes though. :)

If you want to improve performance a bit you could try this:
- prefer local variables to instance variables when executing a line repeatedly- avoid the use of blocks, use while for repetition. However, I don't know if  while i < ...; s1.getbyte(i) ; end is actually faster than s1.bytes { ... } so this point might also have the opposite effect here.

I didn't try out this variant:

def method  s1 = @aStr  s2 = @aStr2  ary = Array.new  index = -1  target = s1.bytesize  while (index += 1) < target    ary << index  if s1.getbyte(index) != s2.getbyte(index)  end  aryendDisclaimer, just for the record: I don't want to discourage the use of instance variables or blocks! This won't save your code from performing badly. I also don't even know for sure if the points I stated are correct in general, as they are based on my experiences rather than facts. ^^
 
Last edited by a moderator:

??????

Diabolical Codemaster
Veteran
Joined
May 11, 2012
Messages
6,271
Reaction score
2,329
First Language
Binary
Primarily Uses
RMMV
Yea, I was thinking of using your snippet as it was more compact if nothing else, but I felt as though it was already pretty slow so was hoping to enhance it somehow :p

I will have a fiddle around with whats suggested in your spoiler and see if any positive results occur, thanks for the thoughts. :)

Random Thought:

This is really annoying me cause a few other methods are reliant upon that one, and the rest of the code is nice and neat, then just this big chunky mess of a method  :'( 
 

Sanguine

Hoot
Member
Joined
Oct 18, 2012
Messages
27
Reaction score
53
First Language
English
Primarily Uses
Just curious, is there some way to run a common event in a parallel processed event? Like maybe some way to pause the parallel processing, then run the common event, then resume the parallel process after the common event is done?
 

Users Who Are Viewing This Thread (Users: 0, Guests: 2)

Latest Threads

Latest Posts

Latest Profile Posts

I have tried, several times to understand how Markiplier is popular. You can't deny his popularity. I can only get through a few minutes of his vids, though. He's cringier than ANY cringe comp I've ever watched. When I was a kid, if you acted like that, 0 friends and 100% no dates for you. Times have changed XD
Sometimes you may feel helpless and defeated. But everyone loses from time to time. It's okay to be tired. Take a breather. Have a good cry if you need to. You gotta take breaks from your workout, or you'll collapse before you can get stronger.
So, my roommates wrote a news article in English, translated it into Bengali with google translate and now I'm helping them fix the monstrosity which was the result. Making English the medium of education is fine... but not to an extent that we forget how to write properly in our own language :")
Stream will be live shortly with some more Minecraft spriting! Feel free to drop by~

Forum statistics

Threads
93,543
Messages
913,327
Members
123,069
Latest member
cloud8111
Top