Staredit Network > Forums > SC1 Mapping Tools > Topic: LangUMS - programming language for triggers
LangUMS - programming language for triggers
May 1 2017, 12:15 pm
By: nlight
Pages: < 1 2 3 >
 

May 4 2017, 12:37 am NudeRaider Post #21

We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

Quote from nlight
The compiler does not rely on hypertriggers to work properly, but it does add them automatically and by default (as there is no downside to it I think?). I can easily make it an option to not emit the hypertriggers and everything should still work just slower.
Missed that one at first. Depending on your implementation of hyper triggers it impacts how waits and transmissions can be used or behave when used. There's also the issue of hyper triggers getting wait blocked and neo. And of course, since we're talking about a tool that can easily generate (tens of) thousands of triggers: It impacts performance to the point where it can introduce trigger lag (and quite easily so, if it uses unoptimized conditions).

Allow me that naive question please: You did know about these, right? And just answered from the perspective of the end user?

Because if not, I'd have to question the error checking part I mentioned in my above post, which unfortunately, you have ignored so far. I'm only bringing it up because there also was the issue of race conditions you mentioned, which still I'm surprised you bring up on the topic of triggers. The point is there's a lot of things like that to take into account when creating triggers where sc just won't behave how you'd expect and these 2 comments make me worried you're not deep enough into mapping to know these. BUT I'm just basing this on 2 ambigious comments of yours, so please take no offense if I'm on the wrong track. Just tell me so and I'll shut up and be relieved.




May 4 2017, 7:54 am trgk Post #22



Wow, interesting project!

By just looking at the demo code on the github readme, all examples seems to be compilable without starcraft-side variables: without using any death counters or so. But by seeing your posts here, I believe there should be some mechanism for that.

I've been using epScript for creating eud maps. Since variable assignment and addition/subtraction takes less than 2 triggers to complete in EUD world, We have achived a real run-time computations so we could do something like:

- getting current stage (n, 1~25)
- Get player's username. (lowercased)
- hash it (some complex function.)
- Base24-encode it, effectively generating 6-alphadigit save code.

Example code : https://github.com/phu54321/bwpack/blob/master/src/bulletBase.eps
It's a very eud-oriented code. Lot of cunit editing, but anyway I think it's a good example of what in-game computation should be.

Of course getting user's username should be impossible without help of eud, but I wonder if other kind of runtime computations are possible. Could you give some example codes of runtime arithmetics?

Anyway a great project. I'd like to see it grow. Great thanks for a great tool!

Post has been edited 2 time(s), last time on May 4 2017, 8:05 am by trgk.




May 4 2017, 7:56 pm nlight Post #23



Quote from NudeRaider
Missed that one at first. Depending on your implementation of hyper triggers it impacts how waits and transmissions can be used or behave when used.

You shouldn't use waits with langums as it will block the event loop and stop your event handlers from firing. There are other, much better ways to do timers.

Quote
It impacts performance to the point where it can introduce trigger lag (and quite easily so, if it uses unoptimized conditions).

I'm pretty well aware of the implications on performance. Even now LangUMS generated triggers are more efficient that what a human could do by hand for non-trivial programs.

Quote
Allow me that naive question please: You did know about these, right? And just answered from the perspective of the end user?

Yes, I follow the advice of (very) experienced map makers.

Quote
I'm only bringing it up because there also was the issue of race conditions you mentioned, which still I'm surprised you bring up on the topic of triggers.

Race conditions are absolutely a thing with triggers as they are a parallel machine and you can introduce race conditions in any parallel machine without some form of locking. Most map makers do this locking by hand when necessary. LangUMS does it for you, by default, for everything. And no it doesn't cost you performance or many more triggers than usual.

Quote
you're not deep enough into mapping to know these.

I maybe not (tho I probably know more than you think) but as I said I'm taking advice from people way more experienced than me. I would be happy to hear your suggestions too so if you wish drop by the discord @ https://discord.gg/TNehfve so we can chat more.



None.

May 4 2017, 8:50 pm Wormer Post #24



nlight, looks like you're a specialist in compilers and languages, aren't you? I also have some background in those: as students we had lots of theory and some practice on this topic. This project is indeed very interesting, but in my opinion more from theoretical perspective yet. To prove the contrary you need to convince people make some serious projects with LangUMS. Even better, you're starting your own project and see what's working on practice and what's not.

