• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[General] Simple Reforged WE questions for vJass EXPERTS

Status
Not open for further replies.
Level 12
Joined
Jan 30, 2020
Messages
875
Introduction

I have now reached a point where I can't fix my map further as I can't find anyone with the knowledge to answer my non UI-related questions, I decided I should take the matter in my own hands.
To do so, I think I need to forget about plain Jass and start converting my map into vJass, as Reforged WE is supposed to support it with JassHelper, as well as this mysterious thing called LUA.

First for those who haven't read me yet, remember I just came back to Warcraft 3 in December 2019 after 16 years, so many concepts are new to me.

Well first surprise vJass does not work in Reforged WE. I mean not properly.
For example, I can not declare globals :

JASS:
globals
    integer       udg_or_not_i
endglobals

If I throw these in a custom script, JassHelper throws offended compile errors labeled "syntax error"... unless I enable the DEBUG MODE !!!!! WTF ? And no it is not my map, I tried in a blank map !

Ok so let's say i enable that debug mode. Now I can't use a custom InitGlobals functions, it throws an error even with DEBUG MODE enabled.

SO now I replaced all my map global variables by a nice custom globals section that Jass Helper kindly properly injects into the map globals section (thank you debug mode), how do I initialize my globals other than in my MapInit trigger ? So before I chain run into problem after problem that makes my life a nightmare, here is a list of concise questions for experts.

The questions

1) Why does JassHelper need Debug Mode to support vJass ?

2) How do you initialize declared global variables ?

3) How do you inject code in the Main map script / or how do you modify this Main script ?

4) In WE, what is the difference between an empty Custom Script and an emptied trigger converted to text?

5) Using vJass, can I control the whole map script from WE ?

6) Should I really learn vJass now Jass has very little secrets left for me ?

7) What is LUA, is it better than vJass or Jass ? Should I learn LUA instead of vJass ?
(I am asking this question in the context of reforged, all resources I have found are outdated)
 
Level 12
Joined
Jan 30, 2020
Messages
875
Really, no-one has a single idea ?

EDIT :

WHO MURDERED ALL vJASS EXPERTS OF THE SITE !??
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,992
Chill, dude. You posted again 10 hours later mad nobody had responded. The majority of this site's users are in Europe.

  1. JASSHelper works in Reforged without debug mode. Nobody else is posting about this on the forum so you've just misunderstood something.
  2. Give them a value like a local: real D = 150.
  3. There is really no reason to inject into the main map script. Encapsulating your code in a library or scope or struct allows a function to be automatically run on map init (an initializer). This code is created/compiled at compile time, so you can only edit it by extracting war3map.j from the compiled map file.
  4. Are you referring to the "Custom script" section at the top of the trigger list? That's an artifact from an older time where empty triggers couldn't exist and libraries didn't exist for dependencies. There is no functional difference except that code in the main CS section is technically 'before/above' all the triggers so they can all see code in it (JASS can't call 'down/after' except through ExecuteFunc, .execute() or .evaluate()). Trigger code order is determined by the order in which the triggers were literally created (not organized in the list) so you can't really rely on it.
  5. I'm not sure what you mean. See question 3? Map script is generated automatically and just does things like assign gg_rct_YOUR_RECT_NAME variables and the like.
  6. You should learn Lua; it's much more flexible than vJASS. If you're really jonesing for JASS yes take the dive into vJASS; it's not complicated, just adds OOP structure.
  7. Lua is a 'real' language that exists out in the world. JASS is not. Yes you should use Lua; you can read some real world tutorials about how it works to compare to jass (dynamic/embedded functions that can access parent function's locals are a huge upgrade). A map, however, cannot have JASS and Lua in it; you must pick one and stick to it. There might be a few JASS -> Lua transpilers out there you can use to convert older resources.
 
Level 7
Joined
Apr 17, 2017
Messages
316
6) It's not bad to learn vjass because of two things:
  • Most of the resources on the are written in vjass. At some point you need to understand it if you want to use those resources
  • It teaches you basic oop approach which is good

