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 6 2017, 9:14 am Lanthanide Post #41



Quote from NudeRaider
However I'm interpreting here, because you didn't state the logical connections.
Not sure what you mean. This is a single trigger.

Depending on which player it's owned by, can drastically change the results of the trigger, because if it runs for P1, that may prevent it running from P2. Maybe the map author wants it to run for P1-3, or maybe they want it to only run for P4. How does LangUMS make the right decision for who the owners of the generated triggers should be?



None.

May 6 2017, 9:53 am NudeRaider Post #42

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

You called it logical construction. :P

But okay, if it's a (single) trigger, then we have 3 conditions that all have to be true, and 3 actions that will all run. (= like I assumed)
Who owns it, doesn't even impact the outcome since there's no current player involved.
But it's influenced by how many owners you add, because that means it will create copies and potentially fire multiple times. But that's the equivalent to another trigger loops (just speeds up the giving).

So what I said applies: Why is it important if LangUMS creates the resultant triggers for the human force, a computer player or even splits it up? (Again, as long as it doesn't break the statement you formulated.)




May 6 2017, 11:23 am nlight Post #43



Quote from Lanthanide
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

I'm not sure if this is supposed to be an example of one trigger or three so here are both answers.

If it's one trigger the LangUMS code is:
Code
global marine_count[3];

bring(Player1, AtMost, x, TerranMarine, LocationA),
bring(Player2, AtMost, y, TerranMarine, LocationA),
bring(Player3, AtMost, z, TerranMarine, LocationA) => {
   spawn(TerranMarine, Player1, marine_count[Player1], LocationA);
   spawn(TerranMarine, Player2, marine_count[Player2], LocationA);
   spawn(TerranMarine, Player3, marine_count[Player3], LocationA);
}


Who owns the emitted triggers I really can't tell you that easily. There is a lot going on in the background that decides who owns what. Ideally this whole code will be emitted as 1 trigger owned by whatever of these players makes sense (or maybe the reserved player will own it) but I can't promise that is true 100% of the time. It really depends on the context around the code as well as how the compiler decides to optimize that particular case. There is no ambiguity to the semantics of this code though, it should do what it says.

If it's three separate triggers:
Code
global marine_count[3];

bring(Player1, AtMost, x, TerranMarine, LocationA) => {
   spawn(TerranMarine, Player1, marine_count[Player1], LocationA);
}

bring(Player2, AtMost, y, TerranMarine, LocationA) => {
   spawn(TerranMarine, Player2, marine_count[Player2], LocationA);
}

bring(Player2, AtMost, z, TerranMarine, LocationA) => {
   spawn(TerranMarine, Player2, marine_count[Player3], LocationA);
}


If the bring() quantity is equal for all three players there is a shorthand way to do the above:
Code
global marine_count[3];

for <PlayerId> in (Player1, Player2, Player3) => {
   bring(PlayerId, AtMost, 10, TerranMarine, LocationA) => {
       spawn(TerranMarine, PlayerId, marine_count[PlayerId], LocationA);
   }
}


Quote from NudeRaider
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.

I am well aware of the actual implementation (i.e. how the triggers are actually processed by the game) and LangUMS takes advantage of this a lot. When I talk about triggers being a parallel construction I'm talking in the abstract sense, not literally how the game code does it.

Quote
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.

Sorry if it seems like I'm ignoring any questions. I do try to answer everything, but some responses require more thought than others so my responses are somewhat out of order.

Post has been edited 4 time(s), last time on May 6 2017, 11:58 am by nlight.



None.

May 6 2017, 4:09 pm NudeRaider Post #44

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
I am well aware of the actual implementation (i.e. how the triggers are actually processed by the game) and LangUMS takes advantage of this a lot. When I talk about triggers being a parallel construction I'm talking in the abstract sense, not literally how the game code does it.
*sigh* I am done. I really don't know anymore if you are trolling me, are just dumb, live in a fantasy world, have trouble communicating facts, or come from the multiverse.

Triggers never run in parallel. Stop insisting they would "in a sense". And thanks for wasting my time.




May 6 2017, 5:58 pm Wormer Post #45



I'm starting to understand.

Code
global marine_count[3];

bring(Player1, AtMost, x, TerranMarine, LocationA),
bring(Player2, AtMost, y, TerranMarine, LocationA),
bring(Player3, AtMost, z, TerranMarine, LocationA) => {
   spawn(TerranMarine, Player1, marine_count[Player1], LocationA);
   spawn(TerranMarine, Player2, marine_count[Player2], LocationA);
   spawn(TerranMarine, Player3, marine_count[Player3], LocationA);
}

If for example the code above emitted one trigger for the computer player 8, then what's written below will generate additional triggers for players 1 and 2.

Code
global marine_count[3];

bring(Player1, AtMost, x, TerranMarine, LocationA),
bring(Player2, AtMost, y, TerranMarine, LocationA),
bring(Player3, AtMost, z, TerranMarine, LocationA) => {
   spawn(TerranMarine, Player1, marine_count[Player1], LocationA);
   spawn(TerranMarine, Player2, marine_count[Player2], LocationA);
   spawn(TerranMarine, Player3, marine_count[Player3], LocationA);
   print("Text for player 1", Player1);
   print("Text for player 2", Player2);
}


Only one of those 3 triggers will actually own the specified condition. The rest triggers will rely on a switch set by the first trigger that is going to run. The switch is cleared in the epilogue of the player 8 triggers.

EDIT:
Quote from nlight
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.
LangUMS reminded me of Verilog - a language of specifying the behavior of electronic circuits which are concurrent in nature. There is a notion of blocking and nonblocking assignment in Verilog which you can borrow when something should depend or not from the execution order. In fact Verilog has similar constructs to describe something that should happen after several preconditions are met. I believe you can have inspiration from the language.

EDIT2:
More ideas for you.
Quote
The player selected with --triggers-owner (player 1 by default) must always be in the game (preferably a CPU player). The triggers owner leaving the game leads to undefined behavior
There is a trick that allows to vest a human player with a function to execute such triggers that have to be executed only once. When player leaves, the next player takes his role. Have a look at the trigger:
Code
Trigger("Force 1"){
Conditions:
Deaths("Force 1", "Danimoth (Arbiter)", Exactly, 0);

Actions:
Set Deaths("Current Player", "Danimoth (Arbiter)", Set To, 1);
// Preserve trigger isn't needed.
}

Every trigger that has to be executed like for a CPU have to be 1) owned by the whole Force 1, 2) put below the specified trigger, and 3) must have a precondition Deaths("Current Player", "Danimoth (Arbiter)", At Least, 1).