Quote from nlight
Quote
It impacts performance to the point where it can introduce trigger lag (and quite easily so, if it uses unoptimized conditions).

I'm pretty well aware of the implications on performance. Even now LangUMS generated triggers are more efficient that what a human could do by hand for non-trivial programs.
You see, experienced mappers still think they can write better triggers than any compiler could generate.

In my opinion SC resources are too scarce to throw them about. Every trigger takes up a solid chunk of memory and if you're starting to uncontrollably generate them it leads to large maps (which were the problem before 1.18 and probably are still a problem, but I can't tell for sure if download speed increased significantly with the last patch). Further, as NudeRaider said any additional trigger is getting actually checked every trigger cycle, which eats CPU: some conditions like bring are very expensive in that matter, while others like checking deaths are less.

Your compiler may be useful if you can clearly explain people how triggers are generated and how to control that process. Writing triggers by hand is like writing an assembler code, but I think that with triggering we unfortunately are still in the era where we have only several hundred kilobytes of memory for our program. Back in days assemblers were popular because they allowed people to produce more compact and efficient code (and they are still popular for writing critical code blocks).

To my opinion from practical perspective compiler is a bit overdo. What people really need today are kind of macro capabilities of pre-processor for triggering to generate series of repetitive triggers, to conveniently name their units, locations, death counters, actions and conditions, and probably to make use of some conditional compilation. People also need a convenient way to annotate their triggers, keep track of used locations, death counters, units and etc. Some advanced needs might include tools for grouping triggers into subsystems, specifying subsystems dependency, and probably automatic ordering, but not more. If we dive into too much automation there is always a risk the machine couldn't do something a human may want to do. The tool shouldn't deprive mappers to make the thing they like to do the most: write triggers! The tool should help them to automate tedious repetitive tasks.

Quote from LoveLess
I enjoy writing out triggers as they currently stand with Draft's text triggers in N++, it might take more time and be harder in the end, but I like the busy bee aspect of it. Mainly because I am fucking weird.

Let's take a real example. There recently was a question on UMS assistance forums about how to make a system that gives strategic points to a player that commands the most units in the area. We finally came up with a pretty good solution of only 3 triggers. I'm very interested what will be a solution of this problem written on LangUMS? How many triggers will it generate? How many death counters will it take?

Post has been edited 4 time(s), last time on May 4 2017, 9:01 pm by Wormer.



Some.

May 4 2017, 9:33 pm nlight Post #25



Quote from Wormer
nlight, looks like you're a specialist in compilers and languages, aren't you?

Not really, no. This is the first real compiler I've ever written. I am a moderately decent programmer though and I'm pretty well versed in CS.

Quote
This project is indeed very interesting, but in my opinion more from theoretical perspective yet. To prove the contrary you need to convince people make some serious projects with LangUMS. Even better, you're starting your own project and see what's working on practice and what's not.

There is at least one relatively simple, but playable map in the examples/ folder of the project right now. As far as I'm aware at least 2-3 people are making stuff with LangUMS so we'll have more sample code soon.

Quote
It impacts performance to the point where it can introduce trigger lag (and quite easily so, if it uses unoptimized conditions).

This is a big consideration from the start of the project, from the design of the language to the code gen itself. I believe the emitted triggers right now are really tight. The IR form could use some more optimization, but as long as you write efficient LangUMS code the emitted triggers should be really efficient.

Quote
In my opinion SC resources are too scarce to throw them about.

There is no such thing going on, as I said above keeping trigger count low and ordering conditions for maximum performance have been key goals from the start.

Quote
Every trigger takes up a solid chunk of memory

2.4kb to be exact.

Quote
and if you're starting to uncontrollably generate them

The compiler doesn't do anything uncontrollably.

Quote
Your compiler may be useful if you can clearly explain people how triggers are generated and how to control that process.

If you wish to know exactly how triggers are generated you can always open a langums map and check out the emitted triggers yourself. Or look at the code-gen part of the codebase.

Quote
Writing triggers by hand is like writing an assembler code

Which nobody does anymore, even on the lowest capability devices.

