It may not have been clear that I was laying out multiple options:
1. Run your logic once every frame. You can do this by calling the function you already have from StartFrame.
2. Create an invisible entity to manage the spawning logic. You would create the entity in the worldspawn function. After creating it you would set nextthink and think. The function you already wrote would be modified to become a think function, which means at the end it needs self.nextthink = time + 0.1;
3. You place an entity in the level which has "classname" "chaos_monsters" then you split your current function into two parts, one is the spawn function and one is the think function -- this isn't really an option because you want it to work on existing levels. I mentioned it earlier just to explain how some function are automatically called based on the names of map entities. This case doesn't apply to you.
How would I call the function using think if the function declaration is after the world spawn function. Would the function need to be declared before the world spawn function?
Say for progs.src
The order I currently have is like this
chaos.qc <- contains my function for handling spawns. I set it at the bottom of progs.src so I can reference monster/ai functions.
Is there a different way to do this so I can access the functions that are defined later in the program?
By the way thank you for taking so much time helping me!
That's called "forward declaration" and you can do it by naming the function in an earlier file, or in a place earlier in the same file, than where you use it.
For example you could declare the function with this one line, in world.qc before the worldspawn function:
This allows you to call it in worldspawn even though the full definition of the function happens in a later file.
Thank A Ton My Dude
This is exactly what I needed and couldn’t figure out. Forward declaration is exactly the piece I was missing and needed haha. When I get home I’ll type it up and I’m pretty sure it will work. Thanks a ton mate.
Every Thing Works
So everything works as intended now, except for one issue. Some of the spawn points on all the maps are to close to walls or ceilings and the monsters get stuck. They still shoot and try to walk but can't. How can I move them into a valid space using the info_player_deathmatch as the origin?
That Is Why Droptofloor() Is Your Friend
Look into original id1 code and see what droptofloor() does when monsters or items are set. Pay attention to dprint messages.
Now use it in your new code to remove the entity if it fails.
Ok, so I got two things I'm trying to sort out with particles in quakec.
First one is to create a particle explosion effect. What I'm using now is just the in-built explosion effect...
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY);
WriteByte (MSG_BROADCAST, TE_EXPLOSION);
WriteCoord (MSG_BROADCAST, self.origin_x);
WriteCoord (MSG_BROADCAST, self.origin_y);
WriteCoord (MSG_BROADCAST, self.origin_z);
// these both crash the game session
// WriteByte (MSG_BROADCAST, 176); // quake's palette has no cyans!
// WriteByte (MSG_BROADCAST, 8); // palette color range
... which comes with two problems. One, it plays the standard explosion sound. Not a huge deal, I can get around that. Two, I can't change the color of the particles. If I try the game soft-crashes with a 'bad server message' error.
So ideally I'd like to create my own replacement. Unless there's another canned effect I can use that's a bit more flexible. I want this to be compatible with all kinds of different source ports btw.
And here's the second thing:
I need a uniform distribution of particles inside a spherical radius. I've got no idea how to go about this though. Is this doable with quakec? I mean, the Quake 2 Weapons mod has an effect like this for the BFG projectile so it has to be, right?
I thought I could use a for-loop and particle() to spawn particles at random within a limited radius but so far I haven't had much luck. Any ideas? Any open-source examples out there doing something similar?
EF_BRIGHFIELD Is The Ticket..
Nevermind figured it out. It's all good
Is there a good set of tutorials for beginners looking to dabble in QuakeC in 2021? 10-15 years ago I followed a few of the tutorials on inside3d with some success, but they're largely copy&paste guides and they seem to focus mostly on changing existing game assets instead of adding new stuff. They're also quite reliant on outdated compilers and source codes.
You Might Look
I copied all related stuff from Inside3D there as my experiences from the Quake lab, the first published examples from Id.
Thanks Madfox I'll Have A Look
My anxious consideration's of the BillBoardService, when the internet was still a garden of unlimited treasures.
What could cause a func_train entity to disappear? I have a case with my custom progs.dat and a custom level (the last of Gotshun's "Lost Levels" for SoA) where a silver key is supposed to be transported through a door into a cage at the start of the map. However, in QSS the train on which the key is supposed to be transported is gone, allowing you to grab the key directly.
Without my custom progs.dat (using the one embedded into SoA's pak0.pak), it works. However, Mark V runs the map just fine WITH my code, it's just QSS that doesn't like it.
Which source code files could be responsible? My first suspect would be plats.qc, but the only thing I did there was to make platform movement smoother (10 fps -> 100 fps), and reverting those changes didn't fix it.
I Was Wondering What This Code Is Doing
Is this a new feature, a fix or what?
In triggers.qc (from SoA):
void() hurt_touch =
self.solid = SOLID_NOT;
T_Damage (other, self, self, self.dmg);
self.think = hurt_on;
self.nextthink = time + 1;
// NEW CODE START
if (self.cnt > 0)
self.cnt = self.cnt - 1;
if (self.cnt == 0)
self.touch = SUB_Null;
self.nextthink = time + 0.1;
self.think = SUB_Remove;
// NEW CODE END
void() trigger_hurt =
self.touch = hurt_touch;
self.dmg = 5;
// NEW CODE START
if (self.cnt == 0)
self.cnt = -1;
// NEW CODE END
looks like they added a property which will remove the trigger after it was used a certain number of times. If the mapper added "cnt" "5" it would delete itself after 5 uses.
Since unspecified properties default to "0", they convert 0 to -1 in the spawn function.
Guess that would make it rather useless in ID1 maps, for example. At first I thought it could be something like Maddes' URQP code fix for multiple clients getting hurt at once and only the first client receiving damage, but that would have to look differently code-wise.
I am comparing Maddes' URQP code with Preach's cleaned-up QuakeC 1.06 source and see a difference in ai.qc, in function FindTarget().
It starts as follows in URQP:
float() FindTarget =
if (sight_entity_time >= time - 0.1 && !(self.spawnflags & 3) )
client = sight_entity;
if (client.enemy == self.enemy)
return FALSE; // This is what I wonder about
In Preach's version, it's return TRUE. Which one is correct? According to the file comments, this is supposed to return TRUE if an enemy has been sighted. (Also: What would happen if it's wrong?)
And Another Thing
Any way to access cvars which are not saved to config, e.g. r_slimealpha in QSS? Stuff like cvar("r_slimealpha") wouldn't work, apparently.
Any reason why (am using darkplaces if that is relevant) sounds are sometimes mismatched? Picking up a health pack may make a megahealth sound, ogres may play a death sound in place of their pain sound...not good.
More info: It doesn't happen all the time, and the mod I am modding features a lot of new sounds. Typically it seems the mismatched sound is taken from the same folder (e.g health pack plays megahealth sound), but very rarely it seems completely random.
In the past, people have had this issue because there is something inconsistent about the order of precaches in their code. But, I think that would only show up as a problem when loading a savegame or playing a demo.
Darkplaces might(?) have a feature that auto-caches when you try to play a sound that was not precached. If that's true, perhaps this creates the inconsistent order (becuase it could depend on player actions.)
So, make sure you are precaching all sounds you use in worldspawn or one of the other spawn functions, and, make sure nothing in the spawn logic can randomize the order of the precaches.
Thank you very much for your help.
What about multiple instances of the same sound getting pre-cached?
Also please would you be able to explain why the bug only happens when loading a save game?
My experience with playing DarkPlaces is that it is a mod that is heavily transformed into its own behaviour. So although it uses the original ID1 code as source most related calls go to the DarkPlaces subdirectory, which has its own progs.dat.
So for searching your saved games and related errors with sound you have to search in the DarkPlaces directory.
I know this is not a solution for your problem, but I think you need to search for it there. And yes, DP has a rather kinky code structure.