Script Module Guidelines discussion

Started by RickJ, Wed 02/02/2005 03:01:21

Previous topic - Next topic

Scorpiorus

Documentation

Quote from: RickJAny of the following variations of "Reference" are acceptable and probably the best one is your suggestion of "IniFile Reference", where IniFile is the module name of course.
Ok, it's almost resolved here. Whatever it will be named but it's only a single section name to think of, that's relieving.

QuoteOn another note, Nethros has argeed to help us in this project.
Cool! It's nice to see new participants being interested. :)

QuoteScrop, do you know of any HTML docs similar to what we are proposing that we can use as a starting point or example of the kinds of things that will be required?
Not quite, at the moment, but I'll see if I can find something relevant.


Programming Conventions

Quote from: RickJNo,Ã,  no, no.Ã,  I was making a joke with the language.Ã,  Sorry if the humor didn't translate well.Ã,  I didn't mean to imply anything about macro naming or anything.Ã,  I just thought it ironic and funny that the mis-spelling made me think of the word "muddle" in the context of the discussion.Ã,  I just thought to share my amusement with you.
Hehe, no I certainly got the joke but, the funny thing is, it also incited me to re-think the issue and finally to come up the IniFile_VERSION-as-a-name thingy that I should have thought of in the first place actually. :)

QuoteWhat would you think of just using a shorter version of the name like IniFile_V100. And is there a need to have one that tells what the latest version is? For example "#define IniFile_V000 IniFile_V201", where IniFile_V000Ã,  asways has the latest version.
QuoteAnd just to be sure I understand.... All modules would contain definitons of current and all previous release versions of the module.Ã,  Dependent modules check for the lowest acceptable versions of required modules.Ã,  Is this correct?
Yeah, I thought about having a shorter name but here is what urged me to suggest the original convention:

Suppose, we're making a new module, thus it must have a version, so we define a macro in our module's header (taking IniFile as module name):

#define IniFile_VERSION 100

The neatest thing, this macro's name entirely meets the macro naming convention for modules we were discussing (i.e. IniFile_ is a mix-cased prefix). So, what we can state in the conventions document is that each module *must* have a version macro defined in the very same way. This macro is to be checked by other dependent modules and thereby it can be determined whether the required module exists and its exposed functionality can be used. This macro is also stores the module's current version which can be checked at run-time if necessary (IniFile_V000's analog).

Unfortunetly, the value of version macro can't be used at compile time, therefore there is a necessary to introduced other macros as well:

#define IniFile_VERSIONÃ,  200

#define IniFile_VERSION_200
#define IniFile_VERSION_150
#define IniFile_VERSION_102
#define IniFile_VERSION_101
#define IniFile_VERSION_100

Yes, the module must have all of them. Module developer is just supposed to add a new version name (as well as to change IniFile_VERSION value) each time a new version of a module is released. I named them mainly after the original macro (to be consistent) but having shorter names instead is also a possibility.

What I really hope for, is that these macros are temporary. If in a future version of AGS it were possible to check conditions while pre-processing then these additional macros would become obsolete but the scheme would still work:

Thus older dependent modules would check required modules as:

// if module version is not even defined (word for word btw :) )
#ifndef IniFile_VERSION
#error Can't find the required IniFile module!
#endif

// if the module is here but the version is too old:
#ifndef IniFile_VERSION_102
#error IniFile version 1.02 or higher required!
#ifndef


The newer ones would do:

// if module version is not even defined:
#ifndef IniFile_VERSION
#error Can't find the required IniFile module!
#endif

// if the module is here but the version is too old:
#if IniFile_VERSION < 102
#error IniFile version 1.02 or higher required!
#ifndef

No need for IniFile_VERSION_102, etc. this way.

By the way, it should be noted that in any case a new version of a module should also support functionalities of previous versions as well, i.e. the exposed but obsolete functionality should not be removed in order to ensure all dependent modules would work correctly. Such functionality can however be hidden from the autocomplete feature so that the chance it will be used in future would be minimal.
This would make modules backward compatible.

And to be honest :) the more I think about it the more it seems to me that such dependence checking is to be better supported natively by the editor because it could then also sort the modules list as necessary. I can already foresee difficulties with arranging them manually in case of a large number of dependent modules.


QuoteShould the file names carry the version number as well?Ã,  I was planning on this for the zip file but perhaps the other files should be named this way as well (i.e. IniFile_V100.scm).
It's ok with me, I too like naming them like that. Maybe it should be left up to the author, not certain here.
By the way, AFAIK it is not possible to have two versions of the same module in the module list. When a new module is created it's also assigned a key ID that makes it be unique. If the module with the same key as a module to import is already in the list the editor won't allow importing a new one. It is not therefore, by the by, a good idea to release a brand new module by replacing the source code of the existing one and then exporting it. Those two modules would collide if imported into the same project. So a new module, the "New..." button! Moreover, it means we can't have some kind of a module template by just exporting a dummy one but with examples of version or/and dependencies macros/checkings inside.