Quote
but I think that with triggering we unfortunately are still in the era where we have only several hundred kilobytes of memory for our program

And LangUMS helps you be sure that's used as efficiently as possible.

Quote
Back in days assemblers were popular because they allowed people to produce more compact and efficient code

And eventually compilers became so good that no human could match their efficiency in reasonable time.

Quote
If we dive into too much automation there is always a risk the machine couldn't do something a human may want to do.

I don't believe this is a concern. One might say that Turing-complete programming languages are quite flexible :)

Quote
The tool shouldn't deprive mappers to make the thing they like to do the most: write triggers! The tool should help them to automate tedious repetitive tasks.

If doing triggers by hand is your thing then you could just pretend this doesn't exist and continue doing it I guess?



None.

May 4 2017, 11:10 pm NudeRaider Post #26

We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

Quote from nlight
You shouldn't use waits with langums as it will block the event loop and stop your event handlers from firing. There are other, much better ways to do timers.
While I tend to agree for waits, (although even those are useful at times because you can control timings with twice the accuracy when using waits, as long as the duration is at least 3 frames,) I'm a bit surprised you just decided that your language should not generate waits so you can ignore the "downsides" (limitations/things you need to be aware of) of hypers.
Also transmissions need to remain a thing because they can't be fully replicated. And those contain waits. So you can't just ignore the problems they can cause.

Btw. how does LangUMS implement hypers? Does it know the different methods and when one is preferable over another?

Also while I haven't looked at the program logic of LangUMS, and thus not know the exact impact, "blocking event loops and handlers" sounds like bad thing. In sc a wait stops the current trigger from continuing (and as a side effect calls another trigger loop) but everything else continues. This may be desired behavior. Does it impact more than just that one trigger in the LangUMS implementation?


Quote from nlight
I'm pretty well aware of the implications on performance. Even now LangUMS generated triggers are more efficient that what a human could do by hand for non-trivial programs.
Good. I'm just reminding you that this is the reason we need an option to do variable length (3+ frames) hypers and (for that 1 in a million guy) to not have them at all.


Quote from nlight
Race conditions are absolutely a thing with triggers as they are a parallel machine and you can introduce race conditions in any parallel machine without some form of locking. Most map makers do this locking by hand when necessary. LangUMS does it for you, by default, for everything. And no it doesn't cost you performance or many more triggers than usual.
As much as I'm open to new information, this is such an established fact, which every half-decent mapper can confirm to you, that I just need to outright tell you "no", right now. There's concrete rules on the order of triggers and I've yet to see a trigger system where triggers would not fire in the expected order. If you think there can be exceptions I'd need an example to discuss it further.


Quote from nlight
I maybe not (tho I probably know more than you think) but as I said I'm taking advice from people way more experienced than me. I would be happy to hear your suggestions too so if you wish drop by the discord @ https://discord.gg/TNehfve so we can chat more.
I'm not about to judge your mapping skills. I rather try to delve into facts, and as a matter of fact, in just a short conversation I uncovered a couple of things that are plain wrong or at least seem to limit the end result. And I don't need to tell you what happens if you write a program where you tell it to do things the wrong way.

So I, too, would like to discuss things further, but I'm not sure on the best way to do it. I can start making a list - or probably it would be helpful if the whole of SEN, and/or other communities joined in - with all the things that come to mind that are odd or simply important to know about the sc trigger engine. But that seems rather tedious with no way of guaranteeing to catch everything.

So sure, we can talk about that on the discord. I just have sketchy times when I am online, so I'm not sure we actually manage to meet there. So maybe the form of a forum discussion would be more useful. Unless you have a large availability window and "can be summoned via the discord on a whim"? :P




May 5 2017, 1:39 pm outlawpoet Post #27



