[python] WC3 Mapmaking in Python

Level 6
Joined
Jun 18, 2004
Messages
118
Hello guys,

I've made a project for programming WC3 in Python located here:
Blimba/PyWC3

It translates user python code to lua, and includes it into the map. A summary of features includes:
  • Preprocessing scripts (can be used for script based preplacing of doodads!)
  • Object editing in python source code
  • Code Completion & Syntax highlighting of your favourite IDE
  • Support for maps as "folders" as well as "mpq"
  • Quick maptesting through command line interface
  • Expanding list of modules in the standard library (I welcome people to develop missing modules by pull requests!)
Here's an example to show how easy it is using a pythonic 'TimerUtils':
Python:
from std.index import *
from std.timer import Timer
def timeout():
   t = Timer.get_expired()
   print(t.data,t.data2)
   t.destroy()

def test():
   t = Timer(periodic=False)
   t.data = 5
   t.data2 = 3
   t.start(1.0,timeout)
AddScriptHook(test,MAIN_AFTER)

Or, just use the even easier ITimer class:
Python:
"""

This small addition to the Timer class makes life a lot easier. Instead of having to track timer handles for simple
tasks, this scripts handles everything automatically, and passes whichever data you give the start function.

For example:

def timeout_function(timervar, data1, data2):
    print(data1,data2)

ITimer.start(3.0, timeout_function, "hello", "from ITimer")

This script would print 'hello  from ITimer' after 3 seconds. Please note how we do not require to destroy the timer
manually.

"""
from ..std.timer import *
class ITimer():
    @staticmethod
    def _timeout():
        t = Timer.get_expired()
        try: t._callback(t,*t._args)
        except: print(Error)
        t.destroy()

    @staticmethod
    def start(time,callback,*args):
        t = Timer()
        t._callback = callback
        t._args = args
        t.start(time,ITimer._timeout)

Some more features:

Subclasses for units that have event functions that run on specific events.
Python:
class MyUnit(Unit):
    def on_death(self):
        print(self.name,'dying')
    def on_damaging(self,target):
        print(self.name,'damaging',target.name)
    def on_damaged(self,source):
        print(self.name,'damaged by',source.name)
I'm not planning on added each and every possible PlayerUnitEvent, so instead, you can add one yourself easily by following this example:
Python:
class MyUnit(Unit):
    def on_attacked(self,attacker):
        print(self.name,'attacked by',attacker.name)
# the following code will make the event available for ALL Units (note: only if they have been wrapped in the python wrapper!), as long as they have the on_attacked method, so only call it once!
PlayerUnitEvent(EVENT_PLAYER_UNIT_ATTACKED, "on_attacked", Unit.get_trigger, Unit.get_attacker)

Object editing from the python code. Here's an example of how to add a modified "Channel" ability to a footman using a json formatted table:
Python:
"""ObjEditor
{
    "unit": {
        "hfoo": {
            "uabi": "A000"
        }
    },
    "ability": {
        "ANcl>A000": {
            "aher": {
                "value": 0,
                "level": 0,
                "pointer": 0
            },
            "Ncl3": {
                "value": 1,
                "level": 1,
                "pointer": 3
            }
        }
    }
}
"""

It is still in early development, but please let me know if you are interested, or if you are having any issues using it!

Cheers,

inf
 
Last edited:
Level 12
Joined
Jun 13, 2016
Messages
494
My question was weirdly phrased, I realize that now. I'm mostly confused. If you want script syntax for your Lua code, why would you choose python syntax over jass syntax?

Because Python, like TypeScript and C# (for which Lua transpilers with WC3 workflows exist as well), is a much more mature language with a much more expressive syntax and richer language features than JASS (or its variants). JASS, comparatively, is a very plain and boring language with a lot of very backwards limitations.

I'll turn your question around. If you can use a more expressive language, why bother with JASS?
 