QuoteUsing the same name for the file and the macro is appealing to me for some reason
Oh, hehe that's probably another good reason for using shorter version names.

Quote from: RickJ
Quote from: ScorpiorusI believe there should be no problems with that as static and global functions are basically the same. It's a pity we can't have static member variables, yeah.
Hmmm, I thought of this work around... I am not sure if this actually works or if it's something we should suggest as it's a bit convoluted.Ã,  Ã, What do you think?
Yeah why not, nice trick! As long as there is no need to also create other instances of "IniFile" (i.e. there is no IniFile struct).
This can actually be not revealed to the module user or, on the countrary, clearly said that there is a single exposed IniFile instance to access module's functionality. So, I think, it's up to the developer as the module name can really be used as one likes, I think. ;)


Quote from: SSHWell, for exmaple, I'll have a module that uses a GUE as well, so the module dependecies will reflect that, and the GUE shoudl also have some comment in to mention the module, but since the GUE wont really have a lot of script (I'm guessing that it includes only GUI on_click and handler functions)Ã,  those will have to go INSIDE one/all of the functions.
Quote from: RickJSo I guess you would check for a macro definition in one of the handler functions.Ã, 
Probably it wouldn't need to be done in all of them since you would only need to generate one error.
Yeah, if a certain GUI is connected with the module (calls into it) the module presence can be checked within one of the GUI functions, I believe (it doesn't matter which one as long as its code is transported along with the exported GUI) or maybe even outside the function but inside #section* block (didn't test that though):

#sectionstart gSave_Click
// <--maybe placing it here is also ok (assuming it will be exported that way)
function gSave_Click(GUI *theGui, MouseButton button) {

#ifndef ImportantGUIModule_VERSION
#error Can't find the necessary ImportantGUIModule module!
#endif

}
#sectionend gSave_Click


On the other hand, if a module needs to know whether a GUI exists it can look for its original name:

module script:

#ifndef STATUSLINE
#error Can't find the STATUSLINE GUI!
#endif

Which also as well brings us back to the naming conventions, GUIs now... :P

Pumaman

#21
Quote from: Scorpiorus on Thu 17/02/2005 18:47:10
And to be honest :) the more I think about it the more it seems to me that such dependence checking is to be better supported natively by the editor because it could then also sort the modules list as necessary. I can already foresee difficulties with arranging them manually in case of a large number of dependent modules.

If it becomes a problem, then some sort of native dependency support would be a good idea. However, I don't forsee there being lots of modules with dependencies since as I see it modules will generally be contained as a unit and not rely on external things.

RickJ

Documentation
Quote from: Scorpiorus
Quote from: RickJAny of the following variations of "Reference" are acceptable and probably the best one is your suggestion of "IniFile Reference", where IniFile is the module name of course.
Ok, it's almost resolved here. Whatever it will be named but it's only a single section name to think of, that's relieving.
Agree.  have you ever heard the phrase "It's close enough for goverment work!"  ;D

Quote from: Scorpiorus
QuoteScrop, do you know of any HTML docs similar to what we are proposing that we can use as a starting point or example of the kinds of things that will be required?
Not quite, at the moment, but I'll see if I can find something relevant.
I surfed around last night for examples of API type documents and how they show function proto-types, code examples, etc.   Since we pretty much settled on the organization, we only need some examples of how different kinds of things can be presented just to get a discussion started.  Maybe SSH has knows of some examples. 

Programming Conventions
Quote from: Scorpiorus
Quote from: RickJNo,  no, no.  I was making a joke with the language.  Sorry if the humor didn't translate well.  I didn't mean to imply anything about macro naming or anything.  I just thought it ironic and funny that the mis-spelling made me think of the word "muddle" in the context of the discussion.  I just thought to share my amusement with you.
Hehe, no I certainly got the joke but, the funny thing is, it also incited me to re-think the issue and finally to come up the IniFile_VERSION-as-a-name thingy that I should have thought of in the first place actually. :)
Hehe, funny how things work out sometimes.  After reading your other comments on the subject I like the IniFile_VERSION scheme very much.   The longer macro names (i.e. IniFile_VERSION_100, etc) also make more sense to me now as well.  So I am persuaded that we should go with this.   

Quote from: Scorpiorus
What I really hope for, is that these macros are temporary. If in a future version of AGS it were possible to check conditions while pre-processing then these additional macros would become obsolete but the scheme would still work:

// if the module is here but the version is too old:
#if IniFile_VERSION < 102
#error IniFile version 1.02 or higher required!
#ifndef
Yeah, that would be a really cool way of handling it.   

