• 🏆 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!

[Release] WurstScript - A Wurst to Jass Compiler & IDE

Status
Not open for further replies.

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
Hi,

I really want to use this. But the standard library is broken from the manual.
http://peq.github.io/WurstScript/standardlib.html

Is there a fix for this?
Thanks

I fixed the link, but as Frotty said the documentation of the standard library is not very good at the moment. Most of the times it is better to directly look at the source code or just explore the API by using Eclipse autocomplete and jump to declaration ;)
 
Level 1
Joined
Jun 17, 2014
Messages
3
I'm experienced in programming many languages for work. I am completely new to war3 modding - just that I have a game idea and felt the war3 engine will do what I need.

Thanks for that lib folder. I ended up copy pasting it as a project named "lib" in eclipse which makes it pretty easy to work out with nice syntax highlighting etc. I think that is what I was missing. I'll go through some more Jass tutorials as well.

Thanks again.
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
I'm experienced in programming many languages for work. I am completely new to war3 modding - just that I have a game idea and felt the war3 engine will do what I need.

Thanks for that lib folder. I ended up copy pasting it as a project named "lib" in eclipse which makes it pretty easy to work out with nice syntax highlighting etc. I think that is what I was missing. I'll go through some more Jass tutorials as well.

Thanks again.

No Problem.
Cool enough that you chose Wurst ;)
Feel free to ask Questions and leave Feedback, use the issue tracker for bugs and other things.

Enjoy.
 
Level 13
Joined
Mar 6, 2008
Messages
852
It's a little bit weird.
This weekend Crigges incidentally told me about a Wurst feature which haven't been advertised here and which I think is pretty neat especially for terrainers or people with an enormous amount of imports.

I am talking about the auto-import. If you have a folder called "imports" in the same folder as your map and if you save your map, all files which are in the "imports"-folder will imported into your map automatically. Their import path will be the same path they have in the "imports"-folder.
One just have to re-start the map afterwards and everything is ready to go.
 

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
Wurst Birthday

Today Wurst is 3 years old. The initial commit was on 22. June 2011.

Time to increase the version number and post a new changelog:

Version 1.4.1.0

