vile's Map Making Tips!

vile

New Member
Reaction score
8
Hi there everyone. I've been scripting with jass on warcraft 3 for 5 years now,
making several maps that me and my friends had alot of fun with, Age of Myths
is one of them.

During my experience with my map making, I learned alot, and I'd like to share
that knowledge with you, map makers that mess with jass or gui, so you won't have to
make the same mistakes that I made. I am not comparing my skills to famous known
brilliant jassers and coders like Vexorian/PitzerMike/PipeDream, but I have more experience
when it comes to map bugs, and that's where I'm getting at.

Map making is a bitch, I can tell you that. You should avoid the things I am listing
now, do whatever you want, but I feel I should say this.

Before I start though I want to point out that you should use Vexorian's NewGen Jass
pack, download it from http://wc3campaigns.net/showthread.php?goto=newpost&t=90999
and use it, to avoid lame crashes from the editor for minor coding mistakes and avoid triggeraction leaks for jass users.
Therefore, I will only post here bugs in the game itself, and not with world editor
crashing, since it can be easily avoided by using something else then the usual
world editor.
-----------------------------------------------

(Bug) Using a different buff for a spell that isn't its original buff will most likely
cause crashes in multiplayer gaming.
(Solution) Don't use a Freezing Breath buff on a War Stomp spell for example.
Modify the original buff that War Stomp uses and change whatever you want there.

(Bug) Don't ever try to move nullified lightning effect variables, it will instantly
cause a crash.
(Solution)
Always set a lightning variable to null whenever you finish using it and
destroying it, and use the following function(s) to move them:
Code:
function LightningMove takes lightning l, boolean checkvisibility, real x1, real y1, real x2, real y2 returns nothing
    if l!=null then
        call MoveLightning(l,checkvisibility,x1,y1,x2,y2)
    endif
endfunction
Code:
function LightningMoveEx takes lightning l, boolean checkvisibility, real x1, real y1, real z1, real x2, real y2, real z2 returns nothing
    if l!=null then
        call MoveLightningEx(l,checkvisibility,x1,y1,z1,x2,y2,z2)
    endif
endfunction

(Bug) Using an item ability that has a chance to affect summons/units/heroes, you need to use
an ability to cause that effect. If you use the same chance within the chance, the map will
crash once you get that item.
(Solution) Don't do it :) Make sure you put an ability and not the chance itself.


(Bug) Moving a unit with SetUnitX and SetUnitY outside the map bounds can cause
crashes.
(Solution) Don't use the original SetUnitX and SetUnitY to move units, use this function
instead to avoid moving the unit outside the map bounds and cause a crash:
Code:
function SetUnitXY takes unit u, real x, real y returns nothing
     if x<GetRectMaxX(bj_mapInitialPlayableArea) and x>GetRectMinX(bj_mapInitialPlayableArea) and y<GetRectMaxY(bj_mapInitialPlayableArea) and y>GetRectMinY(bj_mapInitialPlayableArea) then
       call SetUnitX(u,x)
       call SetUnitY(u,y)
     endif
endfunction

(Bug) Boolean Expressions (boolexpr) usually fails ALOT in the map. They will sometimes
cause your conditions to behave in a weird way.
(Solution) Don't use them, use null instead and then in the trigger actions themselves
use an if/then/else comparision.

(Bug) If you use alot of game cache functions, your map will behave in a weird way
and will bug out most timers and functions.
(Solution) Don't use game cache. I learned it the hard way with alot of version
releases. Don't use handle vars. Don't use the return bug (H2I). Don't
use tables. Use GLOBAL VARIABLES. Use Vexorian's Jass New Gen Pack on
www.wc3campaigns.net and then you can declare globals through triggers
and you can avoid triggeraction leaks by declaring them as globals,
something you cant do through GUI's variable making interface.
It's your call, I just recommend what I experienced.