7)Alternatively, you can also learn Typescript, c# or even python as we have these translators to lua. In my opinion, it's hard to organize your code in Lua. But again Lua is 1000 times better than jass.
For ts: cipherxof/wc3-ts-template
C#: [C#] Mapmaking in csharp
Python: [python] WC3 Mapmaking in Python
 
Level 12
Joined
Jan 30, 2020
Messages
875
Very quick reply before I leave for my appointment.

@Pyrogasm :
1) ? Why does JassHelper refuse to compile an empty map (with just base triggers and no globals) without debugging mode enabled when I add the code I mentioned ? this is beyond me. I also tried without udg_ and the result was identical : Compile error - unknown compile error on line xx (syntax error) and the line xx is the line "globals" that i tried to declare.
2) Thanks I already do that. So I should do that at Map Init ? By the way how do you differentiate locals from globals if no prefix ? I see no formatting specification
3) OK I see what you mean, I'll look into structs and libraries and scopes as soon as I get my globals working
4) This actually perfectly answers my question :)
5) yes that was a bit redundant after question 3) I admit
6) I don't mind using OOP at all, just not used to it in mapmaking context
7) OK thanks I get the point, I suppose I will need to dig deep to find tutorials explaining how to use LUA in Reforged WE

@Aeryn : I did a bit of C# a few years back, and also some python, never though it would be possible to use these to elaborate map script. Not sure it is the path I would chose, but certainly not useless to be aware of.

Thanks for your time guys, and sorry if I seemed impatient, but I kind of asked these questions several times under different circumstances without getting a solution.

Yet again I am still stuck with vJass refusing to compile any map when I try to add globals when everywhere people mention declaring globals everywhere you feel like with vJass - I am starting to think I lost my mind somewhere in the process :D

OMG I am late, but I had to reply. Thanks again, this actually helps. If someone still has a glimpse of an idea about my globals hex, please let me know.

Take care !


EDIT : I live in the middle of Europe - I'm french :D
 
Level 12
Joined
Jan 30, 2020
Messages
875
Well As I was late already, I managed to gain 30 mins on mu appointment :)

No when I tried it on a fresh blank map, let WE create the basic melee triggers (no variables then) and starting location, I just added that custom script :

JASS:
globals
    integer udg_i = 0
endglobals
and had the same result.

My map (the next version of the one in my signature), has no more variables in the variable editor.
I indded added this custom script instead :

