Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
Ideally it would be text-based, and from a ".j" file.
However, he does say he has some .mpq extracting utility on the server, so it's possible that it can grab war3map.j from the map, compile it, then throw the map back at the user, in the best case scenario.
I've tried to convert the delphi project consolejasser.dpr in a lazarus project with the tool made for that, but there is still windows stuff, and comment it didn't help.
Ofc i suppose it could still be compiled for linux, but that's not so easy, it requires to edit the code and i have not the knowledge to do it, nor the willing to learn.
Ideally it would be text-based, and from a ".j" file.
However, he does say he has some .mpq extracting utility on the server, so it's possible that it can grab war3map.j from the map, compile it, then throw the map back at the user, in the best case scenario.
//! include and //! external directives would still not work.
And //! external is used very often these days (ObjectMerger and LUA)
If you wanted online compilation of whole maps your best option would be putting it on a windows server.
The thing I don't understand is why would anyone want to compile maps online?
If you have a Macintosh it would be both faster and easier to install WMware.
The group-for loops work great, however the integer-for loops work a bit awkwardly when compiled.
Currently they do this:
JASS:
//====== for i = 0 to 7 ======//
set i = (0) - 1
loop
set i = i + 1
exitwhen i > (7)
call SetUnitColor(OpenCinematic__warChaser[i], PLAYER_COLOR_RED)
call SetWidgetLife(OpenCinematic__warChaser[i], 0.406)
endloop // endfor
I don't know what's the point of adding the "()" wrapper since no optimizer is going to remove that, we're just adding obesity (albeit a small amount). Another problem is, in the beginning, you add 1 for "downto loops" and you subtract 1 for "to loops".
It would work just fine if the compiler did the following, instead:
JASS:
//====== for i = 0 to 7 ======//
set i = 0
loop
exitwhen i > 7
call SetUnitColor(OpenCinematic__warChaser[i], PLAYER_COLOR_RED)
call SetWidgetLife(OpenCinematic__warChaser[i], 0.406)
set i = i + 1
endloop // endfor
Looking at the source code (consolejasser/stage2/Structs02) I can see that it is split into two tokens, the "for" and "endfor". While I don't know pascal I can imagine it would be easy enough to set a boolean flag that says whether or not to include the "set i = i +/-1" part when you process a closing "endfor" block.
Otherwise, great work on this compiler. The loading of blizzard.j/common.j has been the bottleneck of JassHelper parsing for me for the past couple years and you just cut compile time by 3/4 for me.
parentheses () are pure semantic elements, they affect only ordering of operations so there is no obesity there.
The reason they are used is in cases when boundaries of a loop are not simple integers.
The reason +1/-1 trick is used is to make all closing statements semantically equivalent. endloop, endfor, endwhile are all synonyms.
I still don't get the need of (), i mean i can't imagine a case where the precedence will be changed if you add () or not.
Ofc i'm talking about your for loop converted in jass.
@Cohadar, honestly the closing statements don't have to be all identical with how they are parsed. It would honestly just involve a string queue (first in, last out) and if it's a "downto" or a "to" loop you can insert the unique string into the queue, and remove it from the queue when you hit an "endfor" token. You would just store an empty string for things like "for u in group".
@Troll-Brain
Search for a word "operator" inside jasshelpermanual.
And than imagine Nestharus doing crazy shit with operator overloading.
@Bribe
Compilers are not just about compiling proper code.
What if you have nested loops but you forgot to close one of them?
How would you do error reporting there?
I take great joy in seeing you two reverting to BJism madness.
It assures me that the latest version is really stable
I'm not sure what you are talking about by "reverting to BJism madness", but it is a while now that i'm no more a speedfreak dude.
Now, i would still not use your "while not loop", coz of what i've already told you on wc3c.net, but the for loops really cut off verbosity, so i might use them (or not, i'm still not sure).
At least, i'm already using the "for unit in group" loop.
I've read the jasshelper documentation again, and even if your for loops are used in a struct where the operator ">" is overloaded, i still can't find a case where the () are needed.
Maybe the case does not exist, maybe it does?
The fact is I personally am not totally sure it would be safe to remove them.
My programming instincts tell me to do it the standard way.
Like I said, parentheses are pure semantic elements, they just order precedence, so there is really no real reason to remove them except saving 2 bytes in input script.
I am doing some mayor refactoring, all this talk just seems irrelevant to me now.
New error reporting style is coming and new function interfaces are coming, prepare yourself to be amazed.
@Bribe
Function interfaces will not change on the outside.
But new implementation will be faster, safer and will not generate parts that are not needed.
But before I can do them I must finish new bug reporting mechanism.
Currently bug reporting in jasshelper shows you the compiled text when it catches error in later stages. This is ugly and confusing.
New mechanism will ALWAYS give you error report on your original (uncompiled) text.
I know this is off-topic but it would be great if someone has the skill to edit the object editor exporting/importing
method, means if you import things, the previous data wont be erased or overwitten by the new one, just 'adds'
the data, coz opening/saving/cnp is just pain...
An idea that a lot of people have been wanting if you haven't yet implemented
Top down ordering of methods inside of a struct to prevent trigger evaluation generation when implementing modules. If it's impossible to order a given method, then and only then generate a trigger for it (I'd prefer if it displayed an error myself though). This will make it so that we don't have to create 2-3 modules to implement to prevent triggers from being generated.
Also, if a method is to be inlined, it should never be generating a trigger ^)^.
Automatic fixing of returned local non arg handles ; O (yes, they do leak pointers).
JASS:
function ReturnSomething takes nothing returns unit
local unit u = CreateUnit(Player(0), 'hfoo', 0, 0, 0)
return u //leak!
endfunction
to
JASS:
globals
unit returnUnt
endglobals
function ReturnSomething takes nothing returns unit
local unit u = CreateUnit(Player(0), 'hfoo', 0, 0, 0)
set returnUnit = u
set u = null
return returnUnit //no longer leaks ^)^
endfunction
Only 1 variable should be generated for any given handle (please don't spam 1 for every function).
Eventually, at some point, it would be cool to be able to access object editor data from JASS. You could store it in a dictionary or something and then when you see something like Objects, you'll know that they want to read from the dictionary.
for example
Objects["units"]['hpea']["usei"]
And if something is an array of items
Objects["units]['hpea']["utra"][0]
From there, should be able to use some sort of reflection to figure out the returned item for a given array (if the item may have been an upgrade, a unit, an item, or w/e). Also should include some nice polymorphism. For example, items, upgrades, and units share gold and lumber costs ; ).
This would ofc be a feature for a much later date. It would make some libs like GetUnitCollision deprecated. I'm sure a lot of people would appreciate this ; ).
This one is already possible, add the tag [forcemethodevaluate] to jasshelper.conf.
I also personnaly use [noshadowfixer]
EDIT : And now that i'm thinking about it i would also use [noimplicitthis].
JASS:
struct S
integer data
method m takes integer data returns nothing
set (this).data = data
// "set data = data" wouldn't work so well, and even if does , the syntax is senseless
endmethod
endstruct
All this reminds me of LaTeX and how unusuable it is to do anything functional...
I would much rather see merging of Vexorian's script optimizer into JassHelper than new features that people use just because they think it is clever to use instead of actually because they are needed.
Automatic fixing of returned local non arg handles ; O (yes, they do leak pointers).
Not possible. There are situations where some handles are never removed so the reference counter is purposly left to leak as part of an optimization (eg local players which can never be truely destroyed). Some maps might also implement recycling systems for objects like timers and groups which again are unaffected by reference leaks due to never getting destroyed.
Eventually, at some point, it would be cool to be able to access object editor data from JASS. You could store it in a dictionary or something and then when you see something like Objects, you'll know that they want to read from the dictionary.
Or you could just mod StarCraft II where the game nativly supports such functionality. I would leave it at a macro command atmost which would look up the value at precompiler time.
Since we are covering pointless features, how about the ability to set arrays neatly?
set array = {N...a,b,c,d,e,etc}
Where N is an initial offset.
integer array arr
// set index 0 to 1 ... etc ... index 4 to 5
set arr = {1,2,3,4,5}
// set index 5 to 1 ... etc ... index 9 to 5
set arr = {5...1,2,3,4,5}
// also needs multi line support
Code:
set arr = {5...
1,
2,
3,
4,
5}
The precopiler generates the following.
set array = {N...a,b,c,etc}
becomes
JASS:
set array[N] = a
set array[N+1] = b
set array[N+2] = c
...
Obviously you apply a numeric constants optimizer to it so that an expression like
set arr = {5...1,2,3} // N is a constant
becomes
JASS:
set arr[5] = 1
set arr[6] = 2
set arr[7] = 3
The reason to introduce such a feature is to greatly improve the usability of arrays when storing bulk data (such as table entries).
Lets say we have a wave system for a towerdefense. Currently one has to apply a set line for each entry (wave) and compute the index manually. If you compute the index dynamicly then you incure a performance penalty for no reason (as the indexes you are setting are constant). With this feature it would allow you to set all waves with a single set statement and make changes such as deletion or insertion without having to recompute all the constant indexes. This becomes very user friendly for people to use such a system as they are modifying a table like structure rather than JASS arrays which a lot of people do not undertstand.
Even though it would support dynamic offsets, the advantage purly becomes code neatness rather than ease of use.
Some native functions don't work or even make wc3 crash if they are used in the global definition.
For example CreateRegion doesn't work, while GetLocalPlayer make wc3 crash.
It could be easily fixed by setting the globals in the main function instead.
But maybe it's just too much, it's just a suggestion.
It would allow even more fancy stuff, such as using custom functions.
It would be pretty annoying to find out which ones don't work and which ones don't, and add them to a list which gets added to the main function, so the compiler can change what the user could have changed already. It would also need an ExecuteFunc of its own, to avoid op limit risks.
Now that library initializers are run with the same priority as modules, it's not adding a lot of work to the user to move the occasional Rect/CreateUnit/Item/Destructable/Region call to that dedicated function.
It would be pretty annoying to find out which ones don't work and which ones don't, and add them to a list which gets added to the main function, so the compiler can change what the user could have changed already. It would also need an ExecuteFunc of its own, to avoid op limit risks.
The thing is that you don't need to find them, just make the false assumption that they are not working correctly.
I mean move all globals definition in the main function.
About the op-limit, you would have to init several thousands of globals to reach it.
Now instead of be included directly in the main function, it could be used in a custom dedicaced function, and then called through ExecuteFunc in the main function.
The only cost will be few bytes more (the variables names will be used 2 times instead of just one, and with an additional "set ")
Now that library initializers are run with the same priority as modules, it's not adding a lot of work to the user to move the occasional Rect/CreateUnit/Item/Destructable/Region call to that dedicated function.
It's clearly not the OMG-i-need-this-feature-so-much, in fact i don't care that much.
I just find it as a neat feature, and is in my to-do list for my own jass pre-processor (just because i can)
Sure, but you're not allowed to use CreateUnit,Rect and such, sure it's clearly not a big deal.
Also as said, then you would be allowed to use custom functions instead of just natives one.
But it's probably too overkilled for the providen feature.
Global blocks are currently parsed before static if's, so if you want to avoid generating certain globals under certain preprocessor conditions, you have to use struct members.
Try to compile this, it will still generate the "poop" integer.
JASS:
static if false then
globals
integer poop = 'fart'
endglobals
endif
I hope this is an easy one to fix, to just move the parsing precedence of globals lower than static if's.
For example CreateRegion doesn't work, while GetLocalPlayer make wc3 crash.
It could be easily fixed by setting the globals in the main function instead.
But maybe it's just too much, it's just a suggestion.
Except this makes the pre-compiler start to modify the funcionality of the code. This is not a good idea as it encourages people to script badly and rely on the precompiler to make it work rather than script properly in the first place.
edit
this jasshelper generates some weird stuff in my map..
JASS:
function sc__SummonHandler_create takes integer unitTypeId,real x,real y,real facing,real x2,real y2,real facing2,integer owner,integer count,integer checkpoint1,integer checkpoint2 returns integer
set f__arg_integer1=unitTypeId
set f__arg_real1=x
set f__arg_real2=y
set f__arg_real3=facing
set f__arg_real4=x2
set f__arg_real5=y2
set f__arg_real6=facing2
set f__arg_integer2=owner
set f__arg_integer3=count
set f__arg_integer4=checkpoint1
set f__arg_integer5=checkpoint2
call TriggerEvaluate(st__SummonHandler_create)
return f__result_integer
endfunction
Note that SummonHandler is a struct that extends an array and that function is not called anywhere in the compiled script. Everything that calls it either uses that library or is not in a library.
Here are some other weird ones..
JASS:
function sc___prototype38_execute takes integer i,integer a1,integer a2 returns nothing
set f__arg_integer1=a1
set f__arg_integer2=a2
call TriggerExecute(st___prototype38[i])
endfunction
function sc___prototype38_evaluate takes integer i,integer a1,integer a2 returns nothing
set f__arg_integer1=a1
set f__arg_integer2=a2
call TriggerEvaluate(st___prototype38[i])
endfunction
What those are I have absolutely no idea..
edit
apparently Warcraft 3 doesn't need new line characters to separate lines out??
check out war3map.j. That is the script optimized by cjass for my map... my map runs and everything using that script... removing all of the spacing/comments and what not cut my script size down by a little more than 50%.
Does it really worth it ?
Reserved keywords are not meant to be used as a variable name, even the vJass abuse like that is a really terrible practice :
JASS:
struct S
integer integer
endstruct
Sure, these keywords were introduced later, but it doesn't really make sense to use them anyway and the fix is easy.
Off-topic :
Btw is "unix" newline characters '\n' are supported for a mapscript ? (i can test it myself, but if you know it ...)
Does it really worth it ?
Reserved keywords are not meant to be used as a variable name, even the vJass abuse like that is a really terrible practice :
Is it really worth maintaining backwards compatibility? Yes.
The big thing about this is that it's supposed to be backwards compatible with regular vjass. If you want to add new keywords, that's your problem. They shouldn't be breaking previously working scripts.
The for to thing is easy to fix. You can just find out if the line starts with "for " (ignoring comments and space) or not. For while, you can check if the line starts with "while " or not. For all of your other keywords, same deal. It's extremely easy to fix... you should probably be doing for this all keywords. loop is a keyword if line starts with loop, etc.
Breaking backwards compatibility for a major resource like jasshelper is not cool, and if you can fix it (which you can rather easily), you should.
Ok, let's rephrase it, how many guys on the earth use such shorts names as "to" for their variable and method names, comparing to the other don't at all ?
"to,while,endwhile,for,in,endfor" are new reserved keyword, take it and "handle" it.
Not to mention that even if you don't use the new loops if you want a proper init without the module abuse this jasshelper is already needed.
I mean the pros are much better than this "con", so take your ego off and change your variable/method/whatever names.
Not to mention that even if you don't use the new loops if you want a proper init without the module abuse this jasshelper is already needed.
I mean the pros are much better than this "con", so take your ego off and change your variable/method/whatever names.
Breaking backwards compatibility for a major resource is a major no no. If it can be fixed, it should be fixed -.-. I've already provided the very easy solution. With regex, it's a 5-10 minute fix...
Blablabla *2, as usually you over-exaggerate a little thing that can be "fixed" easily, and shouldn't even exist in the first place anyway (to is a really poor name).
You're not going to convince me, neither i will convince you, so end of story for me.
It is a 5-10 seconds fix if you simply change that variable name.
You cannot really say compatibility is broken if updating your map takes less than 30 seconds and compiler tells you exactly what you need to do.
Btw any "suggestions" you make about jasshelper are going to the bottom of priority list until you do some community work.
Specifically writing tests for //! externalblock directive since it is obviously "your thing"
Same goes for you Troll-Brain.
I expect you to make some good Module tests (at least 3) that will test every possible use of Modules.
(They are obviously one of the most used advanced vjass features so it is paramount that EVERYTHING about them is under proper test)
Sounds a bit childish, i mean the suggestions should be considered only depends on their potential usefulness, no matter who said them.
Now if you use "" to highlight the stupid suggestions, just ignore them.
I mean it's not because someone help you by provide test codes or anything else, that he should be rewarded by implementing a dumb feature that no-one-will-ever-use-except-the-guy.
Hopefully i think you are enough mature to get this obvious fact, but i just found your sentence weird.
Anyway i've done one test, but i don't think i will post more, i'm an lazy-ass after all. (seriously)
Working on jasshelper is serious and hard work, also one that demands responsibility because of compatibility issues.
That is where tests come in.
I don't care what you think it is childish, and I am serious about priority statement above.
The amount of work that is needed to do those tests is insignificant compared to the amount of work I spend on jasshelper.
Right now watermelon_1234, Fledermaus and Bribe have request priority because of their contributions.
Work is rewarded with virtual coins, there is nothing childish about that, it is simple economy.
This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
By continuing to use this site, you are consenting to our use of cookies.