Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[Mapping] How to get the "Compress Names" optimizer function work

Discussion in '"Graveyard"' started by Luorax, Mar 3, 2012.

  1. Luorax

    Luorax

    Joined:
    Aug 7, 2009
    Messages:
    1,301
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Introduction
    Short variable names are not only faster, but reduce the script's total size. It's a known fact. But nowadays many people write their submissed systems/snippets - even the complicited ones - that takes more time understing, than writing, because of the super-annoying short names. Their reason(/excuse): The "Compress Names" function of Vexorian's optimizer is broken, and as said above, it's faster this way. Well, this little tutorial will show you how you can get it work, so that this annoying habit can finally go to an end.

    Tools Needed
    1. Wc3mapoptimizer
    2. Ladik's MPQ Editor
    3. Notepad++ (Optional)

    Let's Begin!

    1, First of all, we need a map. Open the optimizer, browse the map, and set it up according to your liking. I'll make it like this:

    Picture
    [​IMG]


    2, Click "Save optimized as..." and save it. This will optimize everything and create two files: the optimized map, and the script file. Go and rename it immediately to "war3map.j"

    Picture
    [​IMG]


    3, Open the generated script file. Natives must be directly under global declaration, after the keyword
    endglobals
    . The optimizer generates some garbage functions and places them inbetween the two of them; locate all the custom declared natives and move them where they belong.

    Picture
    [​IMG]


    4, Open Ladik's awesome MPQ editor. We know how big our script file is; sort files by file size, locate the script file, and delete it. If you're not sure it's the right file, open it by double-clicking on it.

    Picture
    [​IMG]


    5, Go to Operations -> Add File(S), or press Ctrl+A. Locate our fixed script file, and import it. When the window pops up, select "Compress+Encrypt" and "Zlib" compression. Then go to File -> Close all MPQ's.

    Picture
    [​IMG]

    Picture
    [​IMG]


    6, Open your WarCraft 3 and test it. It should work by now.


    ExecuteFunc/TriggerRegisterVariableEvent natives
    Those two natives have a string parameter; one of them is a function name, the other one is a variable name. If you pass a concatenated string, the optimizer will just ignore it. It can also be fixed by editing the "war3map.j" script file, when fixing the native bug, but you have to go through the entire file and find all these function calls, plus their arguments' shortened names. It's hard and time-consuming.
    Getting rid of those ExecuteFunc/TriggerRegisterVariableEvent calls is simple, you have many options:
    • Use either
      .evaluate
      or
      .evaluate
      ;
    • Evaluate triggers manually;
    • Use this snippet.

    Credits
    • BBQ, for revealing why natives break maps
    • Vexorian & Ladik, for their tools
     

    Attached Files:

    Last edited: Mar 6, 2012
  2. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I gotta try Ladik's MPQ Editor, looks pretty sweet!
     
  3. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,413
    Resources:
    1
    JASS:
    1
    Resources:
    1
    It's strange that Bribe didn't talked about ExecuteFunc and TriggerRegisterVariableEvent.
     
  4. Luorax

    Luorax

    Joined:
    Aug 7, 2009
    Messages:
    1,301
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Well, I wanted to include them too, but they were working fine for me. These didn't break my map:

    Code (vJASS):
    private function Foo takes nothing returns nothing
        call ExecuteFunc(SCOPE_PRIVATE+"Test")
        call ExecuteFunc("Temp"+"Test")
        call TriggerRegisterVariableEvent(CreateTrigger(),SCOPE_PRIVATE,EQUAL,100)
    endfunction


    Of course if you can tell me in which situations they fail to work, I'll include them too.

    Yea, I've encountered many MPQ editors, this one was the only one that worked so far - and not even it's older versions.
     
  5. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Those two won't stop your map from opening or loading, it's just that Vexorian's Optimizer compresses the name of the function/variable but does not identify the string concatenators.

    There is no quick & dirty fix to make it work. Your only chance is to go through the entire map script and make some manual adjustments. Good luck finding all functions/variables and what their original names were. Oh wait, 99.99% of maps won't be doing this crazy concatenation stuff any way. Unless you use Nestharus' Event library and register triggers instead of boolexpr.
     
  6. Luorax

    Luorax

    Joined:
    Aug 7, 2009
    Messages:
    1,301
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Yea, I see - you're right, it was "Foo__Test" passed to the
    ExecuteFunc
    call, however that function did not even exist anymore. I just didn't pay attention to it.
    So, in that case, it's not the tutorials task to cover them; plus, on the other hand, as Bribe said, noone uses them - they can also be avoided easily.

    EDIT: okay, I did mention them in the tutorial, and added a few ways to avoid them. Anything else left I should do?
     
  7. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Well, ExecuteFunc with I2S concatenation is a rare but sometimes used utility. I saw a guy who wrote an AI script which used this technique, it was the function name + a unit raw code, but he could have made a long if/then/else block to handle this process so it was not really a problem.

    Besides, each ExecuteFunc call has the weight of like 300 function calls. So a huge if/then/else block will still be wildly more efficient.
     
  8. Luorax

    Luorax

    Joined:
    Aug 7, 2009
    Messages:
    1,301
    Resources:
    1
    Maps:
    1
    Resources:
    1
    As you said it yourself: it can be avoided. Sometimes the other way is even faster, and saves you a lot of time if you want to get it work with the optimizer.
     
  9. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,413
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I suppose that TriggerRegisterVariableEvent is not that much efficient neither, but the good thing with it : it's a real event, so you can disable the custom event based on it simply by turning off the trigger (no need of extra checks IsTriggerEnabled, or check if the trigger was destroyed, like Event by Jesus4Lyf).
     
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    The bad thing about it is that triggers are really ugly to work with, which is why in the Advent library I eliminated user-accessible triggers altogether.
     
  11. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,413
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Sometimes i prefer using several events on the same trigger, than splitting the code.
    I would say that it even makes more sense (still sometimes)
     
  12. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I agree, for WarChasers 2, I use a lot of if/else blocks because it's just more organized that way to me (makes it easier to edit a lot of times).
     
  13. Troll-Brain

    Troll-Brain

    Joined:
    Apr 27, 2008
    Messages:
    2,413
    Resources:
    1
    JASS:
    1
    Resources:
    1
    But you eliminate this possibility in some way, if you don't support triggers with custom events.
     
  14. Vexorian

    Vexorian

    Joined:
    Mar 11, 2004
    Messages:
    649
    Resources:
    1
    Maps:
    1
    Resources:
    1
    SCOPE_PRIVATE is a constant. And when Jasshelper sees something like "constant"+"constant", it actually evaluates it to "constantconstant". You would have to test with some variables.
     
  15. Luorax

    Luorax

    Joined:
    Aug 7, 2009
    Messages:
    1,301
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Hmm, that's true - forgot about constant inlining.

    BTW, considering you're here: why don't you fix the optimizer? These are minor things to fix and yet major problems; just check any of Nestharus' snippets and you'll see why. Many, many people would appreciate it.
     
  16. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    He updated the optimizer to 5, but 5 still has broken compress names... not sure what the bug is if $ is valid for hexadecimal.

    Also, for some reason, it adds bj code... I ran it w/ bj optimizer disabled and 0 bj code in the entire map. I looked at the original script and typed bj_ to see if there was any and found none (the war3map.j file in the mpq archive). I looked in the optimized map and typed bj_ and found tons... I also tried it with bj optimizer enabled and the exact same added code was there.

    So optimizer now has additional problems ; ). I'm not sure if the old version did this or not as I never looked ;o.


    Btw, 5 also failed to remove all of the non handle constants =o.
     
  17. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,375
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Jasshelper does not concatenate constant strings
     
  18. Vexorian

    Vexorian

    Joined:
    Mar 11, 2004
    Messages:
    649
    Resources:
    1
    Maps:
    1
    Resources:
    1
    -- It does , at least I know SCOPE_PREFIX is concatenated to allow the optimizer to work.

    Because nobody reports problems the required way. That dude out there would rather find any excuse to begin coding short variable names rather than report anything.
     
  19. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,146
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Believe, I would rather code long. My scripts start out with normal names and are only later changed to short names.


    I also recall reporting this 1 year ago with Bribe. After a few months, we just assumed that you were never going to fix it ;p.
     
  20. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,429
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    As for the tutorial, it is nice. However, are the images not showing up for anyone else? Or is it just me?

    Heh, this line is a bit confusing. You say it is hard yet simple. ;) Unless you are referring to something else.

    I'll approve this soon after confirming a few things.

    As for the actual problem with the optimizer, I recommend that someone make a test map with a script that does not work properly after being optimized. (post the options used and everything) That way, if Vexorian wants to fix it, then he can use that as a test map to confirm whether the changes made fix the problem. (unless he does not have wc3 installed anymore)