Quote from: Scorpiorus
By the way, it should be noted that in any case a new version of a module should also support functionalities of previous versions as well, i.e. the exposed but obsolete functionality should not be removed in order to ensure all dependent modules would work correctly. Such functionality can however be hidden from the autocomplete feature so that the chance it will be used in future would be minimal.
This would make modules backward compatible.
Very true.  We need to remember to make this clear in any guidelines we make.

Quote from: Scorpiorus
And to be honest :) the more I think about it the more it seems to me that such dependence checking is to be better supported natively by the editor because it could then also sort the modules list as necessary. I can already foresee difficulties with arranging them manually in case of a large number of dependent modules.
I agree, but I don't think that will happen this go around though.  I wish we were able to read and write the fields in the Module Manager as well.   Then I could make sure the version number there matched what's in the header etc. 

Quote from: Scorpiorus
QuoteShould the file names carry the version number as well?  I was planning on this for the zip file but perhaps the other files should be named this way as well (i.e. IniFile_V100.scm).
It's ok with me, I too like naming them like that. Maybe it should be left up to the author, not certain here.
I'm thinking to auto-generate the zip file name from the module name and version via some kind of "Release Module" command, which would make the zip file in a specified folder. 

Quote from: Scorpiorus
By the way, AFAIK it is not possible to have two versions of the same module in the module list. When a new module is created it's also assigned a key ID that makes it be unique. If the module with the same key as a module to import is already in the list the editor won't allow importing a new one. It is not therefore, by the by, a good idea to release a brand new module by replacing the source code of the existing one and then exporting it. Those two modules would collide if imported into the same project. So a new module, the "New..." button! Moreover, it means we can't have some kind of a module template by just exporting a dummy one but with examples of version or/and dependencies macros/checkings inside.
Wow!  I didn't know about the unique ID thingy, that's very interesting.   

I asked CJ about the possibility of having a default module and room templates.  He said that there is already this possibility with rooms. You put something like _blank.crm in the game folder and "New Room" uses this file as a template.  He didn't say if or when he would do the same for modules.  At the time I assumed that he would do so eventually, however, in light of what we are doing I think it would be a good idea to specifically request it. What do you think?

Quote from: Scorpiorus
QuoteUsing the same name for the file and the macro is appealing to me for some reason
Oh, hehe that's probably another good reason for using shorter version names.
Except that you have already persuaded me that the longer macro names are better.  ::)  Appealing as it is, I haven't made as good a case for it as you have for the longer names.   However file names can still include the version number like this IniFile_V200.zip.

Quote from: ScorpiorusYeah why not, nice trick! As long as there is no need to also create other instances of "IniFile" (i.e. there is no IniFile struct).
This can actually be not revealed to the module user or, on the countrary, clearly said that there is a single exposed IniFile instance to access module's functionality. So, I think, it's up to the developer as the module name can really be used as one likes, I think. ;)
Oh yeah, now I see the flaw.  There is the possibility of name collsions, so I think this is not such a good idea, just using norma global variables are  probably a better idea.   In cases where there is a one on one correspondance between the module and the primary struct (i.e. OO object), I would prefer having the possibity of giving the same name as the struct as I have done in the actual IniFile module.  IMHO, this is more intuitive than giving some other name to the struct.  For this reason I would reject my own idea.  Thanks for enlightening me. :P

Quote from: Scorpiorus
... Which also as well brings us back to the naming conventions, GUIs now... :P
:)

Scorpiorus

Quote from: PumamanIf it becomes a problem, then some sort of native dependency support would be a good idea. However, I don't forsee there being lots of modules with dependencies since as I see it modules will generally be contained as a unit and not rely on external things.
Yeah, I'm not certain how things will go but I agree it obviously isn't a high priority feature for now. Sorry if it sounded like an instant request, I didn't want to even mention it at first, but eventually couldn't resist. :)

Quote from: RickJAgree.Ã,  have you ever heard the phrase "It's close enough for goverment work!"
Quote from: RickJ on Thu 17/02/2005 20:28:37
Quote... Which also as well brings us back to the naming conventions, GUIs now...
:)
Yeah you mean like it's as usual "close enough"? :=


Programming Conventions

QuoteAfter reading your other comments on the subject I like the IniFile_VERSION scheme very much.Ã,  Ã, The longer macro names (i.e. IniFile_VERSION_100, etc) also make more sense to me now as well.Ã,  So I am persuaded that we should go with this.
I'm glad you liked it! Still, the case hasn't been closed so if anyone have any toughts on how this approach can be improved/enhanced, please let us know.