JASS:
globals
    // INTEGERS
    integer                  udg_BallNumber= 0
    integer                  udg_BallsPerLevel= 0
    integer                  udg_DeadTowerRefundPercent= 0
    integer                  udg_GBSize= 0
    integer                  udg_GiantEuros= 0
    integer                  udg_HostNumber= 0
    integer                  udg_LastLevelEuros= 0
    integer                  udg_Length= 0
    integer                  udg_Level= 0
    integer                  udg_Lev10Euros= 0
    integer                  udg_Lev20Euros= 0
    integer                  udg_Lev30Euros= 0
    integer                  udg_Lev40Euros= 0
    integer                  udg_Lev0Euros= 0
    integer                  udg_MaxNameLength= 0
    integer                  udg_MaxLevel= 0
    integer                  udg_NumberOfBalls= 0
    integer                  udg_PlayersLives= 0
    integer                  udg_PlayersLeft= 0
    integer                  udg_PlayersLeftGB= 0
    integer                  udg_TBallsLeft= 0
    integer                  udg_StartingBonus= 0
    integer                  udg_StartingGold= 0
    integer                  udg_TextPos= 0
    integer                  udg_PanelSize= 0
    integer                  udg_WealthGain= 0
    integer                  udg_WPr= 0
    // Game Objects IDs
    integer                  udg_BallID= 0
    integer                  udg_BBTWID= 0
    integer                  udg_BlockingID= 0
    integer                  udg_BouncingID= 0
    integer                  udg_ButterID= 0
    integer                  udg_DivinityID= 0
    integer                  udg_EDCastedID= 0
    integer                  udg_EDDummyICasterD= 0
    integer                  udg_EDDummyID= 0
    integer                  udg_EmberID= 0
    integer                  udg_EndgameID= 0
    integer                  udg_Entity1ID= 0
    integer                  udg_Entity2ID= 0
    integer                  udg_Entity3ID= 0
    integer                  udg_FairiesID= 0
    integer                  udg_FFID= 0
    integer                  udg_FlyingBallID= 0
    integer                  udg_FlyingHeroID= 0
    integer                  udg_ForceWallID= 0
    integer                  udg_FriendlyBID= 0
    integer                  udg_FrostmourneID= 0
    integer                  udg_GargID= 0
    integer                  udg_GAAID= 0
    integer                  udg_GBHID= 0
    integer                  udg_GiantBallID= 0
    integer                  udg_GiantFlyingID= 0
    integer                  udg_Golem1ID= 0
    integer                  udg_Golem2ID= 0
    integer                  udg_Golem3ID= 0
    integer                  udg_GuardID= 0
    integer                  udg_IceCubesID= 0
    integer                  udg_InitBallTriggers= 0
    integer                  udg_InitialHeroID= 0
    integer                  udg_LetterID= 0
    integer                  udg_PlayerSoulID= 0
    integer                  udg_Poison2ID= 0
    integer                  udg_Poison3ID= 0
    integer                  udg_ProtectorID= 0
    integer                  udg_RageID= 0
    integer                  udg_SellID= 0
    integer                  udg_TamedFBID= 0
    integer                  udg_UAAID= 0
    integer                  udg_WealthID= 0
    // INTEGER ARRAYS
    integer array            udg_Destination
    integer array            udg_GBRow
    integer array            udg_GuidesID
    integer array            udg_LetterType
    integer array            udg_PBallsLeft
    integer array            udg_PlayerLives
    integer array            udg_TextAnim
    integer array            udg_Wall
    integer array            udg_WayPointID
    integer array            udg_Red
    integer array            udg_Green
    integer array            udg_Blue
    // REALS
    real                     udg_BallSize= 0
    real                     udg_BaseHPModifier= 0
    real                     udg_BaseSpawnInterval= 0
    real                     udg_CurrentMaxHP= 0
    real                     udg_FlyingSize= 0
    real                     udg_FreeBlinkRange= 0
    real                     udg_GBNameWidth= 0
    real                     udg_GiantFlyingSize= 0
    real                     udg_GiantSize= 0
    real                     udg_HPModifier= 0
    real                     udg_InitialSize= 0
    real                     udg_Pi2= 0
    real                     udg_PiEighth= 0
    real                     udg_ResizeFactor= 0
    real                     udg_ScrollSpeed= 0
    real                     udg_StoreX= 0
    real                     udg_StoreY= 0
    real                     udg_TimeBetweenBalls= 0
    real                     udg_WallDiagonal= 0
    real                     udg_WallSize= 0
    // REAL ARRAYS
    real array               udg_BallHP
    real array               udg_SpellRange
    real array               udg_WPx
    real array               udg_WPy
    // BOOLEANS
    boolean                  udg_IsFlying= false
    boolean                  udg_IsGiant= false
    boolean                  udg_IsGiantFlying= false
    // BOOLEAN ARRAYS
    boolean array            udg_GoingBackHome
    boolean array            udg_OnGameBoard
    boolean array            udg_PlayerAway
    // STRINGS
    string                   udg_CharMap
    string                   udg_ChosenDifficulty
    string                   udg_ChosenSpeed
    string                   udg_GBBLString
    string                   udg_GFKill_Msg
    string                   udg_GKill_Msg1
    string                   udg_GKill_Msg2
    string                   udg_GKill_Msg3
    string                   udg_GKill_Msg4
    string                   udg_GKill_Msg1Last
    string                   udg_MapName
    string                   udg_MapName_1
    string                   udg_MapName_2
    string                   udg_Message
    string                   udg_NL
    string                   udg_Reminder
    string                   udg_ReminderLevels
    string                   udg_ReminderMaze
    string                   udg_ReminderPlayerBuilds
    string                   udg_Spaces
    string                   udg_Text
    string                   udg_Version
    string                   udg_Welcome1
    string                   udg_Welcome2
    string                   udg_Welcome3
    string                   udg_Welcome4
    string                   udg_Welcome5
    // SFX Strings
    string                   udg_BallReachCitadelModel
    string                   udg_BallWings2Model
    string                   udg_BallWings3Model
    string                   udg_BallWingsModel
    string                   udg_BlinkCasterModel
    string                   udg_BlinkTargetModel
    string                   udg_FFEffect
    string                   udg_GBHEffect
    string                   udg_GlowModel
    string                   udg_SellTowerModel
    string                   udg_SpawnBallModel
    string                   udg_UpgradeEffectModel
    string                   udg_UpgradeEffectSound
    string                   udg_ZoomOutCameraModel
    // STRING ARRAYS
    string array             udg_Anim
    string array             udg_CharMapItem
    string array             udg_ChoiceDifficulty
    string array             udg_ChoiceSpeed
    string array             udg_GBBar
    string array             udg_GBBL
    string array             udg_GBLives
    string array             udg_Music
    string array             udg_PlayerName
    string array             udg_SpellOrder
    string array             udg_SpellOrderOn
    string array             udg_SpellOrderOff
    // RECTS
    rect                     udg_Citadel= null
    // RECT ARRAYS
    rect array               udg_NameStart
    rect array               udg_PlayerArea
    rect array               udg_TextStart
    rect array               udg_WPRec
    // TIMERS
    timer                    udg_AnimLoop= null
    timer                    udg_AttackFix= null
    timer                    udg_DisplayMenu= null
    timer                    udg_EndOfLevelTimer= null
    timer                    udg_EndOfGame= null
    timer                    udg_GameStart= null
    timer                    udg_MapInitFinished= null
    timer                    udg_NextBallTimer= null
    timer                    udg_LevelDisplayed= null
    timer                    udg_Scroll= null
    timer                    udg_TickLoop= null
    timer                    udg_VictoryCameraTimer= null
    // TIMER DIALOGS
    timerdialog              udg_LevelTimerWindow= null
    timerdialog              udg_LevelWindow= null
    // TRIGGERS
    trigger                  udg_EDSpell= null
    trigger                  udg_EDLearn= null
    trigger                  udg_EndOfLevel= null
    trigger                  udg_ReachCitadel= null
    // TRIGGER ARRAYS
    trigger array            udg_EndPlayerGame
    trigger array            udg_KilledBall
    trigger array            udg_NextWayPoint
    trigger array            udg_ReorderStoppedBalls
    trigger array            udg_ResizeBall
    trigger array            udg_ResizeBallOnHP
    // DIALOGS
    dialog                   udg_HPDialog= null
    dialog                   udg_SpeedDialog= null
    // DIALOG ARRAYS
    dialog array             udg_EndDialog
    // DIALOG BUTTON ARRAYS
    button array             udg_DifficultyButton
    button array             udg_EndButton
    // MULTIBOARDS
    multiboard udg_GameBoard= null
    // GROUPS
    group                    udg_EmberGroup= null
    // PLAYERS
    player                   udg_BallsMaster= null
    // UNIT ARRAYS
    unit array               udg_Ball
    unit array               udg_Fairies
    unit array               udg_Flying
    unit array               udg_Giant
    unit array               udg_GiantFlying
    unit array               udg_Hero
    unit array               udg_PlayerSoul
    unit array               udg_Protector
    // DESTRUCTABLE ARRAYS
    destructable array       udg_ForceWall
    destructable array       udg_Guides1
    destructable array       udg_Guides2
    destructable array       udg_NamePanel
    destructable array       udg_PanelChar
    destructable array       udg_WP
    // SOUNDS
    sound                    udg_CountDown= null
    sound                    udg_DaybreakRooster= null
    sound                    udg_Doors= null
    sound                    udg_DryadsCrusade= null
    sound                    udg_DuskWolf= null
    sound                    udg_ElunesDiisgrace= null
    sound                    udg_Leak= null
    sound                    udg_LevelEnd= null
    sound                    udg_LevelStart= null
    sound                    udg_WarlockAppears= null
    // CAMERASETUPS
    camerasetup              udg_DefeatCamera= null
    camerasetup              udg_Overview= null
    camerasetup              udg_VictoryCamera= null
    // WEATHEREFFECTS
    weathereffect            udg_WeatherEffect= null
