$imported[:SCRIPT_LIST] (A companion to the proposed expansion of $imported)

What do you think?

  • I like it!

    Votes: 6 54.5%
  • I'm not so sure about this...

    Votes: 4 36.4%
  • I don't like it.

    Votes: 1 9.1%

  • Total voters
    11

PK8

I sense there's something in the wind...
Veteran
Joined
Mar 17, 2012
Messages
1,220
Reaction score
152
Primarily Uses
If you would still like to discuss the potential merits and disadvantages of using the proposed expansion of $imported, or if you'd like to suggest new key/value pairs one could use, click or tap here.

This topic is in some way a response to estriole's reply about the way Victor Sant handles version storage and script dependencies, which is actually a brilliant way to go about it.

Introduction

The purpose behind $imported[:SCRIPT_LIST] is to enhance the recently proposed expansion of $imported. If this were to be adopted by the community along with the latter, a scripter could have more options at their disposal to check for compatibility with other scripts. Users and scripters alike would also have access to a reliable, robust, and perhaps standard way of looking through the list of community-made scripts in the order in which they were installed into the project.

Scripters would be able to utilize $imported[:SCRIPT_LIST] as a means to check for dependencies, to determine whether certain scripts were installed in what they would consider the correct order, and provide solutions based on the result of those conditions. They may also use the data provided within their or another script's personal $imported key to alert the end-user on any potential conflicts that may arise, perhaps due to methods in certain classes being overwritten. Essentially, this alongside the proposed way of writing $imported could make troubleshooting easier for both the scripter and the average RM user.

Implementation

Here is a quick (and ideal) demonstration of how expanded $imported and $imported[:SCRIPT_LIST] would work.

* Any key/value pairs used in any of the following examples are not final and shouldn't be used in a script yet. You can provide suggestions for that in the Improving $imported thread.

Example

# Assign $imported as a hash if it's nil, store information about the script.($imported ||= {})[:username_scriptname] = {  :name => 'Script Name',  :version => '1.0.1',  :author => ['Username'],  :date => '2014-07-21',  :id => :username_scriptname,  :enabled => true,  :aliased => ['Scene_Title#create_background', 'Scene_Title#create_foreground',  'Scene_Title#dispose_background', 'Scene_Title#dispose_foreground']}# Assign $imported[:SCRIPT_LIST] as array, push script info($imported[:SCRIPT_LIST] ||= []) << $imported[:username_scriptname]
The idea is that if more scripts were to use $imported in this form and and if they pushed their information onto the $imported[:SCRIPT_LIST] array, we can begin to read them in the order they were placed onto the script list.

Here's another example. This time with four other scripts. Try not to mind the barebones information that's being provided here. I'm trying to show a small taste of what one could do with that data.

Multiple scripts + Print example

Script 1

# Assign $imported as a hash if it's nil, store information about the script.($imported ||= {})[:username_hello_world] = {  :name => 'Hello World',  :version => '1.0.0',  :author => ['Username'],  :date => '2014-07-21',  :id => :username_hello_world,  :enabled => true}# Assign $imported[:SCRIPT_LIST] as array if nil, push script info onto it.($imported[:SCRIPT_LIST] ||= []) << $imported[:username_hello_world]
Script 2

# Assign $imported as a hash if it's nil, store information about the script.($imported ||= {})[:username_pause] = {  :name => 'Pause Script',  :version => '1.5.0',  :author => ['Username'],  :date => '2008-12-25',  :id => :username_pause,  :enabled => true}# Assign $imported[:SCRIPT_LIST] as array if nil, push script info onto it.($imported[:SCRIPT_LIST] ||= []) << $imported[:username_pause]
Script 3

# Assign $imported as a hash if it's nil, store information about the script.($imported ||= {})[:username_inventory_caps] = {  :name => 'Inventory Caps',  :version => '1.3.2',  :author => ['Username'],  :date => '2011-08-23',  :id => :username_inventory_caps,  :enabled => true}# Assign $imported[:SCRIPT_LIST] as array if nil, push script info onto it.($imported[:SCRIPT_LIST] ||= []) << $imported[:username_inventory_caps]
Script 4