QuoteI agree, but I don't think that will happen this go around though.Ã,  I wish we were able to read and write the fields in the Module Manager as well.Ã,  Ã, Then I could make sure the version number there matched what's in the header etc.
Hehe, what we should only worry about is to bring anyone who follows the guidelines to remember to update the module's version info as well as the version macros themselves, that's for sure. I appreciate one may wish it to be semi-automatic at least but currently there are three steps to pass -- add a new macro, change other macro value and finally don't forget to reflect the version number in the appropriate property to be displayed next to the module name.

QuoteHe didn't say if or when he would do the same for modules.Ã,  At the time I assumed that he would do so eventually, however, in light of what we are doing I think it would be a good idea to specifically request it. What do you think?
Having some sort of a module template would be nice, I agree yeah. Implementing it, again, depends on how badly it is needed for the moment, I guess.

QuoteExcept that you have already persuaded me that the longer macro names are better.
Hehe, but I didn't know for sure if I would do.Ã,  :=

QuoteHowever file names can still include the version number like this IniFile_V200.zip.
Yeah, I'm all for it too.

QuoteOh yeah, now I see the flaw.Ã,  There is the possibility of name collsions, so I think this is not such a good idea, just using norma global variables areÃ,  probably a better idea.
I think sometimes it may be useful. Yep, it's mostly when there is no a struct supposed to be, so it can then be used for grouping both the global functions and variables as you described.

RickJ

#24
Quote from: Scorpiorus
Quote from: PumamanIf it becomes a problem, then some sort of native dependency support would be a good idea. However, I don't forsee there being lots of modules with dependencies since as I see it modules will generally be contained as a unit and not rely on external things.
Yeah, I'm not certain how things will go but I agree it obviously isn't a high priority feature for now. Sorry if it sounded like an instant request, I didn't want to even mention it at first, but eventually couldn't resist. :)
We're thrilled to have a module mechanism and trying to be thorough in our review.   Likely we will end up at the end of this process with a wish list containing items like this.   You rightly point out, that it will become appparent, in due time, which, if any of these are meritorious.   

Quote from: Scorpiorus
Quote from: RickJAgree.  have you ever heard the phrase "It's close enough for goverment work!"
Quote from: RickJ on Thu 17/02/2005 20:28:37
Quote... Which also as well brings us back to the naming conventions, GUIs now...
:)
Yeah you mean like it's as usual "close enough"? :=
Yeah, that's pretty close to the meaning.  ;)   Goverments always spend too much money for everything and usually don't care much about the quality. 

Programming Conventions
Quote from: Scorpiorus
QuoteAfter reading your other comments on the subject I like the IniFile_VERSION scheme very much.   The longer macro names (i.e. IniFile_VERSION_100, etc) also make more sense to me now as well.  So I am persuaded that we should go with this.
I'm glad you liked it! Still, the case hasn't been closed so if anyone have any toughts on how this approach can be improved/enhanced, please let us know.
I shall also  listen...

Quote from: Scorpiorus
QuoteI agree, but I don't think that will happen this go around though.  I wish we were able to read and write the fields in the Module Manager as well.   Then I could make sure the version number there matched what's in the header etc.
Hehe, what we should only worry about is to bring anyone who follows the guidelines to remember to update the module's version info as well as the version macros themselves, that's for sure. I appreciate one may wish it to be semi-automatic at least but currently there are three steps to pass -- add a new macro, change other macro value and finally don't forget to reflect the version number in the appropriate property to be displayed next to the module name.
Actually, I think I can get the Module Manager's version number out of the SCM file, while extracting the documentation.  I could then,  perhaps verify that all three steps have been done correctly?

Quote from: Scorpiorus
QuoteHe didn't say if or when he would do the same for modules.  At the time I assumed that he would do so eventually, however, in light of what we are doing I think it would be a good idea to specifically request it. What do you think?
Having some sort of a module template would be nice, I agree yeah. Implementing it, again, depends on how badly it is needed for the moment, I guess.
I think put this on our wish list and at the end we can maybe llist them in orfer of importance as is our opinion and then let nature take it's course. :)

Quote from: Scorpiorus
QuoteExcept that you have already persuaded me that the longer macro names are better.
Hehe, but I didn't know for sure if I would do.  :=
Hehe... this could get circular :D

Quote from: Scorpiorus
QuoteHowever file names can still include the version number like this IniFile_V200.zip.
Yeah, I'm all for it too.
Cool  8)

Quote from: Scorpiorus
QuoteOh yeah, now I see the flaw.  There is the possibility of name collsions, so I think this is not such a good idea, just using normal global variables are  probably a better idea.
I think sometimes it may be useful. Yep, it's mostly when there is no a struct supposed to be, so it can then be used for grouping both the global functions and variables as you described.
I think your approach, using static functions and global variables is a better solution.  For example in the actual IniFile module I use IniFile as the main struct name.  I could still add static functions as you suggest without any problems.  With my suggestion I would run into a naming problem, in that I coldn't use IniFile for both the struct name and the instance of the struct.   So, Yeah some could do what I suggest if they had a really good reason, but  otherwise they would be better using static functions.   Maybe we put a request for static variables in the wish list also.
======

