Cross-engine scripting and RGSS/Maker version detection (8/4 update: Added polls!)

Discussion in 'RGSSx Scripts In Development' started by PK8, Jul 30, 2014.

?

Maker Detection: Name Scheme?

  1. xp / vx / ??? [use 3rd question to decide ace name]

    77.8%
  2. rmxp / rmvx / rm??? [use 3rd question to decide ace name]

    11.1%
  3. rpgxp / rpgvx / rpg??? [use 3rd question to decide ace name]

    11.1%
Multiple votes are allowed.
  1. PK8

    PK8 I sense there's something in the wind... Veteran

    Messages:
    1,220
    Likes Received:
    152
    Location:
    Spiral Hill
    Although this thread involves the $imported variable like my two other threads (See: Improving $imported and $imported[:SCRIPT_LIST]), this one is not quite as related to those two since it isn't focused on bettering compatibility checks.


    This thread is going to shine a light on proposing two ways in which we can accomplish cross-engine scripting


    Background (You can go ahead and skip this part)


    During my I-took-a-break-longer-than-actually-intended hiatus, I was writing and refining more than a few scripts on a sporadic basis. Most of those scripts worked seamlessly with all RGSS-capable versions of RPG Maker from the start as their code was generally the same, save for a few extra settings along with some extra functionality to go with it.


    Because it's so well known now that one could make their RPG Maker XP project capable of utilizing RGSS2 or RGSS3 functionality or even get their RMVX project to use RGSS3, I figured I should just let users of older makers be able to take advantage of functionality provided by the later (or the latest) versions of RGSS if they really wanted it. Of course, they would have to enable it through a setting in order to gain access to it, right after they do a lengthy process to power their projects with RGSS2/RGSS3.


    But after awhile, I started growing tired of managing 2-3 different text files that had very little differences in each (for some, the only differences were the inclusion of if statements for whether the RGSS2/RGSS3 settings were enabled). I also grew tired of users having to gain access to the extra functionality by changing the value of a particular setting. That's when I decided to start looking into scripts that could sniff out/detect which version of RGSS and RPG Maker someone is using.


    Introduction


    In this thread, I will be proposing two suggestions that (when implemented) could greatly aid a scripter in writing cross-engine scripts. Whether that be scripts that could be installed in any RGSS-capable RPG Maker and/or scripts that grants users access to extra features and calls depending on which version of RGSS is being used. This means that someone could write a script that is very friendly towards older versions of RPG Maker, but can automatically take advantage of what the latest version of RGSS offers if the user decides to power their projects with later versions of RGSS. In order to do this, we will be using a sniffing/detection technique that sniffs out which RPG Maker and version of RGSS a user is using.


    These wouldn't need to be included in our $imported checks at the top of our script (especially not in every script), unless the scripter absolutely needs to use it for a script that's intended to be cross-engine in the sense that it could be installed in any maker and/or use any feature provided by later versions of RGSS.


    Implementation


    Their keys will be named :RGSS_VERSION and :MAKER_VERSION and they can be used within the $imported hash.


    We will be using Constants named RGSS_VERSION (Already available in Ace as mentioned by cremnophobia) and MAKER_VERSION. You can read the next section to learn about the differences between the two.


    So I was bouncing ideas back and forth with FenixFyreX about putting together detection scripts people can use. You can click the spoiler to look at what we came up with.

    For RGSS Version detection, Fenix and I came up with this.*


    * Unfortunately, I had to bunch up the code in order to get it to fit within the script editor's margin line, so it doesn't look quite as pretty as it did before then.

    $imported[:RGSS_VERSION]||=RUBY_VERSION.to_f==1.8 ? (defined?(Hangup) ? 1:2) : 3
    cremnophobia in their next reply suggested something much better than that.
    As for Maker detection, Fenix suggested that the best and safest way to determine which maker is being used is to check for data file extensions. Unfortunately, I have yet to come up with a decent snippet everyone could use to detect which RPG Maker a project uses. I then came up with a decent Maker Detection snippet.


    Q&A


    Q: What's the difference between RGSS_VERSION and MAKER_VERSION?

    RGSS_VERSION would indicate which version of RGSS your project uses no matter which RPG Maker you use.

    MAKER_VERSION should indicate which RPG Maker you use no matter which version of RGSS your project is powered by.

     
    Q: Is this required?

    From the perspective of the scripter and the user: No and no.

    Like $imported[:SCRIPT_LIST] and the expansion of $imported, this is optional for scripters to insert into their script. It also doesn't need to be inserted into every script. Only insert either or both of these somewhere around the top of your script below the header (Near the Import Check if your script includes that) if your script relies on RGSS/Maker version detection.


    Now irrelevant Q&As

    Q: Why $imported (again)?
    Because $imported has already been established as a de facto standard among scripters for a number of years (and it works). Also because we don't need to invent two more global variables just for this purpose.

     


    So any questions? Comments?


    Do you like or dislike this idea?


    Came up with better snippets than what's been posted up here thus far? (This is important. If one could come up with a snippet for MAKER_VERSION, this could have the potential to become something of a standard among scripters too.)
     
    Last edited by a moderator: Aug 4, 2014
    #1
  2. cremnophobia

    cremnophobia Veteran Veteran

    Messages:
    194
    Likes Received:
    80
    Why $imported?
     
    Your line of code isn't future-proof. Of course, scripts aren't too and perhaps can't be (without just hoping they are). But what if RGSS4 is released? Then script with this line sets the value to 3. Another script with a fixed RGSS version check could get it right, but can't anymore.

    Also, there is already a way to get the RGSS version (at the moment only in RGSS3). Why introduce a new one? Since you want it to be squeezed into a line, I suggest this (or something similar as some people might prefer the if modifier statement):

    defined?(RGSS_VERSION) || (RGSS_VERSION = defined?(Hangup) ? '1.0.0' : '2.0.0')A more reliable one needs more lines and maybe a DLL.
     
    #2
    PK8 likes this.
  3. PK8

    PK8 I sense there's something in the wind... Veteran

    Messages:
    1,220
    Likes Received:
    152
    Location:
    Spiral Hill
    Wow, good points all around! I didn't even know about the existence of RGSS_VERSION (for Ace) til today. Thanks for that. I'll just try to answer your questions in the form of what was going through my mind as I made this thread. :guffaw: But you're definitely right!

    Before you mentioned RGSS_VERSION (for Ace), it was like I said in my OP. $imported seemed to be a good fit. What was going through my mind was "If a $imported hash didn't exist, a certain script would've made it anyway." It seemed natural(?) to me to use $imported for concepts like this and :SCRIPT_LIST. After reading your comment, I'm beginning to have some second thoughts there.
    I was aware. But I thought we could've been able to get around the lack of future-proofing with using $imported[:RGSS_VERSION] >= 3
    Like I said earlier, I had no idea RGSS_VERSION existed. I was trying to come up with something that would let scripters write cross-engine scripts no matter which version of RGSS they're using and no matter which RPG Maker they use (For example: RPG Maker XP + RGSS3 Capabilities). Your code is more future proof than what Fenix and I had going on. I just hope RGSS_VERSION sticks around for RGSS4.Now I'm kind of regretting not making $imported[:SCRIPT_LIST] a constant when I was first suggesting it.
     
    #3
  4. MobiusXVI

    MobiusXVI Game Maker Veteran

    Messages:
    362
    Likes Received:
    84
    First Language:
    English
    For maker detection, could you use check the extension of something like the project or the script? when I put this in my script editor, it seems to work alright.

    Code:
      array = Dir.glob("*.{rxproj,rvproj,rvproj2}")  ext = File.extname(array[0])  case ext  when ".rxproj"    print ("XP")  when ".rvproj"    print ("VX")  when ".rvproj2"    print ("VXAce")  end 
     
    #4
  5. PK8

    PK8 I sense there's something in the wind... Veteran

    Messages:
    1,220
    Likes Received:
    152
    Location:
    Spiral Hill
    I just tried it out. While it works in cases where we're testing our projects, it seems to start breaking when the project's encrypted. If you could get that to work while a project is encrypted, that would be awesome.

    I just came up with a Maker Detection snippet. It should be able to work with both encrypted and unencrypted games since it makes use of load_data. Though I'm not sure if it's really any good because I just used load_data to load Scripts.ext for detection purposes. (Would there be anything wrong with doing this?)

    Attempt #1

    MAKER_VERSION = (["rxdata", "rvdata", "rvdata2"].each { |i| file = load_data("Data/Scripts.#{i}") rescue nil file = true if file case i when "rxdata"; break :xp if file when "rvdata"; break :vx if file when "rvdata2"; break :vxa if file else; break :other end}) if !defined?(MAKER_VERSION)
    Attempt #2

    MAKER_VERSION = (['rxdata', 'rvdata', 'rvdata2'].each { |i| file = load_data("Data/Scripts.#{i}") rescue nil file = true if file case i when 'rxdata'; break :xp if file when 'rvdata'; break :vx if file when 'rvdata2'; break :vxa if file end break :other if i == 'rvdata2' and !file}) if !defined?(MAKER_VERSION)
    Attempt #3 (Line reduction attempt)

    Code:
    MAKER_VERSION = (['rxdata', 'rvdata', 'rvdata2'].each { |i|    file = load_data("Data/Scripts.#{i}") rescue nil; file = true if file    break :xp if i == 'rxdata' && file; break :vx if i == 'rvdata' && file    (file ? (break :vxa) : (break :other)) if i == 'rvdata2'}) if !defined?(MAKER_VERSION)
     
    Last edited by a moderator: Aug 2, 2014
    #5
  6. PK8

    PK8 I sense there's something in the wind... Veteran

    Messages:
    1,220
    Likes Received:
    152
    Location:
    Spiral Hill
    Alright, I have waited literally 72 hours to do this so here we go.


    I have added a series of questions I'd like other scripters to answer, if they're also interested in making RPG Maker Detection a thing. Answering these will give us some values we can consistently use and check for when writing cross-engine scripts.
     
    #6
  7. Zeus81

    Zeus81 Veteran Veteran

    Messages:
    164
    Likes Received:
    149
    First Language:
    French
    Personnaly my favorite way to do this now is :

    def xp?() false end; alias vx? xp?; alias vxace? xp?RUBY_VERSION == '1.8.1' ? defined?(Hangup) ?def xp?() true end : def vx?() true end : def vxace?() true endIt creates 3 private methods in Object.

    I came to this because it's shorter to write 'if xp?' than 'if RGSS_VERSION == "1.0.0.0"' and in case we're using it in a loop it offers better performances, string comparison sucks.
     
    #7
  8. Shaz

    Shaz Veteran Veteran

    Messages:
    37,912
    Likes Received:
    11,586
    Location:
    Australia
    First Language:
    English
    Primarily Uses:
    RMMV
    I didn't read through it all, but if you're after "what do I call each version?", why not just go with the standards that everybody already uses?


    XP, VX and Ace.
     
    #8
    ShinGamix and PK8 like this.
  9. ShinGamix

    ShinGamix DS Style 4Ever! Veteran

    Messages:
    3,906
    Likes Received:
    448
    Location:
    Alien Ship
    First Language:
    April Fools
    Primarily Uses:
    N/A
    oh wow!! This is awesome! Is there an MV Mode also? So could I use scripts from Xp in Ace?
     
    #9
  10. TheoAllen

    TheoAllen Self-proclaimed jack of all trades Veteran

    Messages:
    4,485
    Likes Received:
    5,093
    Location:
    Riftverse
    First Language:
    Indonesian
    Primarily Uses:
    RMVXA
    If you don't know yet, MV use Javascript, not Ruby, so no.
     
    #10
    ShinGamix likes this.
  11. ShinGamix

    ShinGamix DS Style 4Ever! Veteran

    Messages:
    3,906
    Likes Received:
    448
    Location:
    Alien Ship
    First Language:
    April Fools
    Primarily Uses:
    N/A
    What about using Xp or vx scripts in ace?? That would be epic and God like!
     
    #11
  12. TheoAllen

    TheoAllen Self-proclaimed jack of all trades Veteran

    Messages:
    4,485
    Likes Received:
    5,093
    Location:
    Riftverse
    First Language:
    Indonesian
    Primarily Uses:
    RMVXA
    Uh, this whole thread is about how script is detecting xp/vx/ace. Not directly how to use xp/vx script to Ace. It's about how you write a script that checks if the script is installed in xp/vx/ace so you can write a cross platform script. If the script is placed in xp, then do this, if vx, do that, etc.
     
    #12
  13. ShinGamix

    ShinGamix DS Style 4Ever! Veteran

    Messages:
    3,906
    Likes Received:
    448
    Location:
    Alien Ship
    First Language:
    April Fools
    Primarily Uses:
    N/A
    crrap...I am going to pm I want to discuss something with you then.
     
    #13

Share This Page