Frogames RTS Building Pack : Particles problem
by Canon · in RTS Starter Kit · 01/28/2006 (5:46 am) · 9 replies
Hello everybody,
I'm working on a RTS Building Pack, and I need some help about particles in the RTS Starter Kit.

I will need to create an explosion when a building is destroyed, in order to create fumes around it when it falls.
But, i noticed that the crossbow explosion doesn't work in the RTS Starter Kit ... it can't find the particles datablock.
So, i want to know if it is a RTS Stater Kit bug, or if I need to create particles in a different way.
Sorry if my question is idiot, but I'm not a programmer.
Thank you very much!
Christophe
I'm working on a RTS Building Pack, and I need some help about particles in the RTS Starter Kit.

I will need to create an explosion when a building is destroyed, in order to create fumes around it when it falls.
But, i noticed that the crossbow explosion doesn't work in the RTS Starter Kit ... it can't find the particles datablock.
So, i want to know if it is a RTS Stater Kit bug, or if I need to create particles in a different way.
Sorry if my question is idiot, but I'm not a programmer.
Thank you very much!
Christophe
About the author
#2
Idiosyncracy of Torque, but explosions are not networked. Instead, what happens is that a projectile is networked, and when it collides with something on the server, it triggers an explosion on the server (for damage purposes), and then destroys the projectile. The destruction of the projectile is networked, and the client handles rendering the explosion based on the destruction of the projectile. Key thing to note here is that the projectile is networked, and is pretty much required for the explosion to occur.
The problem that comes into play with the RTS-SK is that in this code, projectiles are not networked (for network bandwidth optimization purposes). Instead, an AttackEvent is sent to all clients, and the clients are responsible for rendering any projectiles as "eye candy"--they do not in fact exist on the server at all. Obviously, this causes us a problem when we want explosions, because now there is no way to have the explosion actually occur, since the projectile itself never exists to be destroyed.
IMO the "best" (and unfortunately, the most difficult implementation wise) would be to implement a new NetEvent very similar to the RTSAttackEvent to network explosions. This idea has bounced around for a while at GG for core Torque, but was never really seen as a "must have" implementation for stock/core Torque since there is a workaround.
@Dave: If you are going to look into this, you may want to start with researching how the RTSAttackEvent is implemented, and see if it presents a good solution for explosions. If you have any specific questions, feel free to post!
01/31/2006 (10:42 am)
Quick info on one of the possible reasons why you may be having issues:Idiosyncracy of Torque, but explosions are not networked. Instead, what happens is that a projectile is networked, and when it collides with something on the server, it triggers an explosion on the server (for damage purposes), and then destroys the projectile. The destruction of the projectile is networked, and the client handles rendering the explosion based on the destruction of the projectile. Key thing to note here is that the projectile is networked, and is pretty much required for the explosion to occur.
The problem that comes into play with the RTS-SK is that in this code, projectiles are not networked (for network bandwidth optimization purposes). Instead, an AttackEvent is sent to all clients, and the clients are responsible for rendering any projectiles as "eye candy"--they do not in fact exist on the server at all. Obviously, this causes us a problem when we want explosions, because now there is no way to have the explosion actually occur, since the projectile itself never exists to be destroyed.
IMO the "best" (and unfortunately, the most difficult implementation wise) would be to implement a new NetEvent very similar to the RTSAttackEvent to network explosions. This idea has bounced around for a while at GG for core Torque, but was never really seen as a "must have" implementation for stock/core Torque since there is a workaround.
@Dave: If you are going to look into this, you may want to start with researching how the RTSAttackEvent is implemented, and see if it presents a good solution for explosions. If you have any specific questions, feel free to post!
#3
01/31/2006 (10:56 am)
Thank you Dave & Stephen!!
#4
Is that the only way an explosion can be created, at the collision end of a projectile? I was going to try to mount a particle emitter onto a node on a building, seemed like a straightforward thing because it's already working in the demo. I can see from the RTS Villager mod that the villagers (with no visible mounted weapons) will actually fire crossbow projectiles which explode wonderfully upon collision, though they do no damage. I am guessing that the fact that projectiles are not networked is why they can explode, but no onCollision actually happens.
Still, it seems like we should be able to mount a particle emitter to a building, it's only for eye candy.
01/31/2006 (11:37 am)
Stephen-Is that the only way an explosion can be created, at the collision end of a projectile? I was going to try to mount a particle emitter onto a node on a building, seemed like a straightforward thing because it's already working in the demo. I can see from the RTS Villager mod that the villagers (with no visible mounted weapons) will actually fire crossbow projectiles which explode wonderfully upon collision, though they do no damage. I am guessing that the fact that projectiles are not networked is why they can explode, but no onCollision actually happens.
Still, it seems like we should be able to mount a particle emitter to a building, it's only for eye candy.
#5
For this particular case there isn't much direct implementation needed (you could do it via commandToClient pretty much), but for the general case of networked explosions, you'd probably want to just go with your own EventType.
FYI, it's a terminology thing, but the "projectiles" you mention in the RTS-SK aren't net instantiated projectiles in the TGE vernacular...they are just graphics being played in response to an RTSAttackEvent with a range capable unit. Subtle difference, but important one.
01/31/2006 (11:57 am)
Yes, for the visual representation you can certainly mount the particle emitter to the shape, but the root question/challenge is how to let the clients know when to turn the particle emmitter on!For this particular case there isn't much direct implementation needed (you could do it via commandToClient pretty much), but for the general case of networked explosions, you'd probably want to just go with your own EventType.
FYI, it's a terminology thing, but the "projectiles" you mention in the RTS-SK aren't net instantiated projectiles in the TGE vernacular...they are just graphics being played in response to an RTSAttackEvent with a range capable unit. Subtle difference, but important one.
#6
I copied over the chimneyfire.cs to RTS. In RTS, they are available to place in the WorldCreator, as are the datablocks, but only the 'marker' is there.
I'm missing an important concept here, probably has something to do with server/client, but I don't know what ;) Any ideas?
01/31/2006 (1:54 pm)
Actually, I can't seem to get a basic particleemitter working for the RTS. In FPS I can place one with the mission editor or with script and they work.I copied over the chimneyfire.cs to RTS. In RTS, they are available to place in the WorldCreator, as are the datablocks, but only the 'marker' is there.
I'm missing an important concept here, probably has something to do with server/client, but I don't know what ;) Any ideas?
#7
So I pored through the forums searching on various and sundry, and came upon something about making the particles ghostable and always scoped.
So I went into ParticleEmitter.cc and changed line 84 from:
to
and recompiled.
Apparently, and a big discovery for me about netObjects, is that these flags are pretty important if you want certain things to show up on the client. And it's a lot more complex than that potentially. This would be the first thing I know about netObjects ;) But I came across a few great docs that I tucked away for future reading.
Anyway, I still had no way to test the particles without any being in the game, so I decided to try an easier approach. I thought of the World Editor and its particle emitter placement, and placed one in a map. (I had previously copied over chimneyfire.cs from starter.fps and made sure to execute it in the game.cs). I filled in the name, chose the chimneysmoke datablocks and clicked OK. After a second or two pregnant with anticipation, the little emitter started coughing up smoke. *Cough!* Yeah! It was a profound moment, probably similar to when Og and Mork were rubbing two sticks together several hundred thousand years ago. I made a fire emitter as well and tweaked the settings in the chimneyfire.cs a little to see if I could change it a little (I hadn't even touched particles yet in my learning)
Then I cheated!! Bigtime! But what a shortcut... I saved the mission, went into the mission file and snagged the block of code that the editor created for the smoke emitter and fire nodes. I copy/pasted it into an area I knew would get called when a building was built, to see it in action quickly.
I used:
In case you're wondering what the "MySmoke" @ %b is all about, in this case, %b was the server ID for the building from the serverCmdPlacebuilding in building.cs. Normally the calls looks like: "new ParticleEmitterNode(MySmoke1)", but I didn't want to run into any problems with unique names, so I tried this to be safe.
To my wonder and surprise, when I placed that building, it started to sputter and cough... but in the original location from the World Editor. Doh! In console, I did a 2338.dump(); to see all the functions available to the building, spotted a getPosition function.
So I tried echo(2338.getPosition());
Lo and Behold, it gave me the 3 coord position in the same format the emitter used. So I went back into building.cs and changed the 2 calls to:
And re-exec'd the building.cs (I learned to do this while game is running, quicker than shutting down, deleting DSO's and restarting)
This time when I placed a building, it started smoking and firing in place. I can see that I will need to make the particle emitter bigger, and move it up more so it isn't floored inside the building. But smoke and fire did rise!
I placed a second building as well to make sure it would scale to 2 buildings, and indeed it did with no problems.
I noticed it looked like an industrial chimney smoke, which made me realize I figured out how to create special effects for buildings! I hope you can make an explosion now.
Some major ToDos:
1) I changed source, I didn't even bother trying to set something like ghostable=true in the particleemitternode, I think I could've done this in script.
2) Did not try this with 2 connections to see if they are always visible
3) The emitters will stay there even after the building is destroyed, so its time to make an onDestroy function that will do the cleanup for me, it's good that I will be using emitters with the buildingIds in them.
4) Try changing the settings of the emitter as the building's health goes down, to create a dynamic effect. ie more fire with less health.
5) Figure out how to mount this to nodes on the building, might give more control but would need art tweaks to add the nodes.
6) Go back and see what Stephen was talking about the RTSAttack, if this would be a better implementation.
7) Find an easier way to make particle effects! I can think of many variations on particles, but have no good way to create them or edit them. In something called RealmCrafter, it was possible to make directional and shaped particle effects so you could do cylinders, rings, etc. Cloud swarms, etc. Torque have anything like this?
Have fun! Please let me know if you come up with some improvements, this was fun to learn about.
02/01/2006 (4:56 am)
I admit that I spent several hours trying to get particles to show up on different things, to no avail. I tried the mountedParticle resource, and it seemed to work because of the echo's I saw, but I didn't *see* anything.So I pored through the forums searching on various and sundry, and came upon something about making the particles ghostable and always scoped.
So I went into ParticleEmitter.cc and changed line 84 from:
mNetFlags.set(Ghostable);
to
mNetFlags.set(ScopeAlways | Ghostable);
and recompiled.
Apparently, and a big discovery for me about netObjects, is that these flags are pretty important if you want certain things to show up on the client. And it's a lot more complex than that potentially. This would be the first thing I know about netObjects ;) But I came across a few great docs that I tucked away for future reading.
Anyway, I still had no way to test the particles without any being in the game, so I decided to try an easier approach. I thought of the World Editor and its particle emitter placement, and placed one in a map. (I had previously copied over chimneyfire.cs from starter.fps and made sure to execute it in the game.cs). I filled in the name, chose the chimneysmoke datablocks and clicked OK. After a second or two pregnant with anticipation, the little emitter started coughing up smoke. *Cough!* Yeah! It was a profound moment, probably similar to when Og and Mork were rubbing two sticks together several hundred thousand years ago. I made a fire emitter as well and tweaked the settings in the chimneyfire.cs a little to see if I could change it a little (I hadn't even touched particles yet in my learning)
Then I cheated!! Bigtime! But what a shortcut... I saved the mission, went into the mission file and snagged the block of code that the editor created for the smoke emitter and fire nodes. I copy/pasted it into an area I knew would get called when a building was built, to see it in action quickly.
I used:
new ParticleEmitterNode(("Myfire" @ %b)) {
position = "-39.5223 -61.4361 246.322";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "ChimneyFireEmitterNode";
emitter = "ChimneyFireEmitter";
velocity = "1";
};
new ParticleEmitterNode(("MySmoke" @ %b)) {
position = "-40.5273 -60.6182 245.978";
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "ChimneySmokeEmitterNode";
emitter = "ChimneySmokeEmitter";
velocity = "1";
};In case you're wondering what the "MySmoke" @ %b is all about, in this case, %b was the server ID for the building from the serverCmdPlacebuilding in building.cs. Normally the calls looks like: "new ParticleEmitterNode(MySmoke1)", but I didn't want to run into any problems with unique names, so I tried this to be safe.
To my wonder and surprise, when I placed that building, it started to sputter and cough... but in the original location from the World Editor. Doh! In console, I did a 2338.dump(); to see all the functions available to the building, spotted a getPosition function.
So I tried echo(2338.getPosition());
Lo and Behold, it gave me the 3 coord position in the same format the emitter used. So I went back into building.cs and changed the 2 calls to:
new ParticleEmitterNode(("Myfire" @ %b)) {
position = %b.getPosition();
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "ChimneyFireEmitterNode";
emitter = "ChimneyFireEmitter";
velocity = "1";
};
new ParticleEmitterNode(("MySmoke" @ %b)) {
position = %b.getPosition();
rotation = "1 0 0 0";
scale = "1 1 1";
dataBlock = "ChimneySmokeEmitterNode";
emitter = "ChimneySmokeEmitter";
velocity = "1";
};And re-exec'd the building.cs (I learned to do this while game is running, quicker than shutting down, deleting DSO's and restarting)
This time when I placed a building, it started smoking and firing in place. I can see that I will need to make the particle emitter bigger, and move it up more so it isn't floored inside the building. But smoke and fire did rise!
I placed a second building as well to make sure it would scale to 2 buildings, and indeed it did with no problems.
I noticed it looked like an industrial chimney smoke, which made me realize I figured out how to create special effects for buildings! I hope you can make an explosion now.
Some major ToDos:
1) I changed source, I didn't even bother trying to set something like ghostable=true in the particleemitternode, I think I could've done this in script.
2) Did not try this with 2 connections to see if they are always visible
3) The emitters will stay there even after the building is destroyed, so its time to make an onDestroy function that will do the cleanup for me, it's good that I will be using emitters with the buildingIds in them.
4) Try changing the settings of the emitter as the building's health goes down, to create a dynamic effect. ie more fire with less health.
5) Figure out how to mount this to nodes on the building, might give more control but would need art tweaks to add the nodes.
6) Go back and see what Stephen was talking about the RTSAttack, if this would be a better implementation.
7) Find an easier way to make particle effects! I can think of many variations on particles, but have no good way to create them or edit them. In something called RealmCrafter, it was possible to make directional and shaped particle effects so you could do cylinders, rings, etc. Cloud swarms, etc. Torque have anything like this?
Have fun! Please let me know if you come up with some improvements, this was fun to learn about.
#8
What you've done here is to (by setting the GhostAlways flag) make your particle emitters networked to ALL clients, ALL the time. Basically, in a 3-10 player game, all players will see the particles, even if they can't see the building! The reason for this lies deep in the networking model, and it may be a good time for you to delve deeply into it, so I suggest this TDN article on Torque Networking. With this particular codebase and challenge, what you really would do if you chose to continue ghosting as your solution would be to properly adjust the onCameraScopeQuery (scoping rules) for particles to work with the RTSConnection.
The correct (or at least, more correct) way of doing this would be to have the emitters created client side only (currently you have them server side, and then networked to the clients), and turned on/off via a NetEvent (either script base commandToClient, or using the RTSExplosionEvent/RTSParticleEvent/whatever you decide to implement.
I also wanted to point out the Torque Torque Class Hierarchy documentation, which is an excellent way to become more familiar with all the Torque classes.
02/01/2006 (9:34 am)
Great to see some progress, but wanted to give a little guidance as well!What you've done here is to (by setting the GhostAlways flag) make your particle emitters networked to ALL clients, ALL the time. Basically, in a 3-10 player game, all players will see the particles, even if they can't see the building! The reason for this lies deep in the networking model, and it may be a good time for you to delve deeply into it, so I suggest this TDN article on Torque Networking. With this particular codebase and challenge, what you really would do if you chose to continue ghosting as your solution would be to properly adjust the onCameraScopeQuery (scoping rules) for particles to work with the RTSConnection.
The correct (or at least, more correct) way of doing this would be to have the emitters created client side only (currently you have them server side, and then networked to the clients), and turned on/off via a NetEvent (either script base commandToClient, or using the RTSExplosionEvent/RTSParticleEvent/whatever you decide to implement.
I also wanted to point out the Torque Torque Class Hierarchy documentation, which is an excellent way to become more familiar with all the Torque classes.
#9
[Edit] I created a new thread to deal with explosion/damage effects on units, I will post up a corssref when a solution has been found. sorry to hijack!
02/01/2006 (10:01 am)
Thanks Stephen, I will definitely be jumping into that, good to have some guidance.[Edit] I created a new thread to deal with explosion/damage effects on units, I will post up a corssref when a solution has been found. sorry to hijack!
Torque 3D Owner Dave Young
Dave Young Games