Ok!  It looks like we have settled many issues.  I'm sure others will come up soon enough.   Back to work now...

Scorpiorus

#25
Quote from: RickJ on Sat 19/02/2005 07:54:35Actually, I think I can get the Module Manager's version number out of the SCM file, while extracting the documentation.  I could then,  perhaps verify that all three steps have been done correctly?
Ah, yeah that would be great!

QuoteI think put this on our wish list and at the end we can maybe llist them in orfer of importance as is our opinion and then let nature take it's course. :)
Good idea, it will then be evident what is really needed.

QuoteSo, Yeah some could do what I suggest if they had a really good reason, but  otherwise they would be better using static functions.
Yep, in case they are writing some kind of a library-module (i.e. just a set of related functions and possibly global vars) and thus can use an instance to group all of them together.

QuoteMaybe we put a request for static variables in the wish list also.
Ok with me ;D

QuoteBack to work now...
By the way, what minimum length should a module name have? I appreciate the shorter the name the greater the possiblity of name collisions. Longer names, on the other hand, could clutter the source code, especially if a module has several exposed structs.

struct ModuleName_StructName {
...
};

But then again, such names would mainly be used to declare variables (so the length doesn't really matter here) and we also have the great autocomplete feature.

So the question is, how short a module name can be?

RickJ

Quote
By the way, what minimum length should a module name have? I appreciate the shorter the name the greater the possiblity of name collisions. Longer names, on the other hand, could clutter the source code, especially if a module has several exposed structs.
That's a tough question  ::).  I'm certain that there at least a half dozen opinions on the subject  ;).  However, I guess I would say at least "2 or 3" should be required and probably something like "7 or more" should be the recommendation.   I can see using the shorter names for library type things. 

============
For anyone interested here is a link to a pre-alpha version of the document generator.  Currently it reads the first 100 lines from the IniFile.s file, analyses the line's content and displayss the results in the left hand column of the screen.   The actual line that was read is displayed at the top of the screen.  The document is displayed under the current line as it is being read.   

ScriptDoc_V001A01.zip

The design goal of the parser was to make it very modular so consequently some of the processing is duplicative. I believe this will not be a problem because the file size of the documents are relatively small. 

No I can start working on doing the document output.  This should be a bit more fun and a little less tedious than the parser.   I am thinking of using a config file to define how and what to extract from the input file.  This would allow us to use it for other purposes.  I'll see how it goes and if it's practical. 

Oh well, feel free to let me know what you think.   Cheers!!!


Scorpiorus

Good work with the parser, Rick! :)

Quote from: RickJI am thinking of using a config file to define how and what to extract from the input file.
Would be handy, yeah. Especially considering that we are not yet decided what exactly would be extracted etc. Having some versatility would never hurt.

Quote from: RickJHowever, I guess I would say at least "2 or 3" should be required and probably something like "7 or more" should be the recommendation.
Yeah agree, maybe 3 at least, because that's the number of characters one types-in in order for the autocomplete list to pop up.

SSH

Sorry to drag up an old-ish topic, but did you guys reach a conclusion here, and any chance of writing it up in a printable format?
12

RickJ

SSH, thanks for bumping the thread.  Yeah, I think we reached a concensus of opinions.  Scrop said he would write up something about the "#define Version" stuff.  I plan on writing up something on naming conventions etc.   I have had to take a temporary break from this to  get DemoQuest in shape for the new AGS releasel.   Do you have an immediate need or is this more of a general inquiry?  If there is anything I can help you with please just let me know. 

Cheers 

SSH

Well, I think it would be a good idea to have it written up by the time that AGS 2.7 is released, which may be April 1st.... with the new shareware licence ;)

I dunno if CJ would consider distirbuting the guidelines with the release?

Also, once 2.7 is out, I want ot do a proper release of my savegame with screenshots module and GUE.
12

RickJ

#31
SSH,

Here is a first draft of a document that drescribes what I believe was the concensus of the discussion in this thread.  If something needs to be changed or added please let me know.


strazer

Nice work!

1.) Shouldn't #defines, static variables and utility functions in the module script also be prefixed with the module name as not to collide with anything the game author may have set up in the global script header?

Btw, I like "Internal functions" better than "Utility functions".

2.) If only a specific function depends on another module, we should suggest to use
  #ifndef YourModule_VERSION
    AbortGame("Can't find required module 'YourModule'!");
  #endif

And few spelling errors:

Quotestatic
member functions are recognized but the auto-complete feature of the
Script Editor.

