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

Maker Detection: Name Scheme?


  • Total voters
    9

PK8

I sense there's something in the wind...
Veteran
Joined
Mar 17, 2012
Messages
1,220
Reaction score
152
Primarily Uses
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.
Cremnophobia said:
Code:
defined?(RGSS_VERSION) || (RGSS_VERSION = defined?(Hangup) ? '1.0.0' : '2.0.0')
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:

cremnophobia

Veteran
Veteran
Joined
Dec 10, 2013
Messages
195
Reaction score
80
Primarily Uses
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.
 
  • Like
Reactions: PK8

PK8

I sense there's something in the wind...
Veteran
Joined
Mar 17, 2012
Messages
1,220
Reaction score
152
Primarily Uses
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!

Why $imported?
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.
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.
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
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.
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.
 

MobiusXVI

Game Maker
Veteran
Joined
Mar 20, 2013
Messages
362
Reaction score
84
First Language
English
Primarily Uses
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 
 

PK8

I sense there's something in the wind...
Veteran
Joined
Mar 17, 2012
Messages
1,220
Reaction score
152
Primarily Uses
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:

PK8

I sense there's something in the wind...
Veteran
Joined
Mar 17, 2012
Messages
1,220
Reaction score
152
Primarily Uses
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.
 

Zeus81

Veteran
Veteran
Joined
Mar 17, 2012
Messages
164
Reaction score
149
First Language
French
Primarily Uses
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.
 

Shaz

Veteran
Veteran
Joined
Mar 2, 2012
Messages
38,343
Reaction score
11,939
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.
 

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,906
Reaction score
448
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?
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
4,645
Reaction score
5,284
First Language
Indonesian
Primarily Uses
RMVXA
oh wow!! This is awesome! Is there an MV Mode also? So could I use scripts from Xp in Ace?
If you don't know yet, MV use Javascript, not Ruby, so no.
 

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,906
Reaction score
448
First Language
April Fools
Primarily Uses
N/A
If you don't know yet, MV use Javascript, not Ruby, so no.
What about using Xp or vx scripts in ace?? That would be epic and God like!
 

TheoAllen

Self-proclaimed jack of all trades
Veteran
Joined
Mar 16, 2012
Messages
4,645
Reaction score
5,284
First Language
Indonesian
Primarily Uses
RMVXA
What about using Xp or vx scripts in ace?? That would be epic and God like!
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.
 

ShinGamix

DS Style 4Ever!
Veteran
Joined
Mar 18, 2012
Messages
3,906
Reaction score
448
First Language
April Fools
Primarily Uses
N/A
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.
crrap...I am going to pm I want to discuss something with you then.
 

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

Latest Threads

Latest Profile Posts

Can't wait for the next Sonichu
Birdhouses are usually made of wood. Birds typically live in trees. Trees are wood. Birdhouses are made of birdhouses.
He just discovered cellphones...

(I don't know why am I drawing so much these days...)
In medieval times, a common way to eat food was upon edible plates, which were made of bread, called trenchers.

Forum statistics

Threads
93,668
Messages
914,417
Members
123,254
Latest member
Ragnamano
Top