I can sort of serve as a go-between, I think, since I've had a lot of conversations with nlight about what mapmakers are going to want. As designed (or at least on the current build), LangUMS has some severe limitations that will undoubtedly put a lot of people off. It's probably best to be up front with people as to what those currently are, so I will list those here.
  • Mapmakers have no access to switches. Switches are being used en masse for events in order to keep them sequential.
    Quote from nlight
    The conditions are just generated as simple triggers that set switches. And then when you call poll_events() code runs which goes through these switches one by one and then runs the code in the event handler. So it absolutely does not matter who owns the condition as long as it sets the switch.
    It's pretty likely that complex maps or maps with a lot of events will run out of switches.
  • There is no way to specify which player owns a trigger. Systems which are designed on the basis of who owns a particular trigger will have to be redesigned to run as if any arbitrary player can own that trigger.
  • There is no "current player" functionality. To write a trigger that's owned by all players and runs for current player, you have to use "for <PlayerId> in (Player1, Player2, Player3, Player4, Player5, Player6, Player7, Player8) {" -- and you still don't know who owns this trigger, so even if "current player" were to be added here it would be of questionable utility.
  • Mapmakers have very limited control over which death counts get used and how. The compiler decides this too. You can pass a --reg option that allows you to tell the compiler which units it's allowed to use as death counts, but that's all at the moment.
  • You must have a computer player on the map, or a player that cannot leave, since the compiler requires a safe spot to store its calculations. Maps with 8 human players are not currently feasible.
  • Because of the programming language's goal of compiling into triggers directly, a lot of things mapmakers want in terms of making triggers easier to write are not currently possible. Another layer of abstraction still needs to be added on top if things like for loops, appending to a string, or indexing arrays with variables are to work. In its current state it's best to generate the .l script with a separate scripting language of some kind, for even simple maps.

There's more, but this is definitely enough to put people off from using it in its current state. It's probably sufficient to say that I've been consistently giving feedback as to how these design choices impact mapmakers, and that there has been steady improvement. Whether the tool will become usable for certain needs or not remains to be seen, and is also a function of how much people contribute, but it does have potential. nlight is by all appearances a competent programmer, has consistently listened to feedback, and has a lot on the to-do list.

Post has been edited 1 time(s), last time on May 5 2017, 1:50 pm by outlawpoet.



None.

May 5 2017, 6:54 pm Lanthanide Post #28



Yeah, those limitations pretty much invalidate this for most "serious" mapping.

Not surprising, because when something seems too good to be true, it usually is.



None.

May 5 2017, 6:56 pm NudeRaider Post #29

We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

Quote from outlawpoet
  • Mapmakers have no access to switches. Switches are being used en masse for events in order to keep them sequential.
  • There is no way to specify which player owns a trigger. Systems which are designed on the basis of who owns a particular trigger will have to be redesigned to run as if any arbitrary player can own that trigger.
  • There is no "current player" functionality. To write a trigger that's owned by all players and runs for current player, you have to use "for <PlayerId> in (Player1, Player2, Player3, Player4, Player5, Player6, Player7, Player8) {" -- and you still don't know who owns this trigger, so even if "current player" were to be added here it would be of questionable utility.
Those are no problem at all. Controlling trigger owner, and using switches are just tools you learned to use for a certain goal, but as long as langUMS lets me do all the things I used these tools for, this probably just makes things easier without taking away anything.

I'm more concerned about actual functions: Precise timing control using waits, immersive RPG maps using transmissions, having control over correct order of actions and the timeframe in which they will be processed. So if at all possible I'd like some further elaboration on how these work in LangUMS, especially how statements regarding multiple players are going to be processed, because there seems to be confusion about how sc's trigger engine works.

Quote from outlawpoet
  • Mapmakers have very limited control over which death counts get used and how. The compiler decides this too. You can pass a --reg option that allows you to tell the compiler which units it's allowed to use as death counts, but that's all at the moment.
  • You must have a computer player on the map, or a player that cannot leave, since the compiler requires a safe spot to store its calculations. Maps with 8 human players are not currently feasible.
Unfortunate, but understandable. Probably not a deal breaker for the majority of maps.




May 5 2017, 9:29 pm Lanthanide Post #30



Quote from NudeRaider
Those are no problem at all. Controlling trigger owner, and using switches are just tools you learned to use for a certain goal, but as long as langUMS lets me do all the things I used these tools for, this probably just makes things easier without taking away anything.
The fact is, certain pieces of trigger functionality will depend on which player owns them, in order to function properly. If langUMS never makes specific use of player owner for triggers, then that functionality will be impossible to implement using langUMS.

So what you've said is kind of a weird sophist argument: if it can do all the functions I need, then it does what I need it to do. Except that if it doesn't have the capability to assign specific triggers to specific player owners, then it can't do all the functions you need.