Quote
   // Note: String variables are ->NOT<- permitted inside a
   // struct.  Use a char array instead.

Quoteoutside the bounds of any fucntion

Quotegive credit where credit is do.

Quote"Derrived from IniFile by RickJ"

Quotecopiler errprs

Quoteapporpiate error message

RickJ

Quote from: strazer
1.) Shouldn't #defines, static variables and utility functions in the module script also be prefixed with the module name as not to collide with anything the game author may have set up in the global script header?
I don't believe the Global Script Header is included into Module Script, only the Module Header. 

Quote from: strazer
Btw, I like "Internal functions" better than "Utility functions".
I suppose there could be a whole discussion about both terms "Utility" and "Application" to possibly come up with better names.   I choose to apply "Utility" to the functions that do all the dirty work and "Application" to the functions that provide a clean interface to some high level functionality.   In my mind "Internal" seems to apply equally to both. 

Does anyone else have opinions about this?


Quote from: strazer
2.) If only a specific function depends on another module, we should suggest to use
  #ifndef YourModule_VERSION
    AbortGame("Can't find required module 'YourModule'!");
  #endif
The #ifndef, #endif, #error,  ect.. are directives that are only executed at compile time.   AbortGame() is a function called at runtime.  The #error directive does more or less the samething as AbortGame() but at compile time instead of at runtime.   Having said that, a variation of your idea would make it possible to use only one macro definition to manage dependancies. 

You would check for the existence of the module in the Module Header as Scorp suggested.  If YourModule is not imported into AGS prior to MyModue being imported into AGS then an error is generate by the compiler.  So far this is what is currently suggested. 

Now to check the version of YourModule, this could be done at runtime, as you suggest Strazer, instead of doing it at compile time as Scrop suggests.  The advantage of doing it at runtime is that only one macro will be required;  there is always a possibility of someone deleting those additional version macros from some future version of the module and breaking other modules.   The disadvantage is, ofcourse, that the error won't be detected until runtime.   Here is an example of what I am talking about.
// YourModule Module Header
#define YourModule_VERSION 200 

// MyModule Module Header
#ifndef YourModule_VERSION
#error *** Error-MyModule, can't find required module 'YourModule'!
#endif

// MyModule Module Script
function start_game() {

   // Check module dependancies
   if (YourModule_VERSION<150) {
      AbortGame("*** Error-MyModule, version YourModule V1.50 or greater required");
   }
}

Any comments about this ?  SCROP, SSH, etc...

Quote from: strazer
Quotecopiler errprs
Hehe!  ;D  I find that one funny.   ALso, why do we call them "compiler errors" when in fact it was the programmer who made the error and not the compiler?  Perhaps from now on they should be refered to a s"programmer errors"?    :P

In any case thanks for checking my spelling.  I'll get right on it and correct those "author errors".

==================

Also, I would like to add you guys to the credits of this document as it is just a summary of our discussion here.  So if you would like me to do so please PM me your  frist, last, and forum name so that I can add it to the document.   

Cheers


strazer

#34
Quote from: RickJ on Sat 26/03/2005 02:17:40
I don't believe the Global Script Header is included into Module Script, only the Module Header. 

Hey, you're right. Good to know. I assumed it is.

Quote from: RickJ on Sat 26/03/2005 02:17:40In my mind "Internal" seems to apply equally to both. 

You have a point. Still, I think the difference between "Internal functions" and "User functions" is more obvious.

Quote from: RickJ on Sat 26/03/2005 02:17:40
The #error directive does more or less the samething as AbortGame() but at compile time instead of at runtime.

I know. What I mean is, if only one function of your module depends on another module, but this function is not even used by the game author, IMO the dependency shouldn't be enforced.
Instead, you could do:

Code: ags

static function MyModule::DoSomeStuff() {

  #ifndef MODULE_YOURMODULE
    AbortGame("This function depends on 'YourModule'!");
  #endif

  // (the stuff)

}


The game author will know that he has to import another module the moment he tries to use the function.

Edit:

Quote#error *** Err-MyModule, can't find required module "YourModule"!

"Err-MyModule" isn't needed as the AGS error message displays the module name where the error was raised.

Edit 2:

QuoteAt the time of this writing, it is not clear to the author what scope or other charactistics enums defined in the Module Script have

Good question.

Scorpiorus

#35
Digging it up...

Quote from: SSH on Wed 23/03/2005 14:53:57
Sorry to drag up an old-ish topic, but did you guys reach a conclusion here, and any chance of writing it up in a printable format?
Quote from: RickJ on Wed 23/03/2005 16:33:54
SSH, thanks for bumping the thread.  Yeah, I think we reached a concensus of opinions.  Scrop said he would write up something about the "#define Version" stuff.  I plan on writing up something on naming conventions etc
I did start making a doc about module dependencies but got wiped it all out as my hard drive crashed. It took pretty much time to set the system up again and finally be online. Fortunately, this thread contains all the info regarding dependencies stuff so I think it won't be a big problem to rewrite from scratch. :)

