Script Compability

Engr. Adiktuzmiko

Chemical Engineer, Game Developer, Using BlinkBoy'
Veteran
Joined
May 15, 2012
Messages
14,682
Reaction score
3,003
First Language
Tagalog
Primarily Uses
RMVXA
fits the bill better since


spr.bitmap.blt(Graphics.width/2,Graphics.height/2,bit,rect)


would put the top left corner at the center of the graphic instead of the top-left corner of the graphic.
x,y means where the picture will start (top-left of the picture), as I said on the example, it was for showing a picture that will start at the center of the graphic (in this case, the actual game window)...


the x,y there will be based on actual screen coordinates since I made the bitmap as large as the game window
 

Mike

Veteran
Veteran
Joined
Aug 28, 2013
Messages
316
Reaction score
36
First Language
English
Primarily Uses
Gotcha, thanks for the input. I'll go back the script to add some features, hopefully I could submit the final work by the weekend.
 

modern algebra

Veteran
Veteran
Joined
Sep 28, 2012
Messages
59
Reaction score
49
First Language
English
Primarily Uses
Mike, on 26 Dec 2013 - 5:39 PM, said:

       Ah, I'm overloading the basic terminate and update modules on the default classes like Scenes, so I'm thinking of
        begin
            mod = self.const_get "terminate"
            alias a_terminate terminate
            def terminate
              a_terminate
              @asd.dispose
            end
          rescue NameError
            def terminate
              super
              @asd.dispose
            end
          end
    Mithran, on 05 Jan 2014 - 6:33 PM, said:

    I'm a little late here, but I'd like to point out that the code block posted would be pretty much useless. If you are getting NameErrors while simply defining your methods, it is usually something you screwed up and not an incompatibility with some other script since very few scripts go about removing methods. Using it like this would only serve to mask the actual error you made. The example you posted would have the first part of the block fail every time due to attempting to get a constant beginning with a lowercase letter.

    In general, for completed scripts, you should only use these rescue blocks in an area where you expect a crash due to user input, but the input was not important enough that you can't continue running. An example of this is the default scripts, where having a syntax or name error in a custom damage formula will be rescued and spit out a 0. (even this is borderline for me, ideally it should be accompanied by some sort of error message so it is obvious that the user made a mistake) If you need to use rescue before a point where there is some outside input or variable you can't control correctly, then you should probably reconsider how your script is written.
You're right that his code block was broken as it was, but I think the idea behind it is not. For compatibility purposes, I think what that code was trying to do makes sense if you are working within the default scripts and want to change how a superclass' method works in one of its subclasses, but that method has not already been re-defined in the subclass by default. For example, let's say the default scripts had the following classes:

class Book  def initialize     #bla  end  def turn_page    #bla  endendclass Book_2 < Book  def initialize    super    #bla  endendIf we want to alter the turn_page method in Book_2 but not in Book, then we could alias. If we did that, though. then it would only copy the method as that method currently is in the superclass. If another script interpreted later (i.e. placed below it) aliased and re-defined the turn_page method in Book, then the changes made by that script would not be called when we called the turn_page method of a Book_2 object. Ideally, we want the first-interpreted script that re-defines the method in the subclass to call super in order to account for that possibility.

So you could just write it:

class Book_2  def turn_page    super    # Bla  endendBut then, if another scripter also wanted to change how turn_page worked for the Book_2 class and did the same thing, the two scripts would be incompatible because the changes made to the method in whichever script is interpreted first would not run.

So, in those (admittedly limited) circumstances, I think it makes sense to check if the method is defined in the subclass, and then alias if it is but call super it if it is not (which I think was what Mike was trying to do.)

Anyway, you're right that it shouldn't be done as an error-check. Mike's code wouldn't work even if the constant check was OK, since you can alias a superclass method in a subclass and it won't throw an error. If I were trying to do what I described above, I would just check directly if the method had been defined in this subclass already, with something like:

class Book_2  if instance_methods(false).include?:)turn_page)    alias ma_turnpge_3ib6 turn_page    def turn_page      ma_turnpge_3ib6      ma_turn_page_in_book_2    end  else    def turn_page      super      ma_turn_page_in_book_2    end  end def ma_turn_page_in_book_2 # bla endendAnyway, Mithran was right, but I wanted to point out that what the code block was trying to do could potentially be useful in some circumstances.

EDIT::

@Mithran - In a sense, I guess this could be the type of overplanning that you've cautioned about earlier, but I don't really see the harm in accounting for possibilities like that. In that vein, I was wondering a little about this:

An example of this type of over-planning would be using (*args, &block) as the arguments for every single method being redefined after you alias it, to prevent any potential argumenterror. The simple fact is, if a method has changed enough from the defaults that it now takes a block where it didn't before, you are likely going to run into another issue other than "I should have transparently passed that block I didn't have any reason to know or expect would be there".
Although I agree with your logic, I still commonly take pre-emptive strikes like that. I mean, sure, I don't think I've ever added arguments to a default method, and I've never even seen anyone change a default method to take a block. However, is there any major downside to using (*args, &block)? A lot of times when I am aliasing methods, I am just doing it because I want to do something around that time in the processing, and I am not trying to change the method's behaviour or even necessarily do anything with its arguments (for instance, if I am adding an attribute to a class, I may want to alias initialize to initialize it, but I don't necessarily care about what else is being done in that method). Even when I am doing something more substantial, I don't really see the harm in accounting for the possibility that some other scripter will change the method to pass more arguments to it. Obviously, there are some changes which can't be reasonably anticipated, but it is still possible that a change in arguments would not interfere with what my script is doing.

I am open to updating my practice if there are reasons for doing so that I haven't considered, but I guess I don't really see the harm in taking small pre-emptive measures like this to preserve compatibility. Especially in the RM context, where people can have scripts from 30 different scripters in their projects, and any one or more of those scripts could have been written by someone with little or no training or experience. 
 
Last edited by a moderator:

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
@modern_algebra - Yeah, I realized in a later post what he was trying to do was syncing the properties of his sub-sprite with the properties of the window after all initialization method had been run once the code had been cleaned up a bit. It was mostly the broken rescue blocks that made me cringe since he used it on pretty much every alias in his script submission to completed scripts (before he started cleaning it up here) and none of them did anything, so over half the code were branches that could never be reached.


As for overplanning, I was just mentioning that the mindset behind it can be detrimental, especially if just starting out with Ruby in RM where you can, as you said, have 30 people modifying the same code. Transparently passing arguments and a (potentially nonexistent) block is not inherently harmful by itself, but the idea that you can prevent every compatibility would might be. I was just pointing this out as an example because if you actually needed to use whatever arguments were passed, you'd have to make an assumption anyway, although 99% of the time if someone is going to alter a method's arguments, they are going to just tack an additional argument at the end of the existing list so transparently passing *args is always a good idea. I didn't mean to insinuate it wasn't.


If someone added a block requirement to the method where there was none before, however, the method might not even have the same function anymore. (It could, but probably not, especially specific to RM where I've never seen this done.) I'd hope that anyone modifying an existing method to take a block would be considerate of those things but you really have no idea what they have done - you are just operating on a set of assumptions that it will fit in with the base code, plus any code added by an arbitrary amount of people that doesn't directly overwrite or completely change the function. That just brings me back to the point I was trying to make in another post that even if you follow basic compatibility guidelines that there will be that one person that doesn't, and that will be the incompatible script. If not binding and passing the block is causing a problem, you'd know that one or more of your assumptions is wrong and the code requires further analysis.


Of course, neither matters in situations such as your example where you don't care about what the content of either the arguments or if it needs a block, such as adding a variable in initialize. Not including the block binding also wouldn't make errors any more obvious in the case where the block was a conditional argument in the other modified method anyway, and in the event they did use it correctly, it would just silently break some function in the other script. I guess I was more leaning toward expecting the function of the method to have changed if a block requirement is suddenly introduced, where you were leaning toward anyone adding the block argument knows what they are doing enough that you can safely pass the block without having to make any extra provisions. So, bad example of being overzealous for the sake of compatibility I guess.


Note I'm not a professional programmer, just a hobbyist who has been tinkering with Ruby and RM for just over 5 years now, and I think you have been in the RM scene around even longer. I've done far worse in an attempt to maintain compatibility, and looking back at that code, it still can be (and looking at the threads, in many cases, was) broken by another script, regardless of the provisions I had made, so I am just speaking from personal experience.


I could have cited a specific example from there, like the times I avoided overwriting make_obj_damage_value / make_attack_damage_value in separate scripts while changing either way criticals were handled or the damage formula through complicated workarounds, when I could have just overwritten the whole method, which would have made little difference because the scripts already made a large amount of assumptions about what was going on inside the method. Eg., since there was a "damage *= 3 if @critical" buried in the method, and I wanted to modify that 3, my assumption would be that this line remained in any so I would have to divide damage by 3 and then multiply by whatever value I wanted to modify it to. In this case, it was a safe assumption, since if anybody is going to change that value directly they probably wouldn't use a different script that specifically does the same thing, but it is still really easy to break since it operates on that assumption.


@Mike -


If you want to resize the sprite, instead of stretch_blt, which would require you maintaining a unique (not cached) bitmap for each Sprite, consider using the zoom_x and zoom_y properties of the sprite to size it appropriately.

It's window_help, and window_gold.


The width doesn't work with window_gold.


The height and width doesn't work on window_help.


The rest seems fine.
I don't immediately see the issue with a hand trace. I'll run a test on this after you post a finished version and see if I can weed it out.
 

modern algebra

Veteran
Veteran
Joined
Sep 28, 2012
Messages
59
Reaction score
49
First Language
English
Primarily Uses
Ah, OK. That all makes sense and I agree. I'm not a professional either, so I was just curious if there was something I should be fixing. I get what you're saying now and you're right. I have done some very stupid things to avoid overwriting a method that I was totally changing before too, and I agree that beginning scripters shouldn't cripple themselves too much in those ways. And I do think I'll stop bothering to account for blocks. It is pretty pointless.

Also, despite my absurdly long explanation of that code structure last night, I actually realized this morning that the problem I was thinking of could much more elegantly be avoided simply by making it a module and mixing it in:

module MA_Book2_Mixin  def turn_page    super    #bla  endend class Book_2  include MA_Book2_MixinendSo while the structure could still be useful occasionally, it is less useful than I thought it was.
 
Last edited by a moderator:

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
Excellent discussions reside in this topic. Thanks for providing them :3

Being explicit about not touching the information flow is not pointless. A block passed onto a method can be triggered using the yield method without needing an explicit reference. Passing the &block along using the standard alias pattern preserves the method signature. More importantly other scripters can get this information without having to read the aliased method.

I do agree that an over-focus on compatibility can be harmful. Preventing all compatibility issues has the whiff of programming problems in the fundamentally impossible catergory.

*hugs*
 

Mithran

Global Moderators
Global Mod
Joined
Mar 2, 2012
Messages
404
Reaction score
217
First Language
English
Primarily Uses
I didn't mean that binding the block so it could be transparently passed over an alias was useless, there are even some methods in the default scripts where you would need to do this in order for them to function correctly if you were to alias them. I was just pointing out that if a method defined in the default scripts that you already know does not normally use a block (whether passed implicitly or explicitly) is aliased or overwritten by some other scripter to then use a block, then it is already highly likely that the other scripter was not concerned about compatibility and the method in question might not even do what you expect it to do anymore. In these types of situations, you would probably have to make other provisions, anyway.


Again, it was a bad example on my part since the practice itself is not harmful, and is actually useful or necessary in some situations (such as pointed out, not knowing or caring about the actual method's content, transparently passing to preserve the data flow, metacoding, etc.). Using &block in other cases where it is not explicitly needed is never actually detrimental, as long as you understand why you are doing it.


I'm not passing judgement on anyone's practices or speaking in absolutes here. The guidelines are mainly just for those starting out with making compatible RM scripts. Sometimes, anticipating what other scripters will do can be useful and as you become more familiar with the coding practices of others within the community, you can make your own judgement calls as to what you can add to make a script more compatible.
 

Zeriab

Huggins!
Veteran
Joined
Mar 20, 2012
Messages
1,268
Reaction score
1,422
First Language
English
Primarily Uses
RMXP
No, please do continue being awesome. I, for one, appreciate your well-thought out discussions. :3

Occasional attacks on habits are quite useful in reevaluating them. Before your post I had passed along a block in pretty much all aliasing cases for years without considering the value proposition.
Consider you release a script into the wild where you have applied the standard alias pattern. You talked about how a script by another scripter may affect your code. In particular the point about trying to anticipate whatever change that other scripter may make which requires suddenly using a block. A third party is relevant to the discussion. A scripter who having put both scripts in a project needs to debug a problem. Passing on the block when it is not needed is useful information for that third scripter. It is in the eyes of this third scripter where the biggest value lie. (Of course only for the case where the block doesn’t need to be passed along)
I hadn't considered the value of the third party before, so I am quite happy you brought it up ^_^

Speaking in absolutes about heuristics is easier and often gets the point better across compared to embellishing your message with safeguards and probable talk.

*hugs*
 - Zeriab
 

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

Latest Threads

Latest Posts

Latest Profile Posts

How many parameters is 'too many'??
Yay, now back in action Happy Christmas time, coming back!






Back in action to develop the indie game that has been long overdue... Final Fallacy. A game that keeps on giving! The development never ends as the developer thinks to be the smart cookie by coming back and beginning by saying... "Oh bother, this indie game has been long overdue..." How could one resist such? No-one c
So I was playing with filters and this looked interesting...

Versus the normal look...

Kind of gives a very different feel. :LZSexcite:
To whom ever person or persons who re-did the DS/DS+ asset packs for MV (as in, they are all 48x48, and not just x2 the pixel scale) .... THANK-YOU!!!!!!!!! XwwwwX

Forum statistics

Threads
105,853
Messages
1,016,986
Members
137,561
Latest member
visploo100
Top