Language Changes:


  • The init order now again depends on the import order. A cyclic init order is forbidden. Use the initlater keyword on imports to break cycles.
  • The rules for newlines are changed. Previously all newlines inside parenthesis were ignored (similar to Python). Now newlines are ignored when a line ends with or begins with special characters (similar to Go). For example when a line ends with a comma, the following newline is ignored.
  • It is now possible to have mutually recursive functions.
  • Wurst now supports array members for classes (#176).
  • Packages can now be configured with config-packages.
Standard library:


  • Some bugfixes and refactorings.
Tools:


  • some improvements to auto-complete in Eclipse.
  • better error messages for some special cases.
  • Eclipse now has a command to extract all Custom-Text-Triggers from a map to separate files in the current project.
  • The Wurstpack can now automatically import all files from an import-folder into the map.
  • Some improvements in the Wurstpack updater tool.
  • .j files are now parsed as Jurst files.
Bugfixes:


  • fixed #226, bug in used global variable analysis.
  • fixed #230, read variable analysis.
  • fixed #233, StringCase native was wrong in interpreter.
  • fixed #237, critical bug in localOptimizations->tempMerger.
  • fixed #244: ‘null’ was not translated correctly, when used with a handle bound to a generic type variable.
  • fixed #207, improved flow analysis for closures.
  • many other smaller bugs and possible crashes.
Internal changes:


  • Compiler now uses Antlr4 instead of Cup and Jflex for parsing.
  • Wurst now uses Jmpq2, a new pure Java mpq library written by Crigges. This should eliminate some rare bugs with the old MPQ library and make everything easier to port to different platforms.
 
Level 15
Joined
Aug 7, 2013
Messages
1,337
Question about object creation in Wurst--does it know which fields every object has (i.e. it has reading potential, and not just writing potential)?

For example, suppose I want to take every hero ability in WC3 and make custom versions, each with N levels.

For Lua object generation this was not possible on a general scale, because it did not actually read the fields, but only wrote to them.

So you'd have to know (arbitrarily?) that Blizzard has a shards per wave field, but something like Holy Light doesn't.

So I notice Wurst has "setWC3FieldName" functions, but does it have something like "readWC3FieldName," where it returns the value of that field or null if that field doesn't belong to that object (e.g. trying to see if Holy Light has a shards per wave field before writing to it.).

Otherwise, if you have to know the arbitrary fact that a spell with rawcode Blizzard has a shards per field wave and Holy Light doesn't, it doesn't seem like it would get more functionality than Lua object generation.
 
Last edited:
Level 8
Joined
Nov 20, 2011
Messages
202
Iam not sure what you mean with "reading fields". If you want to get information about the object at compiletime this is not possible.
But wurst got templates for each ability type that exists including nice function names to change fields. Take a look at: https://github.com/peq/WurstScript/...script/lib/objediting/AbilityObjEditing.wurst
And this:
wurstmasterrace.png


There is much more functionality than this. Compiletimefunctions are realy powerful!
 

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
I am actually not sure what part of the Pack uses this executable.
We could probably remove it, as I didn't find any impact yet.

Seems to be related to war3err.dll. That dll could be used to debug warcraft crashes, hitting the op limit and stuff like that. But I think it does not work with the latest version of Warcraft, so we can as well remove it.

If it still works we should add an option to enable it :D

1.1a:
war3err.dll: now logs via popen on logd.exe. Sample logd.exe writes last 1000 lines to bytecode.txt when warcraft crashes/exits.
 

Deleted member 219079

D

Deleted member 219079

Local constants are cool, but if I for example assign it to a unit, does it automatically null it? Since I can't do it then
 
Last edited by a moderator:
Level 8
Joined
Nov 20, 2011
Messages
202
Local constants are cool, but if I for example assign it to a unit, does it automatically null it? Since I can't do it then

Wurst nulls everything for you. Even if you return the value of a local variable:

JASS:
public function handle.doNothing() returns handle
	return this

Will be translated to something like this:

JASS:
function doNothing takes handle h returns handle
	set someGlobal = h
	set h = null
	return someGlobal
endfunction

You can test is out btw. If you type compile into the eclipse console a compiled.j file which contains the mapscript will be created in your project folder.
 

Deleted member 219079

D

Deleted member 219079

That is cool ^^

Also I found a fault in the eclipse plugin:
JASS:
		var t = CreateTrigger()
		TriggerRegisterEnterRectSimple(t, bj_mapInitialPlayableArea)
		TriggerAddCondition(t, Condition(function onEnter))
		t = CreateTrigger()
It nags if I don't use t when it's declared for the first time, but when I declare it for the second time it doesn't.
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
That is cool ^^

Also I found a fault in the eclipse plugin:
JASS:
		var t = CreateTrigger()
		TriggerRegisterEnterRectSimple(t, bj_mapInitialPlayableArea)
		TriggerAddCondition(t, Condition(function onEnter))
		t = CreateTrigger()
It nags if I don't use t when it's declared for the first time, but when I declare it for the second time it doesn't.

It actually does not?
xIlpYOH.png


Remember to save your file.

Or maybe you just didn't set a path in wurst.dependencies.
Please read the manual/instructions (videos)

Also you should change those lines to:
Wurst:
CreateTrigger()..registerEnterRegion(mapRegion, null)..addCondition(Condition(() -> print("no")))

Then again, if you need enter/leave events use this:
http://peeeq.de/code.php?id=7631
 

Deleted member 219079

D

Deleted member 219079

It actually does not?

That's what I meant. Because here:
JASS:
var t = CreateTrigger()
        (use t)
        t = CreateTrigger()
I leak an unused trigger (second t).. Shouldn't the yellow nagging notify about unused variables?


And I don't know who of the developers created enums but he saved my sanity hehe
 
Level 8
Joined
Nov 20, 2011
Messages
202
That's what I meant. Because here:
JASS:
var t = CreateTrigger()
        (use t)
        t = CreateTrigger()
I leak an unused trigger (second t).. Shouldn't the yellow nagging notify about unused variables?


And I don't know who of the developers created enums but he saved my sanity hehe

Warnings aren't perfect atm. You can open an issue on github so peq will fix this issue as soon as he got some time.

Enums wasn't created by wurstscript. Due to the fact that the syntax of wurst is orientated to java wurst got almost all features that java got including enums.
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
I leak an unused trigger (second t).. Shouldn't the yellow nagging notify about unused variables?

Ah, now I understand what you mean.
See Crigges' Answer.

As for
And I don't know who of the developers created enums but he saved my sanity hehe
Enums wasn't created by wurstscript. Due to the fact that the syntax of wurst is orientated to java wurst got almost all features that java got including enums.

I am pretty sure he ment who implemented them in WurstScript, and that was actually me, so yay :grin:

Also, enums in Java are wayyyyyyy different, you should know that Criggos.
 

Deleted member 219079

D

Deleted member 219079

Okay I made a issue thread about it to github. Hope I sent it to right place.

My WurstWE.exe doesn't know where the libraries are at. I'm not talking about the packages I create, the premade ones. It says cannot find lib-package Wurst.

And yes, I run it on admin rights. And I've not moved the WurstWE from the Wurstpack-folder.

attachment.php
 

Attachments

  • asdf.png
    asdf.png
    8.1 KB · Views: 173
Level 23
Joined
Jan 1, 2009
Messages
1,610
As I said, you didn't set the path in wurst.dependencies.
Jondream, please read the instructions/manual, all of this is answered there:
https://peq.github.io/WurstScript/manual.html#eclipse_plugin

The videos are out of date, but explain this too.
When you create a Project in Eclipse, the file is automatically created.
Just set the path to your libfolder.
 

Deleted member 219079

D

Deleted member 219079

I have, before I posted my first post onto this thread, I've gone through the tutorial. Here's a screenshot so you can believe me:
attachment.php

I made the linked folder to the maps folder \ wurst, just as in the documentation. The path is set to a wurstpack and my eclipse has the wurst syntax.

Edit: SOLVED ; I didn't have wurst.dependencies under wurst folder (see the screenshot), so basically frotty was right,, even though I did set the path correctly..
 

Attachments

  • asdf.png
    asdf.png
    26.6 KB · Views: 184
Last edited by a moderator:
Level 14
Joined
Dec 12, 2012
Messages
1,007
Hi,

I have a question, given the following code:

Wurst:
package MyPackage
	function my_max<T>(T first, T second) returns T
		if first > second
			return first
		return second

	init
		print(my_max<int>(5, 3).toString())
endpackage

gives the error "Can not compare with value of type T". Would it be possible to first check whether the current type has a corresponding overload (like int does, like in this example) and if so not throw an error, like it is done in C++?

Also, how much work would it be to make template type deduction for functions automatic, so that one can simple write my_max(5, 3) without passing the template argument explicitly (this can only work for functions of course, not for template classes)?
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Nop this is not possible. You could create a interface Compareable like in java. But remember you are limited to 8000 instances.

Hm ok, thats a pity... would it be possible to add support for this in future releases?

I also have another question about generics. Considering the following code:


Wurst:
package MyPackage
	class Test<T>
		private T t_
		
		construct(T t)
			this.t_ = t
	
		function get() returns T
			return this.t_
			
		function set(T t)
			this.t_ = t
			
	init
		Test<int> t1 = new Test<int>(5) // Works 
		Test<real> t2 = new Test<real>(2.5) // Doesn't work
endpackage

I would imagine that the code compiles to something like this:

JASS:
globals
    integer array Test_integer_t_ // Storage for instances of Test<int>::t_
    real array Test_real_t_ // Storage for instances of Test<real>::t_
endglobals

function Test_integer_get takes integer this returns integer
    return Test_integer_t_[this]
endfunction
function Test_integer_set takes integer this, integer t returns nothing
    set Test_integer_t_[this] = t
endfunction

function Test_real_get takes integer this returns integer
    return Test_real_t_[this]
endfunction
function Test_real_set takes integer this, real t returns nothing
    set Test_real_t_[this] = t
endfunction

// and so on

Why doesn't this just compile like this to two different classes so that one can use generics directly with any type?
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
No, generics only support int-types (and therefore Classes), the other possible values (most handles like unit, item) are casted to their integer value using the fogstate bug.

Look into Typecasting.wurst

In generic modules the Type is unfolded instead.

The generated code is very readable and you can look at it either in eclipse when compiling or in Wurstpack/temp when using Wurstpack.

Also, once again, all of this is in the Manual https://peq.github.io/WurstScript/manual.html#generics
You should really consider reading it...
 

Deleted member 219079

D

Deleted member 219079

It's not that user friendly yet :/

1. It doesn't bring up the list of global constants when I start typing a name of constant. vJass' jasshelper does this just fine, e.g. you start typing EVENT_U - and there's the list.

2. Same as number two but with global functions.

3:
attachment.php

I'm writing a description I don't need that goddamn box atm...

4. Purple is nice color, but it needs more colors imo.. e.g. red BJs

Do I need to post this to the github page too?

And general question, how can I filter which .wurst files from \wurst folder I want to be implemented to my map?

Also I made unit indexer similiar to Cohadar's PUI:
http://www.hiveworkshop.com/forums/pastebin.php?id=pbxznh
 

Attachments

  • asdf.png
    asdf.png
    30.6 KB · Views: 430
Level 23
Joined
Jan 1, 2009
Messages
1,610
It's not that user friendly yet :/

It is. All of what you're saying is working perfectly fine.


1. It doesn't bring up the list of global constants when I start typing a name of constant. vJass' jasshelper does this just fine, e.g. you start typing EVENT_U - and there's the list.

it does.
2014-07-18%2013_47_04-Wurst%20-%20THWContest_lib_objediting_AbilityObjEditing.wurst%20-%20Eclipse.png


2. Same as number two but with global functions.

no.
2014-07-18%2013_49_26-.png



3:
attachment.php

I'm writing a description I don't need that goddamn box atm...

The autocomplete delay can be adjusted or deactivated.
Also a simple click anywhere closes the window.

4. Purple is nice color, but it needs more colors imo.. e.g. red BJs

You can adjust the coloring of supported syntax elements.
BJs are not highlighted, because you simply shouldn't need BJs.
The Stdlib provides a clean alternative to the BJs.

Do I need to post this to the github page too?

No, definitely not!
Youn are only supposed to post real issues after you RTFM.

And general question, how can I filter which .wurst files from \wurst folder I want to be implemented to my map?

By importing or not importing it.

Also I made unit indexer similiar to Cohadar's PUI:
http://www.hiveworkshop.com/forums/pastebin.php?id=pbxznh

Not really, you're missing the index/deindex events.
And, there already is a script for that.
 

Deleted member 219079

D

Deleted member 219079

How did you get that normal function list?
 

Deleted member 219079

D

Deleted member 219079

OH COME ON I've read that page three times! Fine I'll try to figure it out myself...
 

Deleted member 219079

D

Deleted member 219079

Oh I get it now, you refer to "Press Ctrl+space to open the auto complete assistant."

I didn't know it was called auto complete assistant -,-"
 

peq

peq

Level 6
Joined
May 13, 2007
Messages
171
3:
attachment.php

I'm writing a description I don't need that goddamn box atm...

There already is an open issue ( https://github.com/peq/WurstScript/issues/108 ). You can vote for it by posting :+1: in the ticket.

And general question, how can I filter which .wurst files from \wurst folder I want to be implemented to my map?

You can't choose. Everything inside the wurst folder will be used in the map. What is the point of having a file there if it is not used?

If you have more general libraries (like the standard library) you can keep the files in a separate folder, add the folder to your dependencies, and just import the packages you need.


One more comment about the generics: Currently it only supports types which can be represented by an integer, because libraries like hashmaps or attachment libraries want to convert the generic type to integer.
I think in the future we will have more powerful generics, so that you can also use something like strings, if no casts are used. Maybe we will even have bounds on the type parameters as in Java.
But of course this complicates the language, so I don't want to implement it quickly :D

You can still use generic modules, which are a bit more flexible in the type parameters.
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
The generics in Wurst are more like in Java (without the type bounds). They are not like templates in C++.

Also, once again, all of this is in the Manual https://peq.github.io/WurstScript/manual.html#generics
You should really consider reading it...

I already read the manual, don't worry ;)

The question wasn't meant as how it is done internally, but why and if it would possible change in the future. Because Java generics are very limited compared to C++ templates as they are basically just a wrapper for typecasting...

Using a hashtable for every access to a field of a generic class is also quite expensive. Not that I'm someone who is counting nanoseconds, but this is quite a high cost just to get generic types:

Wurst:
package TestPack
	class GenericPack<T>
		private T val
		construct(T t)
			val = t
		function get() returns T
			return val
		function set(T t)
			val = t
	
	class SpecificPack
		private unit val
		construct(unit t)
			val = t
		function get() returns unit
			return val
		function set(unit t)
			val = t

	init
		unit u = CreateUnit(GetLocalPlayer(), 'hfoo', 0.0, 0.0, 0.0)
				
		SpecificPack p1 = new SpecificPack(u)
		GenericPack<unit> p2 = new GenericPack<unit>(u)

		print(p1.get().getName()) // Just an array lookup
		print(p2.get().getName()) // Hashtable lookup!
endpackage

So this comes with quite a high cost... But there are more problems with this approach:

  • Performance drops (already mentioned)
  • Types like real or code can't be used directly to instanciate a generic class, one would have to build a wrapper class around them
  • The user has to implement the typeToIndex and typeFromIndex himself for each trivial built-in datatype like e.g. weapontype
  • If some day the fogstate bug gets fixed, the whole typesystem will break (not that this is likely to happen, but a bit dangerous for a language)

On the other hand all these problems would be fixed with C++ like "generics" (== templates) without adding any real disadvantages.
Just a suggestions.

I think in the future we will have more powerful generics, so that you can also use something like strings, if no casts are used.

That would be great :)
 

Deleted member 219079

D

Deleted member 219079

Since you guys hate struct extends array (honestly what's so bad about it :/ )
How can I fulfill function unit.nearestBase() ?
JASS:
	class Base
		vec2 vec
		construct(real x, real y)
			vec = vec2(x,y)
			
	function unit.nearestBase() returns Base
In vJass I could just
JASS:
function GetNearestBase takes unit u returns integer
    local integer i = Base.max
    local integer tbr = -1
    local real d = maxLookout
    local real bD
    local real uX = GetUnitX(u)
    local real uY = GetUnitY(u)
    if Base.max == -1 then
        return -1
    endif
    loop
        set bD = Pythagoras(uX-Base[i].vec.x,uY-Base[i].vec.y)
        if bD < d then
            set tbr = i
            set d = bD
        endif
        exitwhen i == 0
        set i = i - 1
    endloop
    return tbr
endfunction
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
How can I fulfill function unit.nearestBase() ?

If you want to loop through all the instances of a specific class, import and use the LinkedList module.

Wurst:
import LinkedListModule

class Base
    use LinkedListModule
    vec2 pos

fucntion unit.getNearestBase() returns Base
    let pos = this.getPos()
    var b = Base.first
    var dist = 999999999
    Base nearest = null
    while b != null
        let newDist = b.pos.distanceToVecSquared(pos) 
        if newDist < dist
            dist = newDist
            nearest = b
        b = b.next
    return b

for loops for those modules might also come in the future.
 

Deleted member 219079

D

Deleted member 219079

That works thanks.

I searched for GetClosestWidget here and didn't find any, I can try to do one is it's not done yet.
 

Deleted member 219079

D

Deleted member 219079

Since Group loops are very slow compared to LinkedListModule Loops, we mostly don't use them and therefore no such script exists.
Eh? But there can't be faster way than EnumUnitsInRange() to get closest unit?

Anyway I have just started it, it leaks group and don't have all the types yet, but it's a good start.
 
Level 23
Joined
Jan 1, 2009
Messages
1,610
Eh? But there can't be faster way than EnumUnitsInRange() to get closest unit?

Anyway I have just started it, it leaks group and don't have all the types yet, but it's a good start.

Ah yes, of course I mixed that up.

e: but you should use already provided math functions and preferably at least offer the alternative with a vector.
 
Last edited:
Status
Not open for further replies.
Top