Quote from: strazer on Sat 26/03/2005 00:44:18Shouldn't #defines, static variables and utility functions in the module script also be prefixed with the module name as not to collide with anything the game author may have set up in the global script header?
Yeah, as Rick has already said the global script header is not attached to the script of a module, thus everything that's declared within the module's script and is not exposed via its header is not seen from within any other scripts. Here is a post I made after investigating the mechanism: http://www.adventuregamestudio.co.uk/yabb/index.php?topic=19369.msg230174#msg230174

Quote from: strazer on Sat 26/03/2005 02:40:37
Quote from: RickJ on Sat 26/03/2005 02:17:40In my mind "Internal" seems to apply equally to both. 

You have a point. Still, I think the difference between "Internal functions" and "User functions" is more obvious.
I like "internal functions". It, indeed, may also be internal functions and user functions or possibly internal functions and interface functions. As a module user I'd probably want them to be refered as user functions, ex: "This module provides you with the following user functions..." or "the following user functions are available".

Quote from: strazer on Sat 26/03/2005 02:40:37
Quote from: RickJ on Sat 26/03/2005 02:17:40
The #error directive does more or less the samething as AbortGame() but at compile time instead of at runtime.

I know. What I mean is, if only one function of your module depends on another module, but this function is not even used by the game author, IMO the dependency shouldn't be enforced.
Instead, you could do:

Code: ags

static function MyModule::DoSomeStuff() {

  #ifndef MODULE_YOURMODULE
    AbortGame("This function depends on 'YourModule'!");
  #endif

  // (the stuff)

}
The main problem with having any run-time modules dependency error messages is that it's not actually possible to make a game run (and thus see the message) until you get rid of every single line which calls into the module we depend on. That's why #error directive comes in handy, it reports at compile time instead.

The code in question will not compile if the MyModule::DoSomeStuff function has any calls (and it has, since it depends) into YourModule, we just get undefined token error.

We could of course omit this module check and just let the compiler to report about the undefined token but this will likely confuse a user since (s)he wouldn't have an info regarding what module (and what its version) (s)he is required to install.

As for where to put such dependency checks, a general rule would be - before the first client module's line which code invokes any function of a servicing module.

If it's a single function that depends on a module than, yep, just put a check within this function but before any implementation code:

Code: ags
static function MyModule::DoSomeStuff() {

  #ifndef YourModule_VERSION
      #error This function depends on 'YourModule'!
  #endif

  YourModule_SomeUserFunction(); // calling YourModule function

}


But I appreciate that sometimes there could be some tricky ways of handling dependency issues when we woud like to replace missing functionality with our own implementation if the required module isn't there, or call AbortGame function as a special case. Then we'd need to wrap all the code with #if-#endif:

Code: ags
static function MyModule::DoSomeStuff() {

  #ifndef MODULE_YOURMODULE
       AbortGame("This function depends on 'YourModule'!");
  #endif
  #ifdef MODULE_YOURMODULE
       YourModule_SomeUserFunction(); 
  #endif
}



As for dependent modules, we could put checks within their headers just in case these headers use some of declarations made in servicing modules.

EDIT:

Quote from: strazer on Sat 26/03/2005 02:40:37
QuoteAt the time of this writing, it is not clear to the author what scope or other charactistics enums defined in the Module Script have

Good question.
If I get it right, all the enums defined in the module script are local to the module itself (just like any struct defined within it) so we shouldn't worry about it. Their names must of course differ from AGS internal enums as all scripts (module, global, room) are preceded by what I'd call the internal script header where all game structs and functions are defined (Character, Object, Enums, etc.).

RickJ

#36
Quote
did start making a doc about module dependencies but got wiped it all out as my hard drive crashed. It took pretty much time to set the system up again and finally be online. Fortunately, this thread contains all the info regarding dependencies stuff so I think it won't be a big problem to rewrite from scratch.

Scorp,   While you were gone SSH asked me what conconlsions we had reached so I had a go at making the document which includes a section about the dependancies. So instead of starting from scratch perhaps you could review what I have already done and make any changes you think are appropriate.  Here are the three documents I gave to SSH.


Scorpiorus

Thanks Rick, the links didn't work the time I was replying but thanks for bumping it up -- I've now read the latest version of the document.

Dependencies section looks good, states everything we were talking about. But what do you think of adding a convention to check if module with the same name already exists? That is:

#ifdef MyModule_VERSION
#error Error: module with the same name already on the list!
#endif

// Version Macro Definitions
#define MyModule_VERSION 200
#define MyModule_VERSION_200
#define MyModule_VERSION_150
#define MyModule_VERSION_102
#define MyModule_VERSION_101
#define MyModule_VERSION_100