(Bug) Destroying timers is problematic with jass. Using them just caused me trouble. I learned
not to trust that method.
(Solution) If you need a timer that you use constantly, you can declare a global timer,
create it and then just pause/start it whenever you use it, without destroying
it. For spells, I personally used triggers. When destroying them I didn't have
any weird problems. TriggerRegisterTimerEvent does the trick. Also, don't
ever null timers, triggeractions, triggerconditions, or triggers. It will
leak but it's a very minor leak, unnoticable. Again, your call. I'm just
saying from experience.

I recommend reading http://wc3campaigns.net/showthread.php?t=80693 for known
world editor bugs if you're still using it.

MANY MANY of you will not agree with me on several cases here, and I completely understand, but everyone has their own opinions on how to make their map, I just recommend what I think; you should do what you think.

I also want to say that without any offense to Vexorian, I do NOT recommend using
vJass newgen pack's features other then global declerations. Don't use structs
for example; every struct variable you create will be set as a global array. Who needs
an array for every variable? I dont. It just eats up memory. Just make your own
stuff, that's what I think anyways.

Thanks for reading, and I hope I saved you alot of time in your mapmaking.
 

Tom Jones

N/A
Reaction score
437
>(Bug) If you use alot of game cache functions, your map will behave in a weird way
and will bug out most timers and functions.
(Solution) Don't use game cache. I learned it the hard way with alot of version
releases. Don't use handle vars. Don't use the return bug (H2I). Don't
use tables. Use GLOBAL VARIABLES. Use Vexorian's Jass New Gen Pack on
www.wc3campaigns.net and then you can declare globals through triggers
and you can avoid triggeraction leaks by declaring them as globals,
something you cant do through GUI's variable making interface.
It's your call, I just recommend what I experienced.

Globals can't replace handle vars. Structures can, which is the obvious choice if you allready got Jass NewGen Pack.
 

vile

New Member
Reaction score
8
Nope, its a fact, look at my map. I made the entire spells and systems Multi Instanceable without a single code of handle vars. Global arrays can help you achieve whatever you want, and in many many cases, you dont have to use arrays. Structs creates a whole list of functions, which arent really needed for every single spell.

STRUCTS -ARE- Global arrays. Look at the war3map.j after declaring structs and see what I mean.
Structs dont replace game cache, they're just global arrays as an alternative.
 

SFilip

Gone but not forgotten
Reaction score
634
> I made the entire spells and systems Multi Instanceable without a single code of handle vars.
Any example? I don't see how can you make certain spells completely MUI without H2I.
 

Tom Jones

N/A
Reaction score
437
>STRUCTS -ARE- Global arrays. Look at the war3map.j after declaring structs and see what I mean.
Structs dont replace game cache, they're just global arrays as an alternative.

True, but they work differently. If you got a system that stores the values in the arrays properly, then yes global arrays can easily be used instead of handle vars. I can't see how declaring globals troughout the script can make anything MUI, or be better than handle vars.
 

Vexorian

Why no custom sig?
Reaction score
187
  • H2I doesn't cause any bug.
  • Gamecache does not cause any bug either
  • I2(Any handle type that gets ids larger than 0x10000) may cause errors if handled wrongly with local variables that are set to null. In fact it will even cause you issues with variables themselves. Just get rid of it. This includes all "Handle vars/Tables/csarrays" that return values other than integer, real, boolean or string.
  • DestroyTrigger causes issues.
  • DestroyTimer causes issues.
  • DestroyTrigger is a bigger threat than DestroyTimer, yes it is.
  • There is no need to attach anything to timers, there is no need to have more than 2 timers, this alone will make everything safer.
  • A global array declaration doesn't take any memory space until you use it. Indexes just take memory once assigned.
  • Don't call any natives on null / removed things, this is always a direct result of worse design, think before coding.
  • Not-nulling might appear to help, it is just an illusion, the problem is bigger and just not nulling stuff exchanges the symptons of your coding mistakes with memory leaks. And not-nulling just lowers the odds of problems doesn't completely prevent them.
  • Please don't ever use null as condition for enums, it causes serious issues including a very strange memory leak, in fact, GroupEnums must use a global group object that is not to be destroyed after the enum, and you must always use constant boolexprs like for example BOOLEXPR_TRUE or BOOLEXPR_FALSE (that would hold functions that return true or false)
  • Condition() doesn't "leak" it always creates the same handle.
  • Using DestroyBoolexpr on a boolexpr returned by Condition() causes issues.
  • TriggerAddCondition does not 'leak' there is no need to remove the condition , DestroyTrigger handles it.
  • It is possible that using Conditions instead of triggeractions fixes the problems raised by DestroyTrigger, no proof is available yet.
  • But using conditions over actions is certainly faster, and it is much less problematic.