# Assign $imported as a hash if it's nil, store information about the script.($imported ||= {})[:username_platformer] = {  :name => 'Platformer',  :version => '1.2.0',  :author => ['Username'],  :date => '2010-04-12',  :id => :username_platformer,  :enabled => true}# Assign $imported[:SCRIPT_LIST] as array if nil, push script info onto it.($imported[:SCRIPT_LIST] ||= []) << $imported[:username_platformer]
A quick and dirty result Print.

$imported[:SCRIPT_LIST] ||= []str = ''$imported[:SCRIPT_LIST].each { |i|  str += "#{i[:name]} v#{i[:version]} \n"}print str
Result




While the above example is underwhelming, there are a lot of (advanced) things that could be done with this. So what do you guys think? Do you like it? Not like it? Think it needs refining? Have any questions or suggestions? Got a better name we could use than :SCRIPT_LIST? Post your thoughts!
 
Last edited by a moderator:

FenixFyreX

Fire Deity
Veteran
Joined
Mar 1, 2012
Messages
434
Reaction score
308
First Language
English
Primarily Uses
I like the idea of the system, except for the fact that I feel like $imported[:SCRIPT_LIST] is an unnecessary step? I would just recommend this:

# Assigning $imported as a hash if it's nil.$imported ||= {}# Storing information about the script$imported[:username_scriptname] = { :index => $imported.keys.size, # This line changes it all; it also removes the extra array of data that is already present in $imported :name => 'Script Name', :version => '1.0.1', :author => ['Username'], :date => '2014-07-21', :id => :username_scriptname, :enabled => true, :aliased => ['Scene_Title#create_background', 'Scene_Title#create_foreground', 'Scene_Title#dispose_background', 'Scene_Title#dispose_foreground']}
This way, we can simply:

($imported ||= {}).values.sort_by {|hash| hash[:index] || 0 }And besides, that should even be unnecessary in Ace, as Hashes in ruby are ordered now; this code will get you the very first script added to $imported:
Code:
$imported ||= {}; $imported[$imported.keys[0]]
And that has been guaranteed since (I do believe) Ruby 1.9.1. If they are working in VX or XP, they can simply use this:
Code:
$imported ||= {}; $imported.sort_by {|k,v| v[:index] || 0 }[0]
and it'll do the same thing.I also feel like we are forgetting a crucial detail here; if we are going to this measure to add a method of compatibility, we might as well create a use-all register-your-code script; but that idea, as well as $imported, is completely optional Meaning, this doesn't really help all too much if every script doesn't use it, as there are still compatibility holes left.

Now, I'm not suggesting we give the idea up (except for the :SCRIPT_LIST part :p ), but how are you planning on making this commonplace?
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,230
Reaction score
3,071
First Language
English
Especially since I'm evidently unable to type a version number as a string, having to suddenly type in a hash and fill it with a bunch of key-value pairs seems like a huge leap.


Granted, I'd probably end up just updating my script template with that so it wouldn't be too bad.


So people that have a system set up would likely have an easier (or harder) time with it.


I don't know if I want to go through hundreds of scripts to update them though.
 
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
I would just recommend this:

# Assigning $imported as a hash if it's nil.$imported ||= {}# Storing information about the script$imported[:username_scriptname] = { :index => $imported.keys.size, # This line changes it all; it also removes the extra array of data that is already present in $imported :name => 'Script Name', :version => '1.0.1', :author => ['Username'], :date => '2014-07-21', :id => :username_scriptname, :enabled => true, :aliased => ['Scene_Title#create_background', 'Scene_Title#create_foreground', 'Scene_Title#dispose_background', 'Scene_Title#dispose_foreground']}
This way, we can simply:

($imported ||= {}).values.sort_by {|hash| hash[:index] || 0 }Even though that is a good idea, there are a few issues that your suggestion presents. If the expansion of $imported (I can't think of a better name) were to become commonplace, we would still have to use and work with scripts that either have booleans, strings, floats, or hashes that contain another hash* ($imported[:username] ||= {}; $imported[:username][:yourscripthere] = true;) being assigned to their $imported keys.
* Hashes containing nested hashes aren't as much of a problem as the others. However, if someone were to use :index => $imported.keys.size inside of their nested hashes, the index would remain the same and the parent hash would appear out of order in the sort_by call.

That could prove to be problematic for when we want to index and sort the scripts we install. For one, some index numbers could wind up appearing 'skipped' because of the other $imported keys that either don't include :index in their hashes or aren't hashes at all. Two, if we were to try to sort out $imported while strings/floats/boolean values are being assigned to certain $imported keys, we would run into some errors.

And besides, that should even be unnecessary in Ace, as Hashes in ruby are ordered now; this code will get you the very first script added to $imported:

$imported ||= {}; $imported[$imported.keys[0]]
While that is actually a very good point, there's still also the aforementioned issue with working with a script that has a hash containing a nested hash in its $imported key.
I also feel like we are forgetting a crucial detail here; if we are going to this measure to add a method of compatibility, we might as well create a use-all register-your-code script; but that idea, as well as $imported, is completely optional Meaning, this doesn't really help all too much if every script doesn't use it, as there are still compatibility holes left.
I'm glad you mentioned this! My reasoning for what I'm about to say might sound a little off, but the reason why I've done everything short of actually suggesting that we write some sort of Script Registration/Verification script is mainly to not complicate things (further) with both the scripter and the average user. And I know it sounds kind of funny considering what I'm doing with my two suggestions, but think about it. While going from assigning booleans or version numbers as strings and floats to assigning a hash that's full of key/value pairs to an $imported key might seem like such a huge leap, it's really not going to get to the point where we're going to start requiring users to install a verification/registration script just to verify another script. I'm trying my best to avoid going in that direction.
Edit: I like that $imported is optional. In fact, I find that pretty cool and I hope it remains optional to use and implement despite the improvements being suggested.
Now, I'm not suggesting we give the idea up (except for the :SCRIPT_LIST part :p ), but how are you planning on making this commonplace?
I kind of don't have a game plan right now. I was hoping more people would find these topics interesting enough to provide their input on them whether or not they like either of these ideas, and just hope for the best. Other than that, I don't think there's really much I could do to drum up some interest besides advertising these threads in my signature.
Edit 2:
Especially since I'm evidently unable to type a version number as a string, having to suddenly type in a hash and fill it with a bunch of key-value pairs seems like a huge leap.

Granted, I'd probably end up just updating my script template with that so it wouldn't be too bad.

So people that have a system set up would likely have an easier (or harder) time with it.

I don't know if I want to go through hundreds of scripts to update them though.
I don't think you'll have much to worry about. I just learned today (though I should've known earlier from looking at Mithran's post in the other thread and now I feel slightly stupid for it though I did learn something new in the process) that just checking for $imported[key] does indeed implicitly evaluate as true. So I don't think you'll be breaking anything. /goingonatangentBut I do agree that it would be a lot of work to do and that it is indeed a pretty huge leap compared to just assigning true to an $imported key.
 
Last edited by a moderator:

FenixFyreX

Fire Deity
Veteran
Joined
Mar 1, 2012
Messages
434
Reaction score
308
First Language
English
Primarily Uses
I see your point; actually, I welcome it. It's making me question my ability to accurately problem solve and not second guess, lol. I gotta figure out how to counteract the whole value-might-not-be-a-hash...perhaps:

$imported.sort_by {|k,v| $imported.keys.index(k) }However, this would only work in Ace as in Ruby 1.8.X, hashes are unordered...and that still leaves the whole sub-hash problem out in the open; perhaps keep a counter, instead of an array?
Code:
( ($imported ||= {})[:index] = 0; $imported )["<name>_<script>"] = "1.0.0"
However, there is one flaw with all of the entire system period; $imported[:SCRIPT_LIST] won't hold all of the $imported values anyway, as there are (around) a hundred scripts that use it without using $imported[:SCRIPT_NAME], or a counter, or anything. How do you propose we handle this, other that attempting to use $imported.index or something akin to it? If we use :SCRIPT_LIST, there will still be unidentified scripts.
Don't get me wrong, I actually love the idea of somehow keeping track of what scripts are where to be able to further produce compatibility! I just don't like the idea of lugging around and extra array in a global; it feels dirty (this is my C/C++ side talking now; memory management away~! But I digress.)..


I support this, I just feel like it could be a bit more refined and fleshed out. Here's to hoping we get some more input on the idea.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,230
Reaction score
3,071
First Language
English
lol provide a "script manager" script that will handle the differences for us.


Or abandon those scripts and start fresh. If they want to be cool, they can jump on the train.


Bringing a lot of baggage into a new venture usually just makes it more troublesome than it should and may limit its effectiveness.
 
Last edited by a moderator:

estriole

Veteran
Veteran
Joined
Jun 27, 2012
Messages
1,030
Reaction score
335
First Language
indonesian
totally agree with Hime here.

for future scripts this could be done. but editting all those previous scripts is a tedious work :D . i might not create as many scripts as Hime... but it's already hard work for me... so i think her burden is way lots more :D .
 

PK8

I sense there's something in the wind...
Veteran
Joined
Mar 17, 2012
Messages
1,220
Reaction score
152
Primarily Uses
However, there is one flaw with all of the entire system period; $imported[:SCRIPT_LIST] won't hold all of the $imported values anyway, as there are (around) a hundred scripts that use it without using $imported[:SCRIPT_NAME], or a counter, or anything. How do you propose we handle this, other that attempting to use $imported.index or something akin to it? If we use :SCRIPT_LIST, there will still be unidentified scripts.


Don't get me wrong, I actually love the idea of somehow keeping track of what scripts are where to be able to further produce compatibility! I just don't like the idea of lugging around and extra array in a global; it feels dirty (this is my C/C++ side talking now; memory management away~! But I digress.)..


I support this, I just feel like it could be a bit more refined and fleshed out. Here's to hoping we get some more input on the idea.
$imported[:SCRIPT_LIST] isn't meant to be used for scripts whose $imported keys aren't assigned with hashes (or doesn't contain the necessary key/value pairs (which could be proposed in the other thread)) as they contain no information about the scripts. Thankfully, we can push something that looks like this...
$imported[:username][:script] = { :item1 => 'value', ... }...into the $imported[:SCRIPT_LIST] array and manipulate the data for our needs without much trouble. You can also loop through the array and find whatever specific data (Names, $imported key IDs...) you need and easily manipulate that from there.
Code:
$imported[:SCRIPT_LIST][0][:enabled] = false
I'm kind of going off on another tangent, but this will be good to know.
Anywho, I know we're going to have a huge list of unidentified scripts ahead of us. Garnering support for it will be anything but easy.


What we'll have to do first is try to get Expanded $imported (working name) and $imported[:SCRIPT_LIST] perfected by providing a lot of input in both threads. For Expanded $imported, we'll need to get started on suggesting key/value pairs that will be used and then explain how they would be implemented. I might just get started on doing that in the other thread. For this thread, we'll just have to come up with ways to refine it further. (Personally, I think $imported[:SCRIPT_LIST] is fine, but that's just me.)


Once we feel that Expanded $imported and $imported[:SCRIPT_LIST] are ready to be used in other scripts (perhaps starting with ours), the next thing we're going to have to do is lead by example. We'll need to show and prove to people that this is (or very well could be) a vast improvement over $imported's original implementation. To do this, we'll need to explain the purpose of $imported along with how advanced it's become. Possibly by writing a tutorial thread that encourages us to write snippets based on $imported and share some neat tricks we could do with both $imported and $imported[:SCRIPT_LIST]. The more tricks and potential use cases we share, the more likely people might be wowed by its potential and feel inclined to use for their own scripts too.


If we advertise it just right, this might catch on a little quicker than we expect.


After that, we'll have to start going through old scripts and update them to reflect the changes with $imported.


Unfortunately, Tsukihime's going to have a lot of work to do, if Hime is still up for it. Though if Hime does wind up going for it, Hime might be able to give Expanded $imported and $imported[:SCRIPT_LIST] the exposure it needs for other people to look at it and say "Hey, I like this!" Hime, if you're reading this, I'm so sorry.
 

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,230
Reaction score
3,071
First Language
English
My scripts follow a template so replacing them is a matter of a quick regex search and replace.


Well in general if you're using $imported at all, you likely are using the same pattern over and over.
 
Last edited by a moderator:

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
96
First Language
Dutch
Primarily Uses
It should have been built into the RPG Maker Engine. At least an id, name, version, author, license and what other scripts it requires. But we don't even have a script-tree, just a list in a limited sized window that for some reason can not even be resized and no checkbox infront of a script to quickly disable it or something.

Personally I always used, and will use:

$imported[:nap_script_x] = 1.00I still see people just write:

$imported[:script_y] = trueBut I don't like not having the script author as a name prefix and assigning a boolean where you could have assigned the version number directly is also a waste imo.

Expanding the $imported is not something I would ever be interested in as a Developer. It belongs in the Engine itself.

The more annoying part however is having to define a method that checks for other required scripts and their version number and such in EVERY script. Because you can add it to your core-script but what if they don't want your core script?

That's another reason why I wrote my "Script boss" script. It checks for dependencies, enables, disables scripts (and their dependencies) and performs some minor sanity checks.

But for small projects a simple imported is more than good. Besides, RM is not even aimed at developers but more at general people without any scripting knowledge anyway.
 
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
It should have been built into the RPG Maker Engine. At least an id, name, version, author, license and what other scripts it requires. But we don't even have a script-tree, just a list in a limited sized window that for some reason can not even be resized and no checkbox infront of a script to quickly disable it or something.
Yeah it should've been but it's not, and for the rest of Ace's life cycle, it's not ever going to be built. So why shouldn't we go for the next best thing and actually tag all of this information to the scripts ourselves?
Personally I always used, and will use:

$imported[:nap_script_x] = 1.00I still see people just write:
Code:
$imported[:script_y] = true
But I don't like not having the script author as a name prefix and assigning a boolean where you could have assigned the version number directly is also a waste imo.
Then call the person out on it if you see them not using a unique identifying prefix in their $imported keys. Also, if I could be frank, assigning a version number written either as a string or a float seems like a waste in my opinion, especially when there's a lot more that could be with it if it were assigned a hash. Though I do admit it's certainly better than just assigning true to your own $imported key and leaving it at that.
Expanding the $imported is not something I would ever be interested in as a Developer. It belongs in the Engine itself.

The more annoying part however is having to define a method that checks for other required scripts and their version number and such in EVERY script. Because you can add it to your core-script but what if they don't want your core script?
Correct me if I misread this, but have you even read my two threads? Everything that I'm proposing in them is completely optional to include in your script, and even then, this only adds a layer of extra information to the script that other people can use and reference in their own scripts if need be. So any requirements involving $imported that's being written into someone's script would be on the scripter's end, not on $imported's.
That's another reason why I wrote my "Script boss" script. It checks for dependencies, enables, disables scripts (and their dependencies) and performs some minor sanity checks.
Not sure if this is a subtle plug...Another thing I'm attempting to encourage with the expansion of $imported, particularly with the use of the proposed :enabled key, is to get scripters to wrap their entire script with an if condition that checks if the script has been set to enabled. This is so the average user wouldn't be required to put in much effort in completely hard disabling a script themselves.
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,230
Reaction score
3,071
First Language
English
Then call the person out on it if you see them not using a unique identifying prefix in their $imported keys. Also, if I could be frank, assigning a version number written either as a string or a float seems like a waste in my opinion, especially when there's a lot more that could be with it if it were assigned a hash. Though I do admit it's certainly better than just assigning true to your own $imported key and leaving it at that.
I always thought it was just for checking whether a script exists or not. Like, that was its whole purpose.


Never read the history though, so maybe there was more to it?
 
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
I always thought it was just for checking whether a script exists or not. Like, that was its whole purpose.
That was pretty much it, basically. And I thought that was actually a very clever way to go about it too, once I learned what $imported did. But now I'm thinking in retrospect (and this is just my opinion), assigning the value true to an $imported key seems a little redundant to do. Especially since one could add an additional piece of information they could reference (for example, a version number) and just check if a certain key was included in the $imported hash (in case they didn't know they could use $imported[key] in a conditional and still have it be evaluated as true) to detect whether a script was installed into someone's project or not.
Edit:

Never read the history though, so maybe there was more to it?
Same here. According to Jet... (See topic)

As far as I know it actually began in the Japanese RM coding community, and trickled over with its inclusion in KGC, Yanly, and other major scripter's collections.
Aaaaaaaand that's pretty much all I know.
 
Last edited by a moderator:

Napoleon

Veteran
Veteran
Joined
Dec 29, 2012
Messages
869
Reaction score
96
First Language
Dutch
Primarily Uses
Yes I agree it's a 'subtle' plug indeed :p . But I didn't see any other option at the time.

And improving the $imported is indeed optional because it still validates the

if $imported[:my_stuff]properly. You could even put another script in it. BUT, if only some scripters make use of the 'extended $imported' then scripts that scan for version numbers, licenses, authors, etc. will still be completely useless. You can't even make an automated credits-script because what if it misses even just one script? If must be in the engine and it must be enforced imo.

But even if we would include all that, if others don't then you can only use them for your own scripts. Unless we get something like:

$imported[:someone_elses_stuff][:imported_version] = 1.00So we can check what is available.

But still we would have to check for all kinds of if-statements or for the imported version number and if it mismatches then just skip it all?:

if $imported[:someone_elses_stuff]  if $imported[:someone_elses_stuff][:version] && $imported[:someone_elses_stuff][:version] < 1.32    <do stuff>  end   if $imported[:someone_elses_stuff][:license] &&  $imported[:someone_elses_stuff][:license] != :cc0   p 'warning, non-cc0 license detected in ....' endendI foresee problems either way. And you still get other problems like is the version number a float or a string ("1.30a"). Things like that. Personally I require a float for checking for required scripts and minor revisions like "a" and "b" are simply omitted. So it would have to be sharply defined somewhere and all 'popular' scripters should use it. Otherwise I still don't see a reason to use it (personal opinion).
 