It's just in case two or more module authors would make script modules with identical names, independently of each other.


Also, what if there would be a demo script module? It would basically be a simple working module (eg: math functions) that just shows all the conventions in work. The key point is to make it very simple but still demonstrating every single rule (notations, etc.).

RickJ

#38
Quote from: Scorpiorus
But what do you think of adding a convention to check if module with the same name already exists?
If a game contains MyModule you can't import another module named MyModule.  If this is what you mean then I think it is already prevented.

Quote from: Scorpiorus
Also, what if there would be a demo script module? It would basically be a simple working module (eg: math functions) that just shows all the conventions in work. The key point is to make it very simple but still demonstrating every single rule (notations, etc.).
I like that idea very much.  That was my motivation in making the template files.  I think having an example to go along with them would be a very good idea.   

Perhaps this example should be in the form of  a AGS Game Template (*.agt)  that would contain two modules  ExampleModule containg the example you suggest and NewModule containing empty templates.  This way if someone wanted to make a new module they could use this template to create a new game.  The could rename NewModule to whatever they wanted and start coding.  They could look at ExampleModule whenever they wanted to see how to do things. 

We could also add functionality to the game proper to help in the test process.  There could be GUI's, test room, etc to aid in development.

=====
Btw, I was reviewing the thread and was wondering about the issues SSH brings up.   When he orignally posted I wasn't up to speed on the GUI stuff and overwhelmed with the DQ update.   Would you mind taking a look at his suggestions and let me know what you think.   One of the things he mentions is using the prefix "go" for all of his gui objects.   In DemoQuest I just used the gui name to prefix the objects it contains.  I didn't realize until now that this is one of the things SSH was asking about and had previoously made suggestions.     

In any case this is probably a good time to have a discussion about this.  If we reach a conclusion I can go back and modify DemoQUest to conform to whatever we decide before it is released.



Scorpiorus

Quote from: RickJIf a game contains MyModule you can't import another module named MyModule.Ã,  If this is what you mean then I think it is already prevented.
Yeah, however there is a particular case when two modules can have identical Name_VERSION macros but different names (those appear in the module manager list) and keys.
At present, conventions document states that a module name from the manager list should be in Camel Notation and thus, if I get it right, also be identical to the prefix of the version macro. It is not required to do any extra checks if it's the case but on the other hand I'm not sure if we should restrict module's full name to Camel Notaion. Because the name edit box in the module manager actually allows any string as a module name and, for example, an extra space character could break the rule. And I believe it is meant to be a full name, not just abbreviation. It is becoming important when a prefix is an abbreviation or acronym of the module's name. For example, one would like to name a module "NewObjectFunctions" but have "NOF" as a profix; or have "Math" or "MFL" for "Math Functions Library".
Suppose in a future, AGS will have functionality of handling module dependencies. There will then be a need to introduce another type of module name, the one that we currently use to prefix exposed functions, types, defines and variables. Then the current module name in the manager would be a full name of a module while the new name would be a unique identifier of the module. Just like characters have names and script names. What do you think?

QuotePerhaps this example should be in the form ofÃ,  a AGS Game Template (*.agt)Ã,  that would contain two modulesÃ,  ExampleModule containg the example you suggest and NewModule containing empty templates.
Yeah, agreed. With that ExampleModule one could browse it while reading the conventions document. Module templates, on the other hand, are to be used by someone to actually start off developing their own script modules.

QuoteWe could also add functionality to the game proper to help in the test process.Ã,  There could be GUI's, test room, etc to aid in development.
Do you mean some stuff to debug the user code?

QuoteBtw, I was reviewing the thread and was wondering about the issues SSH brings up.Ã,  Ã, When he orignally posted I wasn't up to speed on the GUI stuff and overwhelmed with the DQ update.Ã,  Ã, Would you mind taking a look at his suggestions and let me know what you think.Ã,  Ã, One of the things he mentions is using the prefix "go" for all of his gui objects.Ã,  Ã, In DemoQuest I just used the gui name to prefix the objects it contains.Ã,  I didn't realize until now that this is one of the things SSH was asking about and had previoously made suggestions.
Yeah, I too browsed it again and indeed the doc doesn't mention anything concerning GUIs. I'm for using a GUI name to prefix its objects(controls) names since just like with module functions and variables GUI controls are contained within a GUI, eg: GUI5_Button3, GUI5_Button3_Click.
But whether GUIs should be prefixed - is still a question.
If it's a specific module GUI I'd use a module name to prefix it:
MyModule_MyGUI
MyModule_MyGUI_Button1
MyModule_MyGUI_Button1_Click

What do you think about the problem?

SMF spam blocked by CleanTalk