|
| 15 Jan 2014 02:46 PM |
| From what I've seen and heard of module scripting they are just huge functions. That can run GLOBABLY just like _G's. So what's the difference? :| |
|
|
| Report Abuse |
|
|
|
| 15 Jan 2014 02:52 PM |
| I kind of wondered the same thing myself. I think one advantage is that sometimes the global table wasn't always loaded in time, and the require function waits until a value is returned before continuing. But other than that I'm not exactly sure. |
|
|
| Report Abuse |
|
|
Thaeh
|
  |
| Joined: 05 Feb 2011 |
| Total Posts: 7685 |
|
|
| 15 Jan 2014 03:02 PM |
| Probably just to make it neater. |
|
|
| Report Abuse |
|
|
|
| 15 Jan 2014 03:10 PM |
Modules can be used by both Scripts and Local Scripts connected Using a _G.Function doesn't work the same, Client scripts and Server Side scripts don't connect with _G |
|
|
| Report Abuse |
|
|
adark
|
  |
| Joined: 13 Jan 2008 |
| Total Posts: 6412 |
|
|
| 15 Jan 2014 03:17 PM |
Safer, actually.
I have to test it later, but I'm decently sure that you can set a local variable inside the ModuleScript using a Setter function from something that utilizes it.
Effectively, we just got real C/C++ classes, and all you have to do is replicate the ModuleScript if you want completely separate objects. (Although it would be better to have each be a 'container' that you script to allow multiple child objects using fancy table hacks.) |
|
|
| Report Abuse |
|
|
adark
|
  |
| Joined: 13 Jan 2008 |
| Total Posts: 6412 |
|
|
| 15 Jan 2014 03:18 PM |
| @Dog; That can be countered by using Remote* objects to access the Server's _G from a LocalScript, but ModuleScripts are just easier. |
|
|
| Report Abuse |
|
|
duckwit
|
  |
| Joined: 08 Aug 2008 |
| Total Posts: 1310 |
|
|
| 16 Jan 2014 07:54 AM |
@adark: "I'm decently sure that you can set a local variable inside the ModuleScript using a Setter function from something that utilises it." Could you explain this a little bit? I don't, as discussed above, notice any immediate advantage to ModuleScript's (as opposed to _G) other than the cross client/server usability.
I was hoping to be able to use code from a module like-so: --ModuleScript m = {} function m.Something() a = 2 end return m
--In Normal Script module = require(thatModule)
module.Something() print(a) --Output 2
xD
I'm making a gun system where the guns each share a lot of code between each other, but then differ slightly too, I wanted to fuse all the cross-over functionality into a module, but this is only possible if all the variables are accessible from both ends, which isn't the case.
So how can we effectively use them, besides the advantage described above? |
|
|
| Report Abuse |
|
|
adark
|
  |