Global arrays (or structs) are just better because they prevent the 3rd point and are also faster. Don't ever think that H2I or gamecache are problematic, they are not and we got proof. It is the typecast from integer to handle which may cause issues.

Because of this GetHandleHandle , GetHandleUnit , GetAttachedUnit , GetAttachedObject, GetTableItem, GetTableUnit, etc should be dismissed, but don't underestimate GetHandleInt , GetTableReal , and the such, gamecache is still the best way to have a 2D hash table.



---
structs are dynamic, globals are not. You may type everything manually, but is it worth it?

Also:

Is:
+ - b c * + a b - d c

The same as:
(b-c) + (a + b)*(d-c)
?

Do not underestimate the difference between sufix notation and prefix notation. Just like last sample shows how prefix is very different to infix.

And you are free to use or not use whatever you want. But there's absolutely not a good reason to prevent usage of structs, the "extra functions" are meaning less space, the extra variables are as well. And you do need a whole array for each value anyways. The only reasons I can think for not to use structs or wewarlock's 'classes' or anything equivalent would be to be a victim of the NIH syndrome . (Not Invented Here) or that you actually prefer BIGPREFIX_SMALLPREFIX_NAME[x] over x.name . Or that you love typing the same code over and over and over.

--
Tom Jones: > Is great for emails, but in forums, for readability's sake, please use
 

SFilip

Gone but not forgotten
Reaction score
634
> DestroyTrigger causes issues.
> DestroyTimer causes issues.
> DestroyTrigger is a bigger threat than DestroyTimer, yes it is.
> typecast from integer to handle which may cause issues

Out of curiosity...what kind of issues might these be?
 

Vexorian

Why no custom sig?
Reaction score
187
The stack is corrupted, then indexes allocated for handles might repeat, then you have multiple handles with the same index and your map literally becomes chaos.

Lately it seems that the real issue is I2Handle and DestroyTrigger is just a catalysts on the bug raising, I just got a very stable spell that still uses DestroyTrigger too much but the bugs are gone (After casting a lot of times you would see it fail) , I actually think this is thanks to avoiding I2Handle stuff completelly . But there's no way to know this is highly undeterministic...
 

vile

New Member
Reaction score
8
So I guess having hundreds of users playing my map every single day while I play with them is not a proof for everything I say, yet when you say it without any proof, you're right?

Doesn't sound too good, the proofs are speaking out loud; trigger type timers are not problematic. H2I is problematic. Game cache is problematic. Handle vars are problematic. You should make a map yourself with your own systems and handle vars and play it for years, see it yourself. And i'm not the only one experiencing these things. Rising Dusk already did and already posted it on wc3campaigns. Fulla experienced it with his hero revival system.

Seriously, I just posted my opinions, you may post yours vex, but please don't say I have no proofs.
Every single thing you said is by your map making experience, or by coding experience? You just test stuff with test maps and dont actually get to play on heavy maps that uses all of that code.

I made and played it enough to know what bugs and what doesn't.

Please don't ever use null as condition for enums
I do and it works perfectly without a single flaw.
My map hasn't got a single crash in it, not a single timer is freezing like H2I causes them to, not a single projectile just hangs in the air like GC usually did on my older maps.

Not-nulling might appear to help
It does help, nulling caused the above errors.

You can't argue with results, or compare them to little test maps that you create.
The big fish are caught in a fish pool, not in the ocean.

