1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. Ride into the sunset with the 32nd Modeling Contest. The contest is optionally paired. Best of luck, people!
    Dismiss Notice
  4. This adventure has come to an end. Congratulate our heroes in the 16th Mini Mapping Contest Results.
    Dismiss Notice
  5. From the gates of hell, the 5th Special Effect Contest Results have emerged.
    Dismiss Notice
  6. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  7. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

JPAG - JASS Proper Application Guide

Discussion in 'JASS/AI Scripts Tutorials' started by Bribe, Sep 27, 2011.

  1. ShadowFlare

    ShadowFlare

    Joined:
    Jun 30, 2008
    Messages:
    552
    Resources:
    0
    Resources:
    0
    Agreed, ugly they will always be. But here is another example:

    Code (vJASS):
                loop
                exitwhen a > slength
                    loop
                    exitwhen b > NA
                        if (SubString(GetEventPlayerChatString(), a-1, a) == NOTALLOWED[b]) then
                            set accepted = false
                        endif
                    set b = b+1
                    endloop
                    set b = 0
                    loop
                    exitwhen c > MC
                        if (StringCase(SubStringBJ(GetEventPlayerChatString(), a, a), false) == SubStringBJ(Curse[c], 1, 1)) then
                            if (StringCase(SubStringBJ(GetEventPlayerChatString(), a, a+StringLength(Curse[c])-1), false) == Curse[c]) then
                                set curse = false
                            endif
                        endif
                    set c = c+1
                    endloop
                    set c = 0  
                set a = a+1
                endloop
                set a = 0


    Nested Loops look a lot cleaner in this format, with the set and exitwhen variable on the same line, or else it would look like this:

    Code (vJASS):
                loop
                    exitwhen a > slength
                    loop
                        exitwhen b > NA
                        if (SubString(GetEventPlayerChatString(), a-1, a) == NOTALLOWED[b]) then
                            set accepted = false
                        endif
                        set b = b+1
                    endloop
                    set b = 0
                    loop
                        exitwhen c > MC
                        if (StringCase(SubStringBJ(GetEventPlayerChatString(), a, a), false) == SubStringBJ(Curse[c], 1, 1)) then
                            if (StringCase(SubStringBJ(GetEventPlayerChatString(), a, a+StringLength(Curse[c])-1), false) == Curse[c]) then
                                set curse = false
                            endif
                        endif
                        set c = c+1
                    endloop
                    set c = 0  
                    set a = a+1
                endloop
                set a = 0


    IGNORE TEH BJ's :p
     
  2. WaterKnight

    WaterKnight

    Joined:
    Aug 18, 2009
    Messages:
    4,033
    Resources:
    5
    Maps:
    1
    Tutorials:
    4
    Resources:
    5
    May be useful for the standard FOR loop to point out the actual loop body independent to the loop's framework. I usually put in a blank line though. Generally, I divide the parts more, for example by a separation line between the loops and what has to be done after another action.
     
  3. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I'm totally with you ShadowFlare, in simple incrementations loops, it just makes the code more readable.
    EDIT : And with you too WaterKnight ^^

    We are lacking something : a way to clearly see if a variable is global or local (and incidentally avoid conflict names, even if it's not really a problem in vJass with the private keyword).

    Blizzard uses the prefix "udg_" for the user defined globals and "bj_" for blizzard jass : blizzard.j known as "GUI", should we use "g_" ?
    Well, i think it's too much for many of them, but personnaly it hurts my eyes when i see a one lower case letter for a global variable such as "q" or whatever.

    Personnaly i use that :

    CamelCase for globals and camelCase for locals.
    Usually i use verbs for functions and names/adjectives, whatever except verbs for variables, i mean the name by itself should be clear enough to make the difference between a function and a global variable.
    But there is an exception the functions which returns a boolean and a boolean global variable, both could be written IsSomething. (ofc functions used in a boolexpr but where the returned boolean doesn't matter are not concerned)

    Sometimes i also use This_is_a_global_variable, this_is_a_local_variable if the name is long enough.

    I'm not pretending my ways are good, just suggesting something because actually there is nothing good about it.
    And it's way more obvious to see a difference between a function and a global variable rather than a global and a local variable if they use all the same syntax.
     
  4. WaterKnight

    WaterKnight

    Joined:
    Aug 18, 2009
    Messages:
    4,033
    Resources:
    5
    Maps:
    1
    Tutorials:
    4
    Resources:
    5
    I write global variables like it was suggested here to write constant variables. Seems really much more useful for me to know if a variable is global or local than if it is constant/not or even more constant in jass meaning. There are only a few scopeless global variables that are primitive code support like NULL or INVALID for a null struct instance, ARRAY_SIZE etc. And even these could be wrapped in scopes.

    I really do not like it when struct instances are compared to numbers in resources.
     
  5. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Hmm i dislike THIS_IS_A_GLOBAL.

    - Because of my azerty keyboard and Windows i've to switch to uppercase / lower case for letters and "_", even if it's not the case in linux : uppercase all the way. (trivial issue i suppose i could fix it on windows :p)
    - For public resources it's really bad since you can't make easily the difference between the configuration part and the "hardcoded" one, even if i'm agree the config part should just be on the top.
    - static ifs (even if it's quite the same reason as said above)
    - I JUST HATE IT, WHY WOULD YOU CRY ? :p
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,162
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Well as struct instances are numbers, it makes sense to compare them to numbers. They aren't handles, after all.

    I agree that globals are not easy to differentiate between locals, I tend to code all my non-constant globals inside of a "struct X extends array", and when I reference them I always include the dot as a prefix.

    If a var shares the same name as its "getter" I usually affix it with a V. Like a method operator that is readonly, I use methodOperatorName and methodOperatorNameV for the thing.

    Obviously this one doesn't have to be the way I do it, because it's a bad excuse to code everything inside of a struct just to tell the difference between global and local. I think the place of all caps should be reserved for constants, personally. But maybe Troll-Brain is onto something with using underscores_for_globals instead of camelCasing.

    I'm not going to edit the first post unless we can get a real good understanding on globals, or I could just leave it up to the user on this one since it's not as big a priority.
     
    Last edited: Oct 6, 2011
  7. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Aha, i've found the point where nobody uses the same rule :p
     
  8. WaterKnight

    WaterKnight

    Joined:
    Aug 18, 2009
    Messages:
    4,033
    Resources:
    5
    Maps:
    1
    Tutorials:
    4
    Resources:
    5
    That would not be a great difference to camelCase though. Well and yes, querty you can write the word in one go.

    Option thingies should really be in an extra paragraph but if you want it at top, you should also have an initializer there as you cannot do everything in globals like filling arrays.

    Elaborate please.

    @Bribe: But we do not want to consider them everywhere as numbers, only if it's for dynamical and low-level reasons and then there could be a basic type referring to all structs. Additionally, the 0 being an invalid struct instance was introduced by JassHelper. It might be different with another allocation etc.
     
  9. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    For me, it does (not talking about the keyboard thingie, just about camelCase).

    Yeah i know, and yes sometimes i use an initializer in the top such as :

    Code (vJASS):
    library MyLibrary initializer init ...

    private function DoInit ...

    private function init ...
        call DoInit()
        ...


    Just to make clear that the needed paramater must be a constant. (also i suppose if you use a non constant one, it will considers it as FALSE instead of displaying an error on save, but i could be wrong about this last point)

    Correct me if i'm wrong but the typecast integer <-> struct is implicit only in the way struct -> integer and must be explicit in the way integer -> struct.
    Elaborate plz.

    Also usefulness or not, pretty much many languages use a different convention for a constant or not variable.
     
  10. ShadowFlare

    ShadowFlare

    Joined:
    Jun 30, 2008
    Messages:
    552
    Resources:
    0
    Resources:
    0
    Global; i.e
    public integer Attribute = 0

    CONSTANT
    private constant integer ATTRIBUTE = 0

    localName
    local integer dX = 0


    Whats wrong with this?
     
  11. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Nothing for me, but tell that about it with some others (such as Nestharus).
     
  12. ShadowFlare

    ShadowFlare

    Joined:
    Jun 30, 2008
    Messages:
    552
    Resources:
    0
    Resources:
    0
  13. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Some people considers that as such an ugly thing, more, as an heresy.
     
  14. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,162
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I don't think anyone checked my post since last I updated it. I am largely on the verge of just leaving global convention up to the user. Berb uses something like data_ or priv_ as prefixes, though I think this might be overkill even to require a prefix at all. As long as it's not easy to get mixed up with something it's not (not getting mixed up with a constant, or a function, etc.) I should think this is fine.
     
  15. WaterKnight

    WaterKnight

    Joined:
    Aug 18, 2009
    Messages:
    4,033
    Resources:
    5
    Maps:
    1
    Tutorials:
    4
    Resources:
    5
    @Shadow-Flare: Well if you write GlobalsLikeThis, on one glimpse, it's harder to distinguish whether it's a local or global +error-prone. Structures of the same naming as suggested here scopes, libaries, structures, modules, functions are placed in different locations or have other additions that makes them easy to identify such as parenthesis or library_member or struct.member. Also you might go in conflict with the names of these other things and are unable to locally address an instance of object type "Box" for example just the same "Box". I do not practise this much either but what default names do you give your variables that you do not have a special one in mind for?

    @Bribe: Your link has double http but I read it now. How can a getter have the same name as your variable? When you prefix getters with the usual "Get", that's an imperative and does not belong in var name. Maybe for flag states "Is" but that can also be easily left out in var names.
     
  16. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,162
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    It depends on the type of data structure, to be honest I don't always
    use the same names for everything.

    If we have something like "j_" prefix, that's going to be impossible to
    miss as a global compared to a local that won't have it. And members
    inside of a struct do not require a prefix because they have the dot.

    I generally don't recommend writing the struct variable name without
    a dot as it is, but I am not in a position to make that a rule because
    not needing a dot is part of what makes vJass look good.
     
  17. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    The not needing of a dot depends how you have configured jasshelper.conf

    If you add this feature are you still allowed to do that ? :

    Code (vJASS):
    struct ...

        integer data

        method m takes integer data ...
            set this.data = data


    If yes, i suppose it's fine.

    Also why "j_", "g_" makes sense because it leads to "global".

    Btw your link in your post is invalid and the main thread still says "use camelCase for variables" and "nothing more" (i mean it's still the same, you never say it's up to the user).
     
  18. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,162
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I have not updated the thread yet because we are still discussion possibilities for globals.

    I like the idea of g_ and I have used it before, I just was using j_ because of the "jass" prefix but your way makes more sense.
     
  19. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,372
    Resources:
    1
    JASS:
    1
    Resources:
    1
    "jass" doesn't mean it's local or global.
     
  20. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,162
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yeah it makes no sense at all.