| Joined: 13 Jan 2008 |
| Total Posts: 6412 |
|
|
| 16 Jan 2014 11:12 PM |
(Sorry for the late reply, didn't have a chance to get back to this for a good while.)
Basically this:
--Workspace.ModuleScript local privateVariable = 0
return { publicVariable = 0; setPrivate = function(num) privateVariable = num end; getPrivate = function() return privateVariable end; }
Now, when I require this ModuleScript, I cannot directly access privateVariable, but I should be able to set it using the provided setPrivate function, and get ts value using the getPrivate function. I would also need to sanitize 'num' so that I only get the data type I want, since Lua is weakly typed and won't error if I set 'num' to something crazy like an Instance. Also, I CAN directly set publicVarialbe. If what I am assuming is true, both of those variables are shared to all scripts that require() this ModuleScript. That is, editing either from one Script or LocalScript will edit what all the rest see. Take that with a grain of salt, though, since I can't test it yet.
Really, we had this type of functionality before, but it required directly using Bindable/Remote Events/Functions. setPrivate would be an *Event, and getPrivate would be a *Function. ModuleScripts do two things to improve on this, though: there's no need to create a cluttered mess of Bindable* or Remote* objects, even though the ModuleScripts probably use them internally, and ModuleScripts can be require()'d from both LocalScripts and normal Scripts. I'm not yet certain whether or not they are actually connected to the same source, but if they are it allows for another way to cross the Server-Client boundary.
Should my assumptions be wrong, you can just do this all using the Bindable* and Remote* objects.
As for your example specifically, this is the best way I can think of so far to accomplish what you want:
In the GunModule, make a public function called newGun, and a private table called GunTypes. Take parameters such as GunName, Damage, basically anything that differs between the gun types.
Now, when you call this function, have it create an entry in the GunTypes table (if it doesn't already exist), with all that data, and if any data is missing, fill in your defaults. (An easy way to be able to skip any data is to pass all of it in using an explicitly named table, that is: {name="Shotgun", capacity=5, reloadTime=10,}. Any data you want to be default, just don't set in that table.) (P.S., accessing a specific gun type later will be easier if you explicitly name the entries to GunTypes as the 'name' given. I.e: GunTypes = {Shotgun = {capacity=5, reloadTime=10, etc.})
Next, create a function named spawnGun, using the gun name as the only parameter. Create an Instance of this gun using the data in the GunTypes table, and return it.
Now, write in all the generic functions and data that every gun will use. Stuff like the actual bullet trajectory math.
In the Instanced gun, you'll also have to include a LocalScript for player input. When they click or hit a specified key, have it call the relevant function in the GunModule, passing in as an argument the instance of the gun you are calling the function for. From that Instance, you can get the gun type, and read its data from the GunTypes table. You can also accomplish this using a general GetMouse() input handler, without having to create an input script for every gun.
As you can probably tell, there are some nuances to using Modules. This stems from the fact that Modules are about half of what you need for OOP, allowing you to script the other half at need. |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 16 Jan 2014 11:24 PM |
| adark, can you get a ModuleScript's environment? |
|
|
| Report Abuse |
|
|
adark
|
  |
| Joined: 13 Jan 2008 |
| Total Posts: 6412 |
|
|
| 16 Jan 2014 11:30 PM |
| Definitely. What that would tell you, however, depends on whether or not my assumptions are correct. |
|
|
| Report Abuse |
|
|
duckwit
|
  |
| Joined: 08 Aug 2008 |
| Total Posts: 1310 |
|
| |
|
|
| 19 Jan 2014 12:29 AM |
Well, ModuleScript's aren't the only way to do OOP in Roblox? I'm pretty sure that it's possible to do the same using tables and metatables. Combine that with _G, and you should get the same effect (except ModuleScripts work on the client and the server).
Of course, ModuleScripts would be the better option to choose since it's a lot less complicated (and more effective, working on the client and server without doing anything extra).
You kept saying that it was just your assumption however. Did you manage to test it yet? :o |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 19 Jan 2014 12:33 AM |
| ModuleScript has really nothing to do with OOP |
|
|
| Report Abuse |
|
|
adark
|
  |
| Joined: 13 Jan 2008 |
| Total Posts: 6412 |
|
|
| 19 Jan 2014 12:35 AM |
Well, I can now, but I haven't done it yet.
Thanks for catching that, btw. It's basically my attempt to save face if I end up being totally wrong, or even partially.
OOP in Lua is ridiculous (check out the MoonScript implementation), and this still technically isn't OOP, just better cross-script communication, and a *very* useful efficiency thing in terms of only one Object *and* only one instance of code running at once *AND* only specific sections of code being 'publicly' accessible. Using any other method, at least one of those is not true.
The most recent way was using Remote* or Bindable* objects, but ModuleScripts kill two birds with one stone there, although they might use those objects internally, in which case the benefit of using them instead of Bindable*s/Remote*s is moot. |
|
|
| Report Abuse |
|
|