None.

May 5 2017, 10:25 pm nlight Post #31



Quote from Lanthanide
The fact is, certain pieces of trigger functionality will depend on which player owns them, in order to function properly. If langUMS never makes specific use of player owner for triggers, then that functionality will be impossible to implement using langUMS.

The compiler will emit the triggers for whatever player makes sense for the specific thing e.g. a bring(Player1, ...) condition will be emitted as a trigger for Player1. The conditions/ actions which are context-sensitive to the current player are always assigned correctly by the compiler because all the built-in functions in LangUMS take the player id as argument so it knows what to do. Meaning the code will run as expected you just don't have _explicit_ control over which trigger is emitted for which player. This is abstracted away for you.

Quote from NudeRaider
I'm more concerned about actual functions: Precise timing control using waits, immersive RPG maps using transmissions, having control over correct order of actions and the timeframe in which they will be processed. So if at all possible I'd like some further elaboration on how these work in LangUMS, especially how statements regarding multiple players are going to be processed, because there seems to be confusion about how sc's trigger engine works.

LangUMS code runs sequentially, meaning all statements in the file are executed one after another. This guarantees that the effects of any statement will be visible to all statements that follow it which makes code much easier to reason about. This is a very nice and strong guarantee but it sacrifices the "parallelism" of the trigger machine, meaning that it's no longer possible for two things to "happen at once" (they never actually happen at once but can happen within the same trigger cycle). LangUMS guarantees that any two triggers the combined result of which depends on their order of execution will always give the same result. In practice this does not mean that a new trigger is emitted for every single statement in the code or that every single statement takes at least 1 cycle to complete. There is a lot of optimization going on and in the end instructions which can be put into a single trigger without affecting the outcome of the program will be.

On the topic of timers. There isn't currently an ideal solution though I am looking for one. You can use waits in langums code but it will understandably block everything until the wait is done. This works for some map designs, doesn't work for others. You can use variables as timers by counting cycles, but that also has its drawbacks. You can of course use the built-in countdown timer if you need only one at a time. There will most likely at some point be a native timer feature that offers an easy and precise way to do time-related stuff not so far in the future.

Post has been edited 2 time(s), last time on May 6 2017, 12:30 am by nlight.



None.

May 5 2017, 10:39 pm Zoan Post #32

Math + Physics + StarCraft = Zoan

Sometimes we want something like Player 1 to detect when Player 2 brings a marine to a location.

e.g.

