
Need help scripting something involving tagged items
Moderator: GZDoom Developers
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Need help scripting something involving tagged items
So basically I'm making a map where youre in a room full of a singular item and I wanna make it so that when all of that item is consumed, the map exits. I'm a little experienced with ACS, but don't really know how to do something as advanced as that. Any help would be greatly appreciated! 

Re: Need help scripting something involving tagged items
Something like this?
Pick up all the health bottles and the map will end.Code: Select all
#include "zcommon.acs"
script 1 OPEN
{
//count the health bottles with tag 201
//and only do stuff when they are all gone
while (thingcount (0, 201))
{
delay (8);
}
//Make a noise
Ambientsound ("misc/chat", 127);
//Display a message
SetHUDSize (640, 480, 0);
hudmessage (s:"You caught them all!";
HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GOLD, 320.4, 340.0, 3.0);
//Wait so that the player can read the message
delay(35*3);
//End the level
Exit_Normal (0);
}
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
Yes, that's exactly what I'm looking for! Thank you!
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
So I have a bit of an issue. There's so many tagged entities in that level to the point where the game just crashes. Any fix for that?
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
[imgur]https://imgur.com/a/beer-land-dSJqP9a[/imgur] This is what the map looks like, just giving an example
Re: Need help scripting something involving tagged items
That does look like a lot of items right enough.JtoTheB wrote: ↑Sat Aug 09, 2025 10:52 am [imgur]https://imgur.com/a/beer-land-dSJqP9a[/imgur] This is what the map looks like, just giving an example
GZDoom should certainly be able to handle it that many items in the map (not saying that it won't lose frame rate, but it should load).
I've never tagged that many items, so that might indeed be the issue, or it could lie elsewhere. It's hard to tell from the information provided.
Do you get any error message or crash report?
Can you run the map without the items being tagged (or just a smaller number of them being tagged)?
If you can, upload your mod somewhere for people to download and take a look, you'll be more likely to get a solution if people can actually test the mod and replicate the problem.
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
Alright, I'll try that. Also responding to one of your questions, no I have not gotten any crash reports or messages. I shouldn't have really said crash, because by that I meant the game stops responding.
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
Turns out it was indeed the tagged entities, but i've also found that if you just wait for a good while the map will load.
Re: Need help scripting something involving tagged items
Was it the fact that they were tagged, or the fact that there were so many of them (i.e. is it still slow to load when they are not tagged)?
If it's just because you have so many actors, there isn't much that can be done if you need that many. Perhaps dividing them up into separate rooms (so that they aren't all being drawn on screen at the same time), and perhaps even counting the different room contents with different scripts that are only triggered when you enter those rooms. However, that does sound like it's not what you want to do.
Another option could be to set up a variable that has the same value as the number of beer bottles. Then give each beer bottle the special of ACS_ExecuteAlways. All the script that the beer bottle run would do would be decrease the variable by 1 every time it is run. Then, instead of doing a beer bottle count, you can have a script waiting for the variable to reach 0 and do stuff then.
As a matter of interest, how many beer bottles are in the map?
If it's the fact that they are tagged, and you are using my script as I provided it, you *might* get better performance by doing the count less often.
You see where I have "delay(8);" I *think* that means the count restarts every 8 tics. It's certainly an 8 tic delay, and I think that means the count is re-tried every 8 tics, but I'm not 100% sure on that.
Anyway, 1 second is 35 tics, so you might not need to do the count that often (i.e. slightly over 4 times per second). So, if you increase the 8 to something that you feel is still acceptable, it might help. Or it might not. I'm just guessing really.
If it's just because you have so many actors, there isn't much that can be done if you need that many. Perhaps dividing them up into separate rooms (so that they aren't all being drawn on screen at the same time), and perhaps even counting the different room contents with different scripts that are only triggered when you enter those rooms. However, that does sound like it's not what you want to do.
Another option could be to set up a variable that has the same value as the number of beer bottles. Then give each beer bottle the special of ACS_ExecuteAlways. All the script that the beer bottle run would do would be decrease the variable by 1 every time it is run. Then, instead of doing a beer bottle count, you can have a script waiting for the variable to reach 0 and do stuff then.
As a matter of interest, how many beer bottles are in the map?
If it's the fact that they are tagged, and you are using my script as I provided it, you *might* get better performance by doing the count less often.
You see where I have "delay(8);" I *think* that means the count restarts every 8 tics. It's certainly an 8 tic delay, and I think that means the count is re-tried every 8 tics, but I'm not 100% sure on that.
Anyway, 1 second is 35 tics, so you might not need to do the count that often (i.e. slightly over 4 times per second). So, if you increase the 8 to something that you feel is still acceptable, it might help. Or it might not. I'm just guessing really.
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
In terms of how many beer bottles, I believe there's 8658. And turns out I may've made a typo with the delay, and I accidentally made it 3 tics so no wonder it was freezing so often.
- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
And I know it's not the fact that there's so many because before I did any of the scripting it ran perfectly fine. Rewriting the delay check to 30 seconds in tics (1050) didn't help much either. I'll try the variable option.
Re: Need help scripting something involving tagged items
Here's an example of the variable option if you need it.
Note, there is no need for the bottles to have tags at all in this version. It's all done using the variable.

Code: Select all
#include "zcommon.acs"
//set this value to however many beer bottles there are
int BeerBottles = 64;
script 1 OPEN
{
//Keep a track of the BeerBottles variable and don't do anything until it reaches 0
while (BeerBottles>0)
{
delay (8);
}
//Make a noise
Ambientsound ("misc/chat", 127);
//Display a message
SetHUDSize (640, 480, 0);
hudmessage (s:"You caught them all!";
HUDMSG_PLAIN|HUDMSG_LOG, 1, CR_GOLD, 320.4, 340.0, 3.0);
//Wait so that the player can read the message
delay(35*3);
//End the level
Exit_Normal (0);
}
//This script is run by each beer bottle when it is picked up
script 2 (void)
{
//this decreases the BeerBottle variable by 1
BeerBottles--;
}
That's a lot of beer.

- JtoTheB
- Posts: 32
- Joined: Sat Aug 09, 2025 9:46 am
- Operating System Version (Optional): Windows 11
- Location: New Jersey
Re: Need help scripting something involving tagged items
Variables for the win! The map runs flawlessly now, AND the script works!
Re: Need help scripting something involving tagged items
Cool. I'm glad it works.
Just remember to update the variable value in your script if you change the number of bottles in the map, and also remember to give any new bottles the special to run the script.
Just for info, the reason I specified ACS_ExecuteAlways, rather than just ACS_Execute, is because the former can run multiple copies of the same script whereas the latter will only run one copy at a time. So, if you use ACS_Execute, it leaves the possibility that two items would get picked up at the same time (i.e. in the same tic) and therefore the script would only be run once for the two pickups, and the variable would never reach 0. With ACS_ExecuteAlways, that shouldn't be a problem.
It's also good to know for future reference how expensive ThingCount is when a LOT of things are being counted. Normally people are counting far fewer than 8000+ things.
Oh, also worth mentioning: I set the counting script to be an OPEN one. That means it starts running as soon as the map starts. If you don't want that, set it to be a (void) script and have the player trigger it (by crossing a line or whatever) whenever it is appropriate to do so.
It's also worth pointing out the an OPEN script is run "by the world", whereas a void, triggered in the way I described, or an enter script is run by the player. This might be important if you want certain things to happen. For example, with the script I posted, I used AmbientSound to make the noise. If I had used LocalAmbientSound, that only gets played to the entity that ran the script - which wasn't the player, so it would be silent from their perspective.
Just remember to update the variable value in your script if you change the number of bottles in the map, and also remember to give any new bottles the special to run the script.

Just for info, the reason I specified ACS_ExecuteAlways, rather than just ACS_Execute, is because the former can run multiple copies of the same script whereas the latter will only run one copy at a time. So, if you use ACS_Execute, it leaves the possibility that two items would get picked up at the same time (i.e. in the same tic) and therefore the script would only be run once for the two pickups, and the variable would never reach 0. With ACS_ExecuteAlways, that shouldn't be a problem.
It's also good to know for future reference how expensive ThingCount is when a LOT of things are being counted. Normally people are counting far fewer than 8000+ things.

Oh, also worth mentioning: I set the counting script to be an OPEN one. That means it starts running as soon as the map starts. If you don't want that, set it to be a (void) script and have the player trigger it (by crossing a line or whatever) whenever it is appropriate to do so.
It's also worth pointing out the an OPEN script is run "by the world", whereas a void, triggered in the way I described, or an enter script is run by the player. This might be important if you want certain things to happen. For example, with the script I posted, I used AmbientSound to make the noise. If I had used LocalAmbientSound, that only gets played to the entity that ran the script - which wasn't the player, so it would be silent from their perspective.