A global array declaration doesn't take any memory space until you use it. Indexes just take memory once assigned.
Where are you getting this information from? I really don't get it.

For sums, everyone should use or not use what they want, you post you opinion against mine (and i knew you would), but you should base your opinions on facts, not myths.
 

Tom Jones

N/A
Reaction score
437
For Vexorians sake:
H2I is problematic. Game cache is problematic. Handle vars are problematic.
No it isn't... If you experience problems using these, your simply doing something wrong. H2I isn't problematic, it's a blessing. Handle vars and gamecaches in general aren't problematic either, they are just slow.

And if you think that 100's of people playing your map every single day proves your point, have a look at DotA which uses game caches. That should prove my point, but it doesn't 'cause it's a ridiculous argument. Vexorians has proven, confirmed, and described all of the things he mentioned, the triggercondition part being the only exception. You are of course entitled to your opinion, as everybody else is, it just doesn't make it right. I can cope with the fact that you wan't to share your knowlegde with other people, but I can't cope with the fact, that your telling people what your saying is the only right thing to do. If that wasn't your intention, then we misunderstood each other along the way.
 

chovynz

We are all noobs! in different states of Noobism!
Reaction score
130
Vex & Vile: For about 5% of mappers this information is useful and understandable. But for the other 95%...we don't understand a word either of you are saying. I've seen you guys fight this kinda of thing out on WC3C as well. I don't really want to see TH become a battelground for your opinions on H2I, structs and etc.

It's obvious to me that both of you know FAR more about Jass and programming than I ever will (mainly because I can't be bothered learning it.) But you're both being silly about what's the best way/correct way/only way to code.

I have a huge respect for both of you for what you've done for the WC3 community, but I think you guys need to chill out. It only confuses the majority when two "experts" do this kind of thing.
 

Fulla

Evil Overlord
Reaction score
31
Well my only advice would be, to avoid using Tables when you can simply and easily substitute globals.

For example, a very basic revival trigger I had:
- A Hero dies
- Create a timer expired after 4 seconds * level of Hero.
- Upon expiration revive Hero

Ever few games a player would have his Hero not revive?
The trigger was very basic and simple with a few string/timer attachments. However, upon changing to global for timers & globals for heroes instead of using tables this problem vanished.

====

I still use gamecache for my item system and tables for alot of spells.
I try where I can to use globals instead, which is faster than tables anyways. So as previously said, id only use tables etc. where you have to.
 

emjlr3

Change can be a good thing
Reaction score
395
i think some of these are more situational then anything else, or more dependant on who is doing the coding

I have no probs with boolexprs, timers, different buffs, or game cache, however the rest is pretty self intuitive

basically, don't do anything stupid, and you will end up ok
 

Ninja_sheep

Heavy is credit to team!
Reaction score
64
Me (the n00000b). Shall i follow those tipps? Or are they jsut for advanced users? you say many things i dont understand :D
 

emjlr3

Change can be a good thing
Reaction score
395
if you dont understand them how could you possibly follow them

for now on lets not post stupid things, and the world will be a much better place
 

vile

New Member
Reaction score
8
Meh, I didnt "fight" or anything, I just stated my opinions and tips about map making, simply for one cause and one cause only: Not to let anyone else do the same mistakes and save others time.
Every time I try to help the community I get bashed in one way or another.
I told myself I wont do it again but I keep seeing mistakes and I say to myself it's just too bad.

Unfortunately some people tend to argue whenever they can. These are my opinions, and anyone can do whatever he wants with them. There is no need to eliminate them.
 

chovynz

We are all noobs! in different states of Noobism!
Reaction score
130
Well, Thank you for your tips. I do appreciate them. I read everything I can on anything to do with WC3 map making. I liked the Lightning tip. I use lightening lots so that'll help me.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1
  • The Helper The Helper:
    New recipe is another summer dessert Berry and Peach Cheesecake - https://www.thehelper.net/threads/recipe-berry-and-peach-cheesecake.194169/

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top