• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 20:02
CET 01:02
KST 09:02
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
[ASL22] Finals Preview: Sweet Victory!11[ASL22] Ro4 Preview: Mirror Mirror6[ASL22] Ro8 Preview: Within Reach5[ASL22] Ro8 Preview: In A Tizzy11[ASL22] Ro16 Preview: Holy Diver5
Community News
Evil Geniuses - shutting down16ISSL (IntoTheTV x SOOP SC2 League): Premier5Weekly Cups (October 12-18): 5.0.17 era begins1[$1250] International ShieldBattery League80Weekly Cups (October 5-11): Farewell to 5.0.167
StarCraft 2
General
REPORT: StarCraft 2: Remastered In Development Evil Geniuses - shutting down How do you feel about the mass reverts in the 5.0.17 PTR? Team Liquid Map Contest #22: Results and Winners No more SC2 streamers on team liquid?
Tourneys
RSL goes to London! 2026 Offline Finals Nov 21-22 ScienceCraft (October 24-25) - Live Event Sparkling Tuna Cup - Weekly Open Tournament ISSL (IntoTheTV x SOOP SC2 League): Premier WORTEX Challenger Series — Open SC2 LAN in Budapes
Strategy
[H] ZvP Mid-Late Game: Stalkers Collossi HT
Custom Maps
[G] How to playtest arcade maps [A] Nemrods 1/4 players [M] (2) Sweltering Sands
External Content
Mutation # 549 Endless Sparkles The PondCast: SC2 News & Results Mutation # 548 Shining Bright Mutation # 547 Temple Of Terror
Brood War
General
[ASL22] Finals Preview: Sweet Victory! Recent recommended BW games [Megathread] Daily Funny Videos Hands of Pluto Oceanic Brood War - Join and chat!
Tourneys
[$1250] International ShieldBattery League [Megathread] Daily Proleagues [ASL22] Grand Finals [BSL23] RO24 Group C
Strategy
50,000-Word Terran Builds Memo 2026-10-22 Cliff Jump Revisited (1 in a 1000 strategy) Simple Questions, Simple Answers
Other Games
General Games
Stormgate/Frost Giant Megathread Nintendo Switch Thread Mobile Legends: Bang Bang Armies of Exigo - YesYes? General RTS Discussion Thread
Dota 2
Dota 2 Champions League Season 3 Begins April 25!
League of Legends
[TL LoL EUW IHs] Teemo shall perish
Heroes of the Storm
Heroes of the Storm 2.0
Hearthstone
Deck construction bug
TL Mafia
TL Mafia Community Thread
Community
General
Things Aren’t Peaceful in Palestine Canadian Politics Mega-thread European Politico-economics QA Mega-thread US Politics Mega-thread Russo-Ukrainian War Thread
Fan Clubs
Reynor Fan Club The Flash Fan Club Serral Fan Club
Media & Entertainment
Anime Discussion Thread Movie Discussion! [Manga] One Piece
Sports
Football (Soccer) Thread TeamLiquid Health and Fitness Initiative For 2023 MLB/Baseball 2023
World Cup 2022
Tech Support
Computer Build, Upgrade & Buying Resource Thread
TL Community
Recent Gifted Posts
Blogs
Innovate or Game Over?
TrAiDoS
ShieldBattery on Mac
Kraekkling
[ASL22] Ro4 Day1 Ticket Giv…
bITt.mAN
Can Bots Beat Pros?? Starcr…
namkraft
Customize Sidebar...

Website Feedback

Closed Threads



Active: 10207 users

Custom map/ UMS creators wanted - Page 5

Forum Index > BW General
Post a Reply
Prev 1 2 3 4 5 All
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-05-01 18:32:01
May 01 2017 18:24 GMT
#81
On May 02 2017 02:59 Powder_Keg wrote:
Maybe it's just me, and maybe it's just that your language is meant to be understood differently from what people are used to, but here's what I had trouble understanding while reading through your code:


I think you have a misunderstanding of what the langums language is. It's an imperative language (meaning statements are executed sequentially, never out of order) not unlike C or JavaScript. It is not meant to be read like scmdraft trigger lists. Control starts at the top of the main() function and executes statements one by one. Typically you'll see something like


while(true) {
poll_events();
}


