• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 01:30
CEST 07:30
KST 14:30
  • 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
[ASL21] Ro24 Preview Pt2: News Flash10[ASL21] Ro24 Preview Pt1: New Chaos0Team Liquid Map Contest #22 - Presented by Monster Energy18ByuL: The Forgotten Master of ZvT30Behind the Blue - Team Liquid History Book20
Community News
Weekly Cups (May 30-Apr 5): herO, Clem, SHIN win0[BSL22] RO32 Group Stage1Weekly Cups (March 23-29): herO takes triple6Aligulac acquired by REPLAYMAN.com/Stego Research8Weekly Cups (March 16-22): herO doubles, Cure surprises3
StarCraft 2
General
Weekly Cups (May 30-Apr 5): herO, Clem, SHIN win Rongyi Cup S3 - Preview & Info Team Liquid Map Contest #22 - Presented by Monster Energy Blizzard Classic Cup @ BlizzCon 2026 - $100k prize pool What mix of new & old maps do you want in the next ladder pool? (SC2)
Tourneys
RSL Season 4 announced for March-April Sparkling Tuna Cup - Weekly Open Tournament StarCraft Evolution League (SC Evo Biweekly) WardiTV Mondays World University TeamLeague (500$+) | Signups Open
Strategy
Custom Maps
[M] (2) Frigid Storage Publishing has been re-enabled! [Feb 24th 2026]
External Content
The PondCast: SC2 News & Results Mutation # 520 Moving Fees Mutation # 519 Inner Power Mutation # 518 Radiation Zone
Brood War
General
so ive been playing broodwar for a week straight. ASL21 General Discussion [BSL22] RO32 Group Stage Gypsy to Korea Pros React To: JaeDong vs Queen
Tourneys
[ASL21] Ro24 Group F Escore Tournament StarCraft Season 2 [Megathread] Daily Proleagues [ASL21] Ro24 Group E
Strategy
What's the deal with APM & what's its true value Fighting Spirit mining rates Simple Questions, Simple Answers
Other Games
General Games
Stormgate/Frost Giant Megathread Starcraft Tabletop Miniature Game Nintendo Switch Thread General RTS Discussion Thread Darkest Dungeon
Dota 2
The Story of Wings Gaming Official 'what is Dota anymore' discussion
League of Legends
G2 just beat GenG in First stand
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Deck construction bug Heroes of StarCraft mini-set
TL Mafia
Mafia Game Mode Feedback/Ideas TL Mafia Community Thread Five o'clock TL Mafia
Community
General
US Politics Mega-thread The Chess Thread Russo-Ukrainian War Thread NASA and the Private Sector Things Aren’t Peaceful in Palestine
Fan Clubs
The IdrA Fan Club
Media & Entertainment
[Manga] One Piece [Req][Books] Good Fantasy/SciFi books Movie Discussion!
Sports
2024 - 2026 Football Thread Formula 1 Discussion Cricket [SPORT] Tokyo Olympics 2021 Thread General nutrition recommendations
World Cup 2022
Tech Support
[G] How to Block Livestream Ads
TL Community
The Automated Ban List
Blogs
Broowar part 2
qwaykee
China Uses Video Games to Sh…
TrAiDoS
Funny Nicknames
LUCKY_NOOB
Iranian anarchists: organize…
XenOsky
FS++
Kraekkling
ASL S21 English Commentary…
namkraft
Electronics
mantequilla
Customize Sidebar...

Website Feedback

Closed Threads



Active: 13502 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
CranKy Ducklings
00:00
TLMC #22: Map Judging #1
Liquipedia
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
Nina 139
ROOTCatZ 94
StarCraft: Brood War
Sea 5794
GuemChi 4714
Leta 569
Tasteless 215
Snow 166
sSak 45
soO 28
ajuk12(nOOB) 22
Sacsri 11
Noble 11
[ Show more ]
Icarus 8
League of Legends
JimRising 707
Counter-Strike
Coldzera 1579
Stewie2K1264
m0e_tv442
Super Smash Bros
C9.Mang0338
Mew2King83
Other Games
summit1g10494
NeuroSwarm89
RuFF_SC225
Organizations
Other Games
gamesdonequick1082
BasetradeTV224
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 13 non-featured ]
StarCraft 2
• AfreecaTV YouTube
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
• Migwel
• sooper7s
StarCraft: Brood War
• BSLYoutube
• STPLYoutube
• ZZZeroYoutube
League of Legends
• Lourlo1186
• Rush1085
• Stunt596
Upcoming Events
Sparkling Tuna Cup
4h 31m
PiGosaur Cup
18h 31m
Replay Cast
1d 3h
Kung Fu Cup
1d 6h
Replay Cast
1d 18h
The PondCast
2 days
CranKy Ducklings
2 days
WardiTV Team League
3 days
Replay Cast
3 days
CranKy Ducklings
4 days
[ Show More ]
WardiTV Team League
4 days
uThermal 2v2 Circuit
4 days
BSL
4 days
Sparkling Tuna Cup
5 days
WardiTV Team League
5 days
BSL
5 days
Replay Cast
5 days
Replay Cast
6 days
Wardi Open
6 days
Liquipedia Results

Completed

CSL Elite League 2026
RSL Revival: Season 4
NationLESS Cup

Ongoing

BSL Season 22
ASL Season 21
CSL 2026 SPRING (S20)
StarCraft2 Community Team League 2026 Spring
Nations Cup 2026
PGL Bucharest 2026
Stake Ranked Episode 1
BLAST Open Spring 2026
ESL Pro League S23 Finals
ESL Pro League S23 Stage 1&2
PGL Cluj-Napoca 2026
IEM Kraków 2026
BLAST Bounty Winter 2026

Upcoming

Escore Tournament S2: W2
IPSL Spring 2026
Escore Tournament S2: W3
Acropolis #4
BSL 22 Non-Korean Championship
CSLAN 4
Kung Fu Cup 2026 Grand Finals
HSC XXIX
uThermal 2v2 2026 Main Event
uThermal 2v2 Last Chance Qualifiers 2026
RSL Revival: Season 5
IEM Cologne Major 2026
Stake Ranked Episode 2
CS Asia Championships 2026
Asian Champions League 2026
IEM Atlanta 2026
PGL Astana 2026
BLAST Rivals Spring 2026
CCT Season 3 Global Finals
IEM Rio 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.