endglobals

And shows the same behaviour if i disable debug mode. With debug mode it runs fine

I didn't remove the udg_ prefixes as I don't want to confuse globals and locals.

EDITs :
The few Typos I just noticed do not affect the game as Variable Editor also changed the names in the triggers before I deleted the variables.
Really have to leave now, will be back in a few hours. Thanks for any help provided so far, and for any further help you may provide guys.
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,992
Thanks I already do that. So I should do that at Map Init ? By the way how do you differentiate locals from globals if no prefix ? I see no formatting specification
No... you just initialize them by giving them a value in the line where they're declared. Like a local. The udg_ prefix has nothing to do with actual variable definition, it's just something Blizzard made the GUI variable editor prepends to user variables (user defined global). Globals are only defined inside globals blocks.

I have no idea why you are getting errors; I can compile that globals block just fine. Are you actually using the stock World Editor or trying to use some old JNGP/WEX version?
 
Level 12
Joined
Jan 30, 2020
Messages
875
Yes I knew about udg_ just not sure what to use instead to differentiate globals from locals, especially when the script starts becoming dense. I mean for constants its easy, the good practice advice to use CAPITALS, but for globals ? or maybe should I use my capitalized words for globals and full lower case for locals ? I'll give it a think.

As for initialization, I suppose then that I have to initialize arrays after the other variables.