Post has been edited 6 time(s), last time on May 6 2017, 6:24 pm by Wormer.



Some.

May 6 2017, 6:38 pm nlight Post #46



Quote from Wormer
If for example the code above emitted one trigger for the computer player 8, then what's written below will generate additional triggers for players 1 and 2. Only one of those 3 triggers will actually own the specified condition. The rest triggers will rely on a switch set by the first trigger that is going to run. The switch is cleared in the epilogue of the player 8 triggers.

Yeah. There will be 1 trigger emitted for the conditions which sets a switch and the rest will be sequenced using deaths()/ set_deaths() chains. The print() calls specifically will always be emitted for the player to whom they're printing because there is no other option.

Quote
There is a trick that allows to vest a human player with a function to execute such triggers that have to be executed only once. When player leaves, the next player takes his role.

This is a cool trick and though I currently haven't found a use for "one off" triggers in the compiler it may come in handy later. Thanks.



None.

Dec 8 2018, 4:29 pm sethmachine Post #47



This is quite amazing, and I am very grateful you spent the time to create this abstracted language to replace using the vanilla Triggers.

I would certainly try using this tool.

I have some questions:

(1a) Are there syntax highlighting plugins available? E.g. if you had one for JetBrains PyCharm that would be fantastic!

(1) Can you provide an example of organized project? E.g. would a developer just have a folder with different src files plus the .scx file, and then decide their order (rather than one big src file)?

(2) Can we define locations' dimensions/will they be created automatically if I reference a new location e.g. "Location64"? The way some of the my triggers work, the initial coordinates of the location don't matter, just their width/height. Even Warcraft 3 has this feature (called RegionCreate, which takes 4 values, x, y, width, and height).

(3) What implementation of hyper triggers are being used (reference or show the Triggers output)? There's a recent post with a hyper triggers version that repeatedly sets a DC to 0 and 1 in a single trigger and seems to be the general preferred version.

(4) Can you provide an example of a Death Counter timer loop, e.g.

[code]
DC = startValue;
while DC > value:
DC -= 1;

if DC == value:
callback();
DC = startValue;
[code/]

(5) Finally, what would be really cool is if you remade a popular map using your LangUMS, and showed either (1) how much time it took, (2) how more efficient the map was, (3) how easier it was to update the map, etc.




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.
[04:47 pm]
Dem0n -- then again w/e
[04:46 pm]
Dem0n -- It's hardly even a SEN server honestly. Just mostly the same 10 people saying dumb shit LMAO
[04:46 pm]
Dem0n -- NudeRaider
NudeRaider shouted: Voyager7456 there should probably be a place more obvious that gives the link to the discord server. I'd say we're past trial stage by now.
no tbh. Lots of dumb people that shouldn't be on it.
[04:45 pm]
Suicidal Insanity -- Naw, somebody just redefined what one standard moose is
[04:39 pm]
Dem0n -- Our Moosey's all grown up C|:'^ )
[04:36 pm]
Dem0n -- O__________________________________________________________O
[04:17 pm]
jjf28 -- moose is no longer a mini O.O
[10:41 am]
NudeRaider -- NudeRaider
NudeRaider shouted: Voyager7456 there should probably be a place more obvious that gives the link to the discord server. I'd say we're past trial stage by now.
In the menu. Probably an item under Site, or preferably next to Wiki
[10:40 am]
NudeRaider -- Voyager7456
Voyager7456 shouted: You download Discord and join the SEN server :P
there should probably be a place more obvious that gives the link to the discord server. I'd say we're past trial stage by now.
[08:53 pm]
O)FaRTy1billion[MM] -- I'm pretty sure you can use the web one on phone too
Please log in to shout.


Members Online: UEDCommander, Roy, Excalibur, 6claudiae232wh7