Last edited by a moderator:

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,230
Reaction score
3,071
First Language
English
Some people also like to use really intricate version systems, for example you have things that might look like


1.2.2.232-r47


I don't see the point, but some people like it.
 
Last edited by a moderator:

Galenmereth

I thought what I'd do was
Veteran
Joined
May 15, 2013
Messages
2,207
Reaction score
1,923
First Language
English
Primarily Uses
RMMV
Some people also like to use really intricate version systems, for example you have things that might look like

1.2.2.232-r47

I don't see the point, but some people like it.
While I personally feel like major, feature, minor is a good enough versioning scheme, the -r47 part is an addition that is nice for widely used software: r47 would stand for "release candidate", meaning it is believed to be bug free enough to be a candidate for public use. However, it does denote that it has not yet been tested in a public environment long enough to be considered "production" safe. There are good reasons for these schemes with widely used codebases, like Ruby on Rails and the Ruby language itself as examples. The larger and more widely adopted a codebase is, the more important it becomes to have finer granular versioning schemes to keep the public informed of the safety of a new version in test and production use cases :)
 
  • Like
Reactions: PK8

Tsukihime

Veteran
Veteran
Joined
Jun 30, 2012
Messages
8,230
Reaction score
3,071
First Language
English
That makes sense.


If we really need to provide proper version checking, it would be best to just provide a standard method that will decompose a "proper" version number.


However, now you're starting to move towards a new script that provides script management functionality.


However, introducing such a script should basically have no compatibility issues
 
Last edited by a moderator:
  • Like
Reactions: PK8

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

Latest Threads

Latest Posts

Latest Profile Posts

I really need to stop thinking there are new freebies just because someone made a new post in the freebies subforum lol.
AND just like that..... I got STEAM DLC up and working! YES!
Game making is like a marathon, except the last 1/4 is more like sprint... a very long and intense sprint.
Finally got to finish the demo for my project!
Another week has gone by. Maybe you made changes to your project/s. Maybe you didn't. Nonetheless, THAT IS NO EXCUSE TO NOT BACK THEM UP O_O!

Forum statistics

Threads
93,441
Messages
912,445
Members
122,968
Latest member
Paitshens
Top