Funny thing the generated map script first declares globals, then uses initGlobals. Thats why I felt i needed to follow this path, but in all fairness nothing seems to indicate it has any advantage.


Yes I use stock Reforged WE. But this just gave me an easy way out.
I must be doing something wrong that is not obvious but definitely causes this strange JassHelper reaction.

My best bet to find my own error :

Please attach an empty map with a small globals section that JassHelper accepts so that I can compare and see what stupid thing I did to make it never work thanks !!!!
 
Last edited:
Level 7
Joined
Apr 17, 2017
Messages
316
Well it's a recommended approach to use camelcase for variable names and pascalcase for function names, also CAPITALS for constant variables. And yes you can only declare if a variable has an array inside global block and can't do something like variable[2] = 20 inside that block.
 

Attachments

  • Global Init.w3m
    16.8 KB · Views: 39
Level 12
Joined
Jan 30, 2020
Messages
875
Back, sorry had some "daughter needs help" real life trigger to fix :D

Ok so now I am starting to worry.

After I opened your test map, I tried to save it right away.... and I get the same errors as with my own attempts. This is worrying. Now I know I didn't do anything stupid, but that there seems to be a problem with my wc3 installation :(

EDIT : a picture is probably showing more.

Imgur

EDIT2 : tag for images is broken on the site
 
Last edited:
Level 12
Joined
Jan 30, 2020
Messages
875
OK tested quite a few things and it's a no go for vJass on my computer for some reasons I did not manage to identify.

Did a clean install of reforged. Then trying my favorite video options and lost buildings ground textures.

So reset my Warcraft 3 settings to default and changed only the resolution - only benefit from this is that my buildings ground textures (ubersplats) are back.

As for vJass, after the clean reinstall now things got worse : I still can't declare globals on any map, blank, old, new whatever.

And now the latest version of my map, where I declared globals thanks to the debug mode simply crashes WE on loading.

I think this is a sign I should give up the entire vJass idea and stick to good old Jass. Pity as I liked the perspectives vJass was offering.

As for LUA, I suppose if I can't even use the most basic vJass thing in WE, chances are high I won't get any more success with LUA.

I suppose I could also go back to the "good" old no-WE and only work on the map script, but that' is not practical, especially when It comes to testing.
 
Level 39
Joined
Feb 27, 2007
Messages
4,992
I don’t understand why you feel the need to explicitly differentiate between locals and globals. You should just... know which ones are which because you wrote the code. You shouldn’t be using the same variable names where confusion could be possible. You can use public variables within scopes to automatically prefix things to your variables:
JASS:
scope GLOBAL
  public real Amount
  public unit Horseman
endscope

call KillUnit(GLOBAL_Horseman)
 