at the end of the main() function. This makes it so all event handlers get executed one after another indefinitely. Again, there is no out of order execution, everything is sequential and linearizable.

[*]What variables are deathcounters and what are just integers (similarly boolians and switches)


All variables are unsigned integers but the underlying storage is death counters. This is abstracted away from the user more or less.

[*]Which players own the triggers


You can set that with the --triggers-owner command-line argument.

[*]When triggers start and when they end


The emitted triggers are vastly different than the langums code and really hard to follow for a human in the same way machine code is hard to follow for a human. You don't really care about that when using this tool.
Powder_Keg
Profile Joined May 2017
8 Posts
Last Edited: 2017-05-01 18:32:05
May 01 2017 18:30 GMT
#82
I think you have a misunderstanding of what the langums language is. It's an imperative language (meaning statements are executed sequentially, never out of order) not unlike C or JavaScript. It is not meant to be read like scmdraft trigger lists.


Your code generates triggers which the map will run through sequentially, that I understand (or am I wrong here? I don't see how I could be.)

What I don't understand from your code is when it generates those triggers.
nlight
Profile Joined October 2011
Bulgaria58 Posts
May 01 2017 18:34 GMT
#83
What I don't understand from your code is when it generates those triggers.


You really shouldn't care about what actual triggers are emitted as long as you can observe the behavior described by the LangUMS code you've written. Well, unless you're working on the compiler itself.
Powder_Keg
Profile Joined May 2017
8 Posts
Last Edited: 2017-05-01 19:08:26
May 01 2017 18:38 GMT
#84
hmmm Can you run through the logic behind how your code decides what triggers to generate please? Without that I just won't understand what I'm doing.

I know how something like

if( conditions ){
deathcounter1 += deathcounter2;
}

would work using switches.

(e.g. the triggers outputted would have "Set Switch1" as an action, and then it would be 32 or so triggers to do a binary addition or w/e it's called adding deathcounter2 to deathcounter1 with each trigger having "Switch 1 is Set" as one of their condition)

Edit: Also, for example, if I just write

var integer = 5

does that take up a deathcounter slot?
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-05-01 19:39:15
May 01 2017 19:36 GMT
#85

if( conditions ){
deathcounter1 += deathcounter2;
}


The if condition is implemented using two triggers - one will have the false condition, the other the true condition. Depending on which one executes the "instruction counter" will be set to a different location effectively jumping to another point of execution. Basically every emitted trigger begins with a check if the current value of the instruction counter is equal to its address. This way we turn the inherently parallel triggers into a sequential machine. No switches are used for this. Switches are used as mutexes for some operations internally but they are not exposed to the user in any way I think.

Also, for example, if I just write

var integer = 5

does that take up a deathcounter slot?


Yes. Every variable takes up a death count slot and every array takes up as many slots as its size. Local variables exist only for the duration of their block (code surrounded by {}) and their storage gets reused.
Powder_Keg
Profile Joined May 2017
8 Posts
Last Edited: 2017-05-01 19:46:31
May 01 2017 19:41 GMT
#86
So each trigger outputted has a "Deathcounter == X" where X is the line of the code, basically?

Also, triggers are by default sequential - StarCraft runs through them from the top to the bottom, but you probably already knew that.

Edit: Would that sometimes cause some triggers to not be run until the next trigger cycle though? for example, lets say you are at line 500 and then now you want to next execute line 200 - to do that you have to wait until the next trigger cycle, which takes up like 1/11 of a second O_O
nlight
Profile Joined October 2011
Bulgaria58 Posts
May 01 2017 19:49 GMT
#87
On May 02 2017 04:41 Powder_Keg wrote:
So each trigger outputted has a "Deathcounter == X" where X is the line of the code, basically?


This is a relatively simplistic way to put it but yeah.

Also, triggers are by default sequential - StarCraft runs through them from the top to the bottom, but you probably already knew that.


They are executed in sequence by the game code by virtue of the game code being sequential but they are inherently a parallel machine. This "design" makes it easy to introduce race conditions (the bane of sane programming) in your logic. LangUMS actively prevents you from introducing race conditions unless you try really hard to twist it. That's the biggest gain from all this. In the end it's all just automation for something absolutely doable by hand but very tedious and error-prone.
Powder_Keg
Profile Joined May 2017
8 Posts
Last Edited: 2017-05-01 19:56:17
May 01 2017 19:51 GMT
#88
What is a race condition?

Edit: nvm, found it https://en.wikipedia.org/wiki/Race_condition

Thanks for answering all my questions btw, I appreciate it :D

What about this question:
Edit: Would that sometimes cause some triggers to not be run until the next trigger cycle though? for example, lets say you are at line 500 and then now you want to next execute line 200 - to do that you have to wait until the next trigger cycle, which takes up like 1/11 of a second O_O

nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-05-02 02:07:04
May 01 2017 20:42 GMT
#89
Would that sometimes cause some triggers to not be run until the next trigger cycle though? for example, lets say you are at line 500 and then now you want to next execute line 200 - to do that you have to wait until the next trigger cycle, which takes up like 1/11 of a second O_O


Yeah, jumps take one full cycle to execute in the worst case, though that is amortized by some compiler optimizations and it will only get better at it. This isn't any better if you sequence the triggers by hand.

EDIT: On second thought, maybe you're asking doesn't that mean you will miss in-game events if your code happens to be doing something else at that time. The answer is yes and no. All events are currently buffered but only once. Say you have a "bring marines to x" condition in your code. If the player brings the marines but 20 cycles pass between the calls to poll_events() it won't fire off the event 20 times but just 1. This can be an advantage or a drawback depending on where you're coming from. It's totally possible to buffer all 20 events and fire them off but I think it's more useful the other way around. I can turn this into an option eventually.
ZurgMaster
Profile Joined May 2017
Canada2 Posts
May 04 2017 17:06 GMT
#90
If you still need/want testers, I'm all for it. Just PM me.
"A life is like a garden. Perfect moments can be had, but not preserved, except in memory." – Leonard Nimoy, 2015
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-05-04 19:12:35
May 04 2017 18:44 GMT
#91
On May 05 2017 02:06 ZurgMaster wrote:
If you still need/want testers, I'm all for it. Just PM me.


Join the Discord @ https://discord.gg/TNehfve that's where we hang out.

Also new features in langums - repeat templates, so you don't have to repeat code for lists of things. Use like:


fn spawn_bonus_items() {
for <Loc> in (BonusLocation1, BonusLocation2, BonusLocation3) {
spawn(PowerupKhalisCrystal, Player8, 1, Loc);
}
}


The bigger news is that a live debugger with breakpoints and variable inspection for VS Code is almost ready and will be available to test soon.
Powder_Keg
Profile Joined May 2017
8 Posts
Last Edited: 2017-05-05 05:14:35
May 05 2017 04:54 GMT
#92
I am confused on why you say SC is inherently parallel.

SC runs triggers in the following way:

1. It first unpacks all triggers belonging to "Force 1," Force 2," etc., and changes them to belong to just the players in those forces - e.g. if Player 1 and Player 2 are in Force 1, then a trigger owned by Force 1 is the same thing as a trigger owned by Player 1 and Player 2. Similarly, a trigger owned by Current Player or All Players is the same thing as a trigger owned by Player 1, Player 2, etc. all the way to Player 8.

2. It then runs through all triggers owned by Player 1, from the top of the list to the bottom of the list. After this has finished it runs through all triggers owned Player 2, and then Player 3, etc. all the way to Player 8.

3. It then repeats this process.

^ How is that not sequential?

EDIT: On second thought, maybe you're asking doesn't that mean you will miss in-game events if your code happens to be doing something else at that time. The answer is yes and no. All events are currently buffered but only once. Say you have a "bring marines to x" condition in your code. If the player brings the marines but 20 cycles pass between the calls to poll_events() it won't fire off the event 20 times but just 1. This can be an advantage or a drawback depending on where you're coming from. It's totally possible to buffer all 20 events and fire them off but I think it's more useful the other way around. I can turn this into an option eventually.


I gotta be honest, I don't understand a lot of what you just said. What does it mean "All events are currently buffered but only once?" What does poll_events() do? If the player brings 20 marines to the location, and this poll_events() doesn't fire, and then the player removes 20 marines from the location, and then poll_events() does fire, will it not realize that in the meantime the player has brought 20 marines to the location?


Yeah, jumps take one full cycle to execute in the worst case, though that is amortized by some compiler optimizations and it will only get better at it. This isn't any better if you sequence the triggers by hand.


So does this mean that sometimes the triggers wont run immediately? e.g. if I have a "Player brings at least 1 Terran marine to location X" condition, and in game player brings a marine to location X, that there is a chance that the trigger still wont execute because there's some inner workings that have to be sorted out first? This sounds like something that could actually totally break a map, and is something that using normal triggers no one would ever have to worry about - i.e. it sounds like it would just be more difficult to make stuff using this than it is otherwise


nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-05-05 11:04:47
May 05 2017 10:59 GMT
#93
^ How is that not sequential?


Triggers may be executed sequentially in reality but they are inherently a parallel machine i.e. two unrelated statements in different parts of the program can, in effect, act at once and modify the same parts of memory. This is essentially parallelism and suffers from the drawbacks of any parallel machine (you need locking to avoid data races).

If the player brings 20 marines to the location, and this poll_events() doesn't fire, and then the player removes 20 marines from the location, and then poll_events() does fire, will it not realize that in the meantime the player has brought 20 marines to the location?


Yes it will that's the point of buffering the events so you don't lose any.

So does this mean that sometimes the triggers wont run immediately?


Nothing ever runs "immediately". Your CPU needs time to execute instructions after all.

To answer your question, if the main langums loop is busy with something else and you're not calling poll_events() quickly enough it may delay stuff (but not break it). This can be anywhere from one trigger cycle to many depending on what you're doing in the code.

if I have a "Player brings at least 1 Terran marine to location X" condition, and in game player brings a marine to location X, that there is a chance that the trigger still wont execute because there's some inner workings that have to be sorted out first?


I don't know where you got that from. LangUMS doesn't roll dice to figure out if your stuff will run properly or not. It has pretty well defined semantics and the code does what it says. The trigger will be executed for sure on the next poll_events() call.
Powder_Keg
Profile Joined May 2017
8 Posts
Last Edited: 2017-05-05 18:10:26
May 05 2017 18:02 GMT
#94
Triggers may be executed sequentially in reality but they are inherently a parallel machine i.e. two unrelated statements in different parts of the program can, in effect, act at once and modify the same parts of memory. This is essentially parallelism and suffers from the drawbacks of any parallel machine (you need locking to avoid data races).


. . . But two triggers are never run at the same time. They are always checked in the same cycle, and they can both run in the same cycle, but even then SC will just run the first one first in the cycle and the second one second in the cycle. I still don't understand why you say it is parallel. Can you give a concrete example of SC executing triggers in parallel please?

Yes it will that's the point of buffering the events so you don't lose any.


Then why not poll_events() every trigger cycle? I don't understand why this was introduced - what is it's purpose?


Nothing ever runs "immediately". Your CPU needs time to execute instructions after all.



I meant in the same trigger cycle that you meet those conditions. It sounds like with langUMS all the conditions of a trigger can be met for a trigger cycle or two and then become unmet and the triggers would never know.

I don't know where you got that from. LangUMS doesn't roll dice to figure out if your stuff will run properly or not. It has pretty well defined semantics and the code does what it says. The trigger will be executed for sure on the next poll_events() call.


I get that the code determines what happens, but I guess the problem here is I don't understand the code, and from what it sounds like the expected behavior is difficult to determine. I mean, a lot of trigger systems require things to be 'trigger-cycle' perfect (i.e. for triggers to execute as soon as the conditions are met), but with this it seems like sometimes this won't happen?
KhaosKreator
Profile Joined April 2009
Canada145 Posts
May 05 2017 18:57 GMT
#95
I'm going to try to get involved in this and make some test maps this weekend, I think.

I am still confused in the same way Powder Keg is confused though.
Kyrie, Ignis Divine, Eleison
nlight
Profile Joined October 2011
Bulgaria58 Posts
Last Edited: 2017-05-06 00:43:09
May 05 2017 22:44 GMT
#96
On May 06 2017 03:02 Powder_Keg wrote:
Triggers may be executed sequentially in reality but they are inherently a parallel machine i.e. two unrelated statements in different parts of the program can, in effect, act at once and modify the same parts of memory. This is essentially parallelism and suffers from the drawbacks of any parallel machine (you need locking to avoid data races).


That's what I mean by parallel. Two triggers can execute during the same cycle and without some form of locking if they access the same "memory" (death counts or whatever else) it creates a data race. This is an issue that experienced map makers are just used to dealing with but it's not simple and is prone to mistakes.

Then why not poll_events() every trigger cycle? I don't understand why this was introduced - what is it's purpose?


The purpose of poll_events() is to run the associated code for any event handlers whose conditions have been fulfilled since the last time poll_events() was called. This is necessary since LangUMS code is sequential and control can't just jump to random places whenever something in-game happens.

You can't poll_events() until the previous one has finished. So the minimum time between poll_events() is the time it takes to execute all your event handlers. This will never be zero unless you have zero event handlers in which case poll_events() emits no instructions.

I meant in the same trigger cycle that you meet those conditions. It sounds like with langUMS all the conditions of a trigger can be met for a trigger cycle or two and then become unmet and the triggers would never know.


The events are buffered so if the conditions are met the event handler will fire the next poll_events() cycle.

I get that the code determines what happens, but I guess the problem here is I don't understand the code, and from what it sounds like the expected behavior is difficult to determine.


The expected behavior is trivial to determine as the code is sequential. You have to read it like any other programming language, each statement follows the preceding one starting from the top of your main() function. Control never just jumps around the place for no reason.

On May 06 2017 03:57 KhaosKreator wrote:
I'm going to try to get involved in this and make some test maps this weekend, I think.


Come to the Discord - https://discord.gg/TNehfve so we can chat about it.
Prev 1 2 3 4 5 All
Please log in or register to reply.
Live Events Refresh
Next event in 28m
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
PiGStarcraft309
Nathanias 103
ViBE100
RuFF_SC2 96
Nina 92
CosmosSc2 39
StarCraft: Brood War
Britney 10398
Rain 1517
GuemChi 855
Artosis 609
ProTech182
White-Ra 116
910 35
Dota 2
syndereN516
febbydoto10
League of Legends
Doublelift4991
Counter-Strike
Fnx 1374
Heroes of the Storm
Trikslyr97
Other Games
summit1g11438
shahzam557
C9.Mang0223
ToD204
minikerr11
fpsfer 1
Organizations
Other Games
gamesdonequick1980
[ Show 14 non-featured ]
StarCraft 2
• Hupsaiya 89
• RyuSc2 29
• davetesta8
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• Migwel
StarCraft: Brood War
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
Dota 2
• masondota2598
League of Legends
• TFBlade323
Other Games
• Shiphtur832
Upcoming Events
PiGosaur Cup
28m
IntoTheTV X SOOP
1h 58m
The PondCast
9h 58m
Kung Fu Cup
10h 58m
IntoTheTV X SOOP
1d 10h
SHIN vs GuMiho
Clem vs Classic
OSC
1d 21h
WardiTV Invitational
2 days
GSL
2 days
Epic.LAN
2 days
Replay Cast
2 days
[ Show More ]
Sparkling Tuna Cup
3 days
Epic.LAN
3 days
Yamato Cup
4 days
Map Test Tournament
4 days
WardiTV Weekly
5 days
Replay Cast
5 days
Rogue vs Classic
Patches Events
6 days
Liquipedia Results

Completed

Acropolis #5 - GSC
Blizzard Classic Cup 2026
HCC Season 3

Ongoing

Acropolis #5
KCM Race Survival 2026 Season 4
International ShieldBattery League
BSL Season 23
PGL Masters Bucharest 2026
Stake Ranked Episode 5
1win Private Club #2
Thunderpick World Champ. '26
ESL Pro League Season 24
Stake Ranked Episode 4
1win Private Club #1
Logitech G Play Connect 2026
SL StarSeries Fall 2026
FISSURE Playground #3
BLAST Open Fall 2026
Esports World Cup 2026

Upcoming

IPSL Winter 2026-27
SC4ALL II: Brood War
BSL 23: Non-Korean Championship
HSC XXX
Stellar Fest 2: Lunar Cup
SC4ALL II: StarCraft II
Kung Fu Cup 2026 Grand Finals
RSL Offline Finals
eXTREMESLAND 2026
PGL Major Singapore 2026
Stake Ranked Episode 6
BLAST Rivals Fall 2026
IEM Beijing 2026
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2026 TLnet. All Rights Reserved.