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

[Wurst] [Snippet] InitPackage

Hey, everyone. I'm trying out Wurst, and I think this snippet might help out with initialization heavy processes. (Its' a simple one, only that I can't seem to find it in the Wurst Standard Library)

Wurst:
package InitPackage

/*
InitPackage - A simple Snippet for dealing with op-limits...
------------------------------------------------------------

Credits to Troll-Brain for the ForForce exploit.

Documentation:
--------------

public function onMapStartDelay(code func)
Creates a trigger with a timer that will execute when done.
Makes initialization of certain things easy, but will cause
a lag spike.

public function onMapStart(code func)
internally calls ForForce which allows for doing initialization-
heavy processes without interrupting the main thread.
*/

public function onMapStartDelay(code func)
    CreateTrigger()
        ..registerTimerEvent(0., false)
        ..addCondition(Condition(func))
        ..addCondition(Condition(() -> DestroyTrigger(GetTriggeringTrigger())))

public function onMapStart(code func)
    ForForce(bj_FORCE_PLAYER[0], func)

:) I got the ForForce idea from TrollBrain so he gets some of the credit for this.
 
Last edited:

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
Hi,

I don't understand what this is.

What do you mean it's for initialization heavy processes?

Is this for preloading a lot of content at map start but not during map loading screen?

If so, I'm surpried there isn't some documentation provided. I also would have guessed to call it something like `onMapStart` or similar. Can you explain?

Thanks,
 
^^ Hello, Cokemon

If I recall, there was something that stated that you shouldn't insert initialization-heavy processes inside an init portion in Wurst, so I thought of writing this as practice for Wurst, and as a way to remove the constraint of those who are coding in Wurst.

I define an initialization-heavy process as something that prevents the map from loading correctly due to op-limit breach.
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
Thanks for the info and for the documentation :)

> Credits to Troll-Brain for the ForForce exploit.

I appreciate giving the credit but I'm not familiar with the "exploit". Can you explain it?

A good rule of thumb is: if you have some code that is doing something not obvious (or even confusing), it may be a good sign to add comments.

onInitDelay:

* Is there any reason not to just use a timer? For example `doAfter(0., function func)` (import ClosureTimers)

* I'm confused about the name. Is there a reason the style of this function name doesn't match `onMapStart`?

* Your documentation explains what the two functions do, but doesn't explain why they're different. I'm guessing that one of them will happen before the other? Can you explain?
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
I think you haven't addressed my feedback yet:

> I appreciate giving the credit but I'm not familiar with the "exploit". Can you explain it?

What is the exploit, and where does it occur? Why use it instead of alternatives? The answer should be written in a code comment.

> Is there any reason not to just use a timer? For example `doAfter(0., function func)` (import ClosureTimers)

It seems to me that the trigger used here isn't necessary.

> I'm confused about the name. Is there a reason the style of this function name doesn't match `onMapStart`?

I think the names onInitDelay and onMapStart aren't very clear in what's different between the two.

> Your documentation explains what the two functions do, but doesn't explain why they're different. I'm guessing that one of them will happen before the other? Can you explain?

Thanks for the explanation on this one, but there is still missing explanation in the code. Can you add a code comment?
 
^^
> I appreciate giving the credit but I'm not familiar with the "exploit". Can you explain it?

The exploit is what virtually allows cheating the op limit (figure of speech). For example, a loop about incrementing a certain integer will run no more than 1000 times, which could be problematic if you want it to run more than 2000 times.

> Is there any reason not to just use a timer? For example `doAfter(0., function func)` (import ClosureTimers)

I tried doing so with a timer, but I realized I can only attach one function, which could be inconvenient / annoying for someone who wants to initialize something. (Inconvenient one-liner, such as destroying the object after use.)

> I'm confused about the name. Is there a reason the style of this function name doesn't match `onMapStart`?

I thought a bit hard on this, and I decided to rename onInitDelay to onMapStartDelay, for consistency.
 

Cokemonkey11

Code Reviewer
Level 29
Joined
May 9, 2006
Messages
3,516
> The exploit is what virtually allows cheating the op limit (figure of speech). For example, a loop about incrementing a certain integer will run no more than 1000 times, which could be problematic if you want it to run more than 2000 times.

Okay, thanks for explaining. I think I would phrase this as "allows us to reset the oplimit" (since it's known to be value that can be reset).

There are other methods to resetting op-limit, for example `ExecFunc` - can you comment on the merits of ForForce method? What makes it better?

> but I realized I can only attach one function

`doAfter()` from ClosureTimers will work no problem MUI.

> I thought a bit hard on this, and I decided to rename onInitDelay to onMapStartDelay, for consistency.

Great choice - I also prefer this.
 
Level 23
Joined
Jan 1, 2009
Messages
1,608
I don't think this should be a package.
@Cokemonkey11 The nice thing about ForForce over ExecuteFunc is that it takes a code param instead of string.

However, if you have heavy init-blocks, just use a timer/forcForce directly?
Wurst:
init
    doAfter(0.1, () -> begin
   
    end)

    ForForce(bj_FORCE_ALL_PLAYERS, () -> begin
   
    end)

    ForForce(bj_FORCE_ALL_PLAYERS, () -> myDelayInit())

Or if you want it grouped, use callFunctionsWithAnnotation and annotate the delayed init functions.
 
Top