Level 12
Joined
Jan 30, 2020
Messages
875
Try enabling Jasshelper but not vJASS in the menu. On patch 1.31, I get syntax errors whenever I enable vJASS. The flags for enabling and disabling vJASS was probably switched ever since a certain patch.

Oh My God.

It was it. How the hell was I supposed to guess that I have no idea.

You just saved me big time. I'd give you 1k reputation for the principle if I could but I can only give 1 at a time for the moment :D

Wow all these headaches because blizzard messed up the vJass option... I can't believe this.


@Chaosy I don't understand what you mean there. these udg_ prefixes are just those created by the variable editor and my first goal was not to get rig of these prefixes, but to take control over the globals in my map. Now I can do it (or it seems) thanks to GhostHunter123. This will allow me to slowly convert my code to make it cleaner and easier to optimize.

@Pyrogasm : I admit I haven't done much programming for a couple of years, but I seem to remember naming conventions were created for this sole purpose of differentiating CONSTANTS,Global and local variables. I used to do that all the time in Object Oriented PHP, although it's been a while now. This said thanks for your scope thingy, I don't understand them yet, they look something like a contextual library. But now I can use vJass at last, I plan to learn everything that is required.

You can't just "know what variables are globals or locals" this does not make sense to me. How are you supposed to do that when you have to review thousands of lines of code ? And worse, when it is not yours. I don't mean I know better, I just find the idea frightening that's all. I am really tempted to start using camel case for locals and pascal case for globals (thanks @Aeryn ). I am a bit perfectionist and I like things to look clean for easy "visual debugging".


EDIT : before I go any further with vJass, what are the things not supported, or simply the things counter-productive performance wise ? What about inheritance, polymorphism and all these OOP goodies ?
 
Last edited:
Level 12
Joined
Jan 30, 2020
Messages
875
I think you are operating on some weird assumption that globals are better than udg_ variables in any way shape or form.

You use either globals or udgs, you don't try to combine them as there is no benefit at all (except for bug abusing which is only done for local variables anyway)


This is very confusing. As far I as know variables created by the Trigger Editor with the udg_ prefix are nothing else than globals. (user defined globals)
I never had any intention of combining globals generated by the Trigger Editor and my self managed globals, I just wanted to regain control of my Global variables.
As for now i deleted the entire "Variables" category from the Trigger Editor anyways.

Fun fact everything works like a charm, it also helped me getting rid of a corrupted global variable entry in the trigger editor that would come back from deletion everytime I reloaded my map.
I can now declare and initialize my globals as I wish, will be able to give them proper Camel Case names with no prefix and edit them when required in Notepad++


The only issue I have left now is that when I work on the map, everything works great, not a single hiccup. But when I save the map, then restart world editor and try to load the map, WE crashes for some weird reason. Even though the "crashing" map actually runs fine when played in the game.

I really start thinking there is something wrong with Reforged WE somewhere.

It might still be something else from my map, so I will attempt to work on a blank new map and see if the issue persists.
 
Last edited:
Level 12
Joined
Jan 30, 2020
Messages
875
This crash on loading is a real killer. Of course it is related to triggers, as the crash occurs while loading them.

I don't think I did something drastically wrong as everything works nice (validating triggers, testing the map, etc...).

Anyone has already experienced similar crashes (the map working great before restarting WE) ?

If I cannot find the solution to this new problem, only issue I can think of is remove all triggers from the map, leaving just custom object data and terrain, and then start coding the map in vJass from scratch.

I feel like Reforge keeps setting me back and refuses to work everytime I try. It has been there since I came back to map making, so far I have found ways around 99% of my problems, but sometimes it seems near impossible (best example is the enable vJass option that disables vJass... i mean this kind of non sense makes tracking issues a real nightmare!).

Anyways I'll keep my remaining non-Jass related issues for later, I doubt they can be fixed unless Blizzard does something about it.

Again thanks for all the help and the information so far guys, every step forward is precious !!!
 