Level 9
Joined
Aug 19, 2008
Messages
492
Because Python, like TypeScript and C# (for which Lua transpilers with WC3 workflows exist as well), is a much more mature language with a much more expressive syntax and richer language features than JASS (or its variants). JASS, comparatively, is a very plain and boring language with a lot of very backwards limitations.
Well obviously.

My confusion came from an incorrect assumption I made about how infrane had written their code. I thought they had written the transpiler from scratch, and so I wondered why they'd choose python (which is indeed more expressive) instead of extending the Jass language to include all those cool things (lambda functions for example). A vJass 2.0 if you will.

Well it turns out this program builds off of an already comprehensive Python-Lua transpiler, so most of their work was already done. So the answer to why they'd choose python syntax over jass syntax I was looking for was "because it's easier to implement".
 
Last edited:
Level 12
Joined
Jan 1, 2018
Messages
526
So the answer to why they'd choose python over lua I was looking for was "because it's easier to implement".
I'd like to add that another reason one might prefer python is simply because someone might already be familiar with the language, thus increasing productivity.
 
Level 6
Joined
Jun 18, 2004
Messages
118
As others have pointed out, indeed I prefer to use python because I use it on a daily basis, and because it makes coding something fast, and is easy to understand for others (including your future self).

Productivity hugely depends on the language your using and its features. For instance, coding in pure jass will take you a small decade to get anything functional. vJass is better, but still very verbose and rather limited. With the native language support for lua, Blizzard opened up a lot more freedom. But, coding in lua directly lacks the OOP that we all enjoy so much. This has caused people to use translators to go from typescript or C# to lua. For me, I am not familiar with either, and would require me to learn another language just for wc3 (I don't see myself using them for anything else atm). Instead, I decided to make a project for python.

Mind you, the python to lua translator is quite rudimentary, so I'm also working on the translator itself to include the more higher-level features of python. However, even in its current shape I can make systems easily in an hour or so which would otherwise perhaps take days of development.

What makes this better than vJass? All I see is syntactic sugar.
Isn't syntaxic sugar all there is to a language in the end? It is essentially what makes machine code understandable by humans, and allows quick development!

Well it turns out this program builds off of an already comprehensive Python-Lua transpiler, so most of their work was already done. So the answer to why they'd choose python syntax over jass syntax I was looking for was "because it's easier to implement".
Not really, because the translator is not fully featured. I'm working on making it reliable, or at least have documentation of the unsupported features in python which are not easily translated. Like drake pointed out, it's mostly about familiarity.
 
Last edited:
Level 6
Joined
Jun 18, 2004
Messages
118
Thanks planetary :) Hope you can find a good use for it.

I've updated the project quite a bit. There's much increased support for odd pythonic features, I've added a whole bunch of libraries, and we have code-based object editing (might still be a bit bugged, as I haven't thoroughly tested it yet).
 
Level 1
Joined
May 6, 2011
Messages
4
Just used it and it's really damn good. I don't really understand some of the complains here. It's just a QoL tool that is pretty damn useful if a) you're already familiar with the language and b) if you're looking for something that can't easily be made in lua for whatever reasons.

Nice job as always iNfraNe.
 
Level 3
Joined
Aug 22, 2005
Messages
44
This is the dankest resource on this site. Until very recently I was chimping out with vJass losing all hope and motivation to continue modding wc3. With just one easy installment of PyWC3 you too can be your own boss and make a map in a language that does not erode the soul.

I'm rewriting one map in python with another map planned for rewrite. I'm using this to learn python and so far it is excellent.

Even if there were benefit over vJass at the language level this tool still saves a lot of time with big maps saving in the world editor. Also allows for saving a lot of time loading map as two maps can share the same code easily. From my actual map I made a copy and scaled the terrain down from 512x512 to 32x32. As long as the object data is synced i can avoid the longer load time of the "real" map. Any of the similar things like TypeScript and C# probably give the same benefit. I went with Python because that is what I want to learn for other reasons.
 
Top