Example
Players

  • Player 1
  • Conditions

  • Player 2 Brings at least 1 Terran Marine to Location X
  • Actions

  • Display Text("Player 2 has a marine at Location X!")


  • How would we do that using langUMS?



    \:rip\:ooooo\:wob\:ooooo \:angel\: ooooo\:wob\:ooooo\:rip\:

    May 5 2017, 10:50 pm nlight Post #33



    Quote from Zoan
    Sometimes we want something like Player 1 to detect when Player 2 brings a marine to a location.
    How would we do that using langUMS?

    Thank you, finally somebody asking concrete questions :)

    This is how this would look with LangUMS:

    Code
    bring(Player2, AtLeast, 1, TerranMarine, LocationX) => {
     print("Player 2 has a marine at Location X!", Player1);
    }


    Also a sneak peek preview of the upcoming VS Code debugger with support for breakpoints, variable inspection, step-in, etc:


    Post has been edited 1 time(s), last time on May 6 2017, 12:21 am by nlight.



    None.

    May 6 2017, 1:52 am UnholyUrine Post #34



    I think it is amazing that there are so many talented people still working on such an old and dear game.
    nlight, what you're doing is fantastic, but you also need to understand that you didn't give us a lot of information to go by. There're so many nuances to SC that most people of SEN knows by heart now that we'd be questioning rather a further abstraction would be helpful or a detriment.

    I'm not a programming at heart, rather I literally just make maps and do not delve into the programming aspects. So, I am coming from the perspective of a mapmaker with novice understanding of programming, but good knowledge of SC triggers. :hurr:

    What I want to know is how LangUMS can help simplify things further for me from the normal SCMDraft text-based triggers.

    Here's a real example:
    I am making a version of Freeze Tag, where each player can be an SCV, Probe, Drone, or "IT" (like a zealot or something). Each time the player that is "IT" kills an SCV, he becomes the SCV, and the person that died becomes IT after 15 seconds.


    Normally, I would have to create a ton of repetitive triggers where I say

    Example
    Players

  • Player 1, Player 2, Player 3, Player 4, Player 5, Player 6
  • Conditions

  • Current Player kills exactly 1 SCV
  • Actions

  • Move Location X on top of Zealot owned by Current Player
  • Remove Zealot owned by Current Player
  • Create SCV for current player at Location X


  • And repeat for killing 2 scvs, 3 scvs, 4, and etc., up until a point where we know a normal game would not have that many deaths. Can LangUMS help make this more expedient?

    (there's probably a better solution to this, but let's just say that there isn't for now).

    Here's a harder example:
    What if I want to use a Mobile Grid system?
    Let's say I want to use a mobile grid to check whether the player has moved his zealot North, East, South, or West. Using a 1x1 mobile grid centered on his zealot... Would LangUMS be able to help with that?

    Here's another one that I had trouble with before:
    What if, in an RPG, I want to award players with minerals every time they've gained 5000 score of Kills and Razings. From 5k to 95k, they get awarded 5 minerals every 5k. When they reach 100,000 score, I want to award them with 10 minearls every 5k. How does LangUMS deal with this? (how does Oreotriggers deal with this...?)
    Added to this, I want to detect when a person has killed anything, and use it for an ability. Let's say, whenever a player kills something, they spawn a broodling. So now, I need to change the score from Kills to Razings.

    Anyway, these are some questions I have always wondered if third party programming tools can help with, as working on these triggers are extremely tedious and time consuming.



    None.

    May 6 2017, 2:29 am Lanthanide Post #35



    Quote from nlight
    Quote from Zoan
    Sometimes we want something like Player 1 to detect when Player 2 brings a marine to a location.
    How would we do that using langUMS?

    Thank you, finally somebody asking concrete questions :)
    This is pretty much the question I was going to ask next, but wasn't able to because your methods weren't clear.

    So once expressed in LangUMS, who would own the resultant triggers from this logical construction?
    • Player 1 brings at most x marines to location a
    • Player 2 brings at most y marines to location a
    • Player 3 brings at most z marines to location a
    • Create f marines at location a for player 1
    • Create g marines at location a for player 2
    • Create h marines at location a for player 3




    None.

    May 6 2017, 2:53 am Jack Post #36

    >be faceless void >mfw I have no face

    I feel like everyone is missing what this does for mapping. You don't have to care at all how the triggers work out, or who owns them, because the compiler should handle that. If you're using LangUMS you don't need to ever use triggers or look at them, you just use LangUMS.



    Red classic.

    "In short, their absurdities are so extreme that it is painful even to quote them."

    May 6 2017, 3:50 am Zoan Post #37

    Math + Physics + StarCraft = Zoan

    But a lot of what people do with triggers requires them to be very precise, and this sounds like it has some mysterious way of doing triggers which isn't explained.



    \:rip\:ooooo\:wob\:ooooo \:angel\: ooooo\:wob\:ooooo\:rip\:

    May 6 2017, 4:32 am NudeRaider Post #38

    We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

    Quote from Lanthanide
    Quote from NudeRaider
    Those are no problem at all. Controlling trigger owner, and using switches are just tools you learned to use for a certain goal, but as long as langUMS lets me do all the things I used these tools for, this probably just makes things easier without taking away anything.
    The fact is, certain pieces of trigger functionality will depend on which player owns them, in order to function properly. If langUMS never makes specific use of player owner for triggers, then that functionality will be impossible to implement using langUMS.

    So what you've said is kind of a weird sophist argument: if it can do all the functions I need, then it does what I need it to do. Except that if it doesn't have the capability to assign specific triggers to specific player owners, then it can't do all the functions you need.
    I assumed you're going to have to rewire your thought process on how to create game logic. Rather than to think in sc triggers you think in statements.
    For example if you want to do something when any human player brings a unit somewhere. That's your statement. You're wired to do it in a certain way without thinking about it: You create the trigger for the human force, detect unit by current player and give reward to current player. But you wouldn't have to! You could make n triggers for a computer player that checks each player's condition individually and gives reward accordingly. And if the condition is only possible for current player the condition might be run by the specific players, but the action will be run by the computer player.

    Point is it doesn't matter how langums implements it, and which action requires which trigger owner, as long as the end result does what you expect. I hope that example made it less sophist for you. ;)

    He's basically saying that here:
    Quote from nlight
    Quote from Lanthanide
    The fact is, certain pieces of trigger functionality will depend on which player owns them, in order to function properly. If langUMS never makes specific use of player owner for triggers, then that functionality will be impossible to implement using langUMS.

    The compiler will emit the triggers for whatever player makes sense for the specific thing e.g. a bring(Player1, ...) condition will be emitted as a trigger for Player1. The conditions/ actions which are context-sensitive to the current player are always assigned correctly by the compiler because all the built-in functions in LangUMS take the player id as argument so it knows what to do. Meaning the code will run as expected you just don't have _explicit_ control over which trigger is emitted for which player. This is abstracted away for you.



    Quote from nlight
    Quote from NudeRaider
    I'm more concerned about actual functions: Precise timing control using waits, immersive RPG maps using transmissions, having control over correct order of actions and the timeframe in which they will be processed. So if at all possible I'd like some further elaboration on how these work in LangUMS, especially how statements regarding multiple players are going to be processed, because there seems to be confusion about how sc's trigger engine works.

    LangUMS code runs sequentially, meaning all statements in the file are executed one after another. This guarantees that the effects of any statement will be visible to all statements that follow it which makes code much easier to reason about. This is a very nice and strong guarantee but it sacrifices the "parallelism" of the trigger machine, meaning that it's no longer possible for two things to "happen at once" (they never actually happen at once but can happen within the same trigger cycle). LangUMS guarantees that any two triggers the combined result of which depends on their order of execution will always give the same result. In practice this does not mean that a new trigger is emitted for every single statement in the code or that every single statement takes at least 1 cycle to complete. There is a lot of optimization going on and in the end instructions which can be put into a single trigger without affecting the outcome of the program will be.
    That's a relief to hear but you really couldn't word it worse. With triggers there is no parallelism going on, neither actual, nor paraphrased. When a trigger loop starts, EVERYTHING happens sequentially--even game time is frozen--so once you reach your last trigger you can be sure the game state is the same it was for the first trigger (except for the effects of the trigger actions, of course). Even if you wanted to and tried extra hard, you couldn't create a tool that breaks this linearity. So please stop advertising it as LangUMS's strong guarantee and best feature. :/

    Any perceived parallelism comes from the misleading way triggers are usually presented: As a long list that suggests sc processes it from top to bottom, when in reality sc does heavy resorting during runtime: Triggers owned by Forces and All Players are made copies of for each of the players that belong in that group so they are now owned by the individual players. Current Player is resolved into actual players. Then sc picks all of the triggers (in order) of the first player and puts those at the top of the list, followed by all of the triggers of the next player until at last the last trigger of the last player finishes the list. This resorted list is then processed top to bottom, until a wait or EOF is hit.

    I'm sorry nobody (apparently) has told you so yet, because that knowledge should make your advertised optimizing a hell of a lot more efficient because most of the time you now can skip setting switches to enforce trigger order.


    Quote from nlight
    On the topic of timers. There isn't currently an ideal solution though I am looking for one. You can use waits in langums code but it will understandably block everything until the wait is done.
    Understandably if you think in terms of one large main loop, maybe. But not if you think of individual trigger systems, or how it's probably (going to be?) implemented in langums: as functions. I hope you can alleviate that restriction one day, because often times you just want to postpone a certain set of actions not everything that's going on.


    Quote from nlight
    You can use variables as timers by counting cycles, but that also has its drawbacks.
    Good to hear, that's been the standard way of doing things. The only drawback being most of the time you wanted to make sure all calculations are being done within one trigger loop. This is the reason we had to generate a lot of triggers to do binary countoffs and such, but I assume langums is going to integrate these methods, if it hasn't already.


    Quote from nlight
    You can of course use the built-in countdown timer if you need only one at a time. There will most likely at some point be a native timer feature that offers an easy and precise way to do time-related stuff not so far in the future.
    Good. That will be important to increase acceptance of langums.


    Quote from nlight
    Thank you, finally somebody asking concrete questions :)
    As if I didn't ask concrete questions. :rolleyes:
    Those were of a more general nature, but still concrete. As Lanth pointed out we need a general understanding first before we can get specific. So it wasn't helpful that you ignored them.

    Post has been edited 1 time(s), last time on May 6 2017, 4:37 am by NudeRaider.




    May 6 2017, 5:15 am Lanthanide Post #39



    Quote from NudeRaider
    I assumed you're going to have to rewire your thought process on how to create game logic. Rather than to think in sc triggers you think in statements.
    For example if you want to do something when any human player brings a unit somewhere. That's your statement. You're wired to do it in a certain way without thinking about it: You create the trigger for the human force, detect unit by current player and give reward to current player. But you wouldn't have to! You could make n triggers for a computer player that checks each player's condition individually and gives reward accordingly. And if the condition is only possible for current player the condition might be run by the specific players, but the action will be run by the computer player.

    Point is it doesn't matter how langums implements it, and which action requires which trigger owner, as long as the end result does what you expect. I hope that example made it less sophist for you. ;)
    Yes, I understand your point, however I have just presented a trigger that could be owned by any of P1, P2, P3 or P4, and depending on who owns it, the resultant gameplay could be very different. Potentially all 4 of these players could own it, or just 2 of them. But it sounds like LangUMS decides who owns a trigger, so who knows what's going to happen with the one I presented?

    Unless the map author has a way of explicitly stating "this logic runs for player X", then I believe that there will be some triggers that LangUMS cannot generate to fit the map author's intent.



    None.

    May 6 2017, 5:55 am NudeRaider Post #40

    We can't explain the universe, just describe it; and we don't know whether our theories are true, we just know they're not wrong. >Harald Lesch

    Quote from Lanthanide
    • Player 1 brings at most x marines to location a
    • Player 2 brings at most y marines to location a
    • Player 3 brings at most z marines to location a
    • Create f marines at location a for player 1
    • Create g marines at location a for player 2
    • Create h marines at location a for player 3
    If I understand your intent correctly you want to create a number of marines for each of the 3 players if all 3 players fall below a certain marine threshold at the same time.
    However I'm interpreting here, because you didn't state the logical connections. It could also be interpreted to create marines for each player individually when they fall below the threshold.
    So once you made a unambiguous statement LangUMS can do whatever it sees fit to meet the critera. It won't matter if it uses 3 triggers, spreads it across owners, or whatever as long as whatever it does will produce the expected result when run by sc.

    Long story short, I think you're asking the wrong question, by formulating an ambigious statement and expecting a definite answer. (if I understood you correctly)




    Options
    Pages: < 1 2 3 >
      Back to forum
    Please log in to reply to this topic or to report it.
    Members in this topic: None.
    [01:39 am]
    Ultraviolet -- no u elky skeleton guy, I'll use em better
    [10:50 pm]
    Vrael -- Ultraviolet
    Ultraviolet shouted: How about you all send me your minerals instead of washing them into the gambling void? I'm saving up for a new name color and/or glow
    hey cut it out I'm getting all the minerals
    [10:11 pm]
    Ultraviolet -- :P
    [10:11 pm]
    Ultraviolet -- How about you all send me your minerals instead of washing them into the gambling void? I'm saving up for a new name color and/or glow
    [2024-4-17. : 11:50 pm]
    O)FaRTy1billion[MM] -- nice, now i have more than enough
    [2024-4-17. : 11:49 pm]
    O)FaRTy1billion[MM] -- if i don't gamble them away first
    [2024-4-17. : 11:49 pm]
    O)FaRTy1billion[MM] -- o, due to a donation i now have enough minerals to send you minerals
    [2024-4-17. : 3:26 am]
    O)FaRTy1billion[MM] -- i have to ask for minerals first tho cuz i don't have enough to send
    [2024-4-17. : 1:53 am]
    Vrael -- bet u'll ask for my minerals first and then just send me some lousy vespene gas instead
    [2024-4-17. : 1:52 am]
    Vrael -- hah do you think I was born yesterday?
    Please log in to shout.


    Members Online: Sylph-Of-Space, jun3hong