Level 39
Joined
Feb 27, 2007
Messages
4,992
You can't just "know what variables are globals or locals" this does not make sense to me. How are you supposed to do that when you have to review thousands of lines of code ?
You absolutely can just know. I have almost never been confused by this in all of my time working with wc3 because JASS variable declarations can only exist at the very beginning of a function. If you come upon a variable and don't know if it's a global or a local, you look at the top of the function for a matching name; if it's there then it's a local (or a global being overwritten by a local but please don't ever do this), and if it's not then it's a global. Simple. In Lua yes the variables can be defined mid-function so you'll have to do a little bit of searching with ctrl+f/g or copy the code into something like notepad++ with lua support and then select the variable to see all uses of it in that function. Again, not too much work.
JASS:
function foo takes nothing returns nothing
  // locals are only declared here
  // they will always be at the top of the function
  local real r1 = 11.23
  local unit un13 = null

  //...
  call DoSomething()

  // locals cannot be defined here:
  local real cannotdothis = 0. //COMPILE ERROR THROWN HERE
endfunction
 
Level 12
Joined
Jan 30, 2020
Messages
875
You absolutely can just know. I have almost never been confused by this in all of my time working with wc3 because JASS variable declarations can only exist at the very beginning of a function. If you come upon a variable and don't know if it's a global or a local, you look at the top of the function for a matching name; if it's there then it's a local (or a global being overwritten by a local but please don't ever do this), and if it's not then it's a global. Simple. In Lua yes the variables can be defined mid-function so you'll have to do a little bit of searching with ctrl+f/g or copy the code into something like notepad++ with lua support and then select the variable to see all uses of it in that function. Again, not too much work.
JASS:
function foo takes nothing returns nothing
  // locals are only declared here
  // they will always be at the top of the function
  local real r1 = 11.23
  local unit un13 = null

  //...
  call DoSomething()

  // locals cannot be defined here:
  local real cannotdothis = 0. //COMPILE ERROR THROWN HERE
endfunction


Please, I know all this. And I understand what you're saying about Jass. Also, I personally don't know many languages where you can declare locals everywhere. I don't know LUA yet, never heard of it when I used to be developer.

But I still disagree. I don't like to use the same naming conventions for local variables and global variables. I never have, whatever development environment I have ever used.

The reason should be obvious !

Imagine you have a function that fills up 12 pages of code (I know what you will say, but it can actually happen in real life coding, trust me).
If you need to scroll up to check the list of 48 local variables (exaggeration on purpose) just to make sure, you are wasting a lot of time.

If you keep naming conventions for your entire code, fact is it makes it much faster to work with and you will be less prone to errors.

With Camel and Pascal Cases, you don't even need to know anything about the locals declaration :

JASS:
   .... 3 pages of code ....
    if ( thePlayer == HostPlayer) then
        ................
    endif

Reding this you IMMEDIATELY know thePlayer is a local and HostPlayer is a global.

Same thing without naming conventions :

JASS:
   .... 3 pages of code ....
    if ( ThePlayer == HostPlayer) then
        ................
    endif

In this case you need to know you locals by heart or you need to scroll and read your locals declarations. Of course it's irrelevant when your functions is 5 lines long, but if you keep changing your naming to with and without convention, it provides what I would call "dirty code".
Some might argue that a search can take a second, but first not all development environments have a text editor as modern and sensible as NotePad++, and as far as I am concerned, it is a lost second.

This is a subject I have always been very strict with when I was a developer, because I often had to fight with my project members who sometimes didn't care, and after we wasted hours trying to decipher each others code, I made naming conventions mandatory for the projects (This also included indentation, spacing and other important visual aspects of the code).
Now of course if you only write code for yourself, this becomes much less vital.

Note that this is also the reason why I wasn't very keen on removing udg_ prefixes at first, because I didn't know vJass good practices, and that includes variables naming. I thought there would be some convention after so many years, but it seems from this thread that people more or less chose their own way.

Anyways I wasn't planning to start a debate on coding good practices, even if every debate can have some use :)
 
Level 39
Joined
Feb 27, 2007
Messages
4,992
magine you have a function that fills up 12 pages of code (I know what you will say, but it can actually happen in real life coding, trust me).
If you need to scroll up to check the list of 48 local variables (exaggeration on purpose) just to make sure, you are wasting a lot of time.
If you don't know if a variable is local or global from context then your code in general is just not clear. And god forbid you have to scroll up a bit once every 30 minutes. If this bothers you then by all means pick your own convention; I'm saying there's really not a reason to need to in my opinion.
In this case you need to know you locals by heart
When are you ever not sure what variables are local in code you wrote? You know how it works. You know if HostPlayer should be global or not based on how it's used. Same for ThePlayer.
 
Level 12
Joined
Jan 30, 2020
Messages
875
As for the first point, I agree, it's better for people to have their own conventions (except when you work in a group, for a project, etc.. where you have to use the group's conventions). But when working alone, it actually makes much more sense to use your own for efficiency and comfort.

As for the second point, I know I tend to express myself with 10x more words than required, but you clearly missed quite a few from my post.
First you can happen to work on big projects where it is impossible to always know all local names by heart even when the code is yours- I suppose that is even the case in wc3 if you look back at projects like Darky27+ custom campaigns in the old days, or more recently a project like YouTD.

But you might also sometimes need to review someone else's code for whatever reason.
In that context, for example, if you don't use conventions, it could give the reviewer an unnecessarily harder time.

Fact is there have always been naming conventions, as well as indenting, etc.. since the very first programming language in plain text. I mean even old simple BASIC 1.0 and its line numbering had some (not many though I must admit). And the reason has always been the same : definitely not code efficiency, but code readability.

Now I don't mean everyone should follow the same visual coding conventions, as it would first require a complete consensus about why it should be done one way or another, but if you push the no convention principle too far, you'll end up with code only you can read. It only is a problem when that code needs to be shared of course.

A last important example :
Making Jass code the most efficient possible just by tinkering with conventions is what Vexorian was using to obfuscate code in his Map Optimizer / Protector. The code is still 100% valid in Jass, but barely readable.

Still, all the points I made are irrelevant in a non code-sharing context where only coder preference should prevail.



Anyways, no need to start a philosophical debate on the matter for days, you probably are a much more experienced Jass coder than me, and I am not here to try to prove everyone but myself wrong. It all started with my desire to take control of my globals and my worry to differentiate them from locals, and @Aeryn reminded me that I could use Camel and Pascal Case. So I am quite happy on this side of things.


Oh and once again, I have to thank you for spending time trying to address my questions, and even debating with me. I really do appreciate.

So far the only issue I have left is that WE crash, I already restarted with a version of my map with cleared triggers, and started from scratch.

So far I have done the globals, their initialization on a separate function (was necessary for arrays), and I applied these Camel and Pascal Case naming conventions to my "Map functions".

On that specific point, i suppose I should use a library ? I seem to have read that a scope is more contextual and is not made to have public functions.

So far the map saves and loads in WE with no crash. Touching wood !!!
 
Last edited:
Level 12
Joined
Jan 30, 2020
Messages
875
You can also check out this if you want to submit a resource for public use: JPAG - JASS Proper Application Guide

Thank you !!!

Well, with the addition of Camel and Pascal Cases, I am following all these nice conventions !
I even battle with NotePad++ sometimes to replace tabulations with 4 spaces :D

EDIT :

Reading a bit deeper, they show interesting examples. One caught my eye, private function in library. Just to make sure I am not lost on a drifting ship again, usually libraries rather have public functions (except for internal operations) i suppose ?

So what are scopes ? IS it a kind of group of functions working on the same context with limited public functions ?

This all looks promising, I know I jump on the running train, but really.

Where can I find a comprehensive "guide" about vJass, one that would tell me what is possible and impossible with vJass.

I mean does it support polymorphism ? interfaces ?
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,992
you clearly missed quite a few from my post
It only is a problem when that code needs to be shared of course.
That's exactly why I ignored some of your commentary.
Where can I find a comprehensive "guide" about vJass, one that would tell me what is possible and impossible with vJass.
There used to be a JASSHelper manual hosted on wc3c but since the site is down now you can't access it directly. This resource is mostly up-to-date: WC3 Modding Information Center - VJASS Documentation
does it support polymorphism? interfaces?
Yes and yes.
So what are scopes ? IS it a kind of group of functions working on the same context with limited public functions ?
It's literally just encapsulation with initializers.
 
Status
Not open for further replies.
Top