Particles

From: Jopsy Pendragon

Particle Anatomy- Prims
Particles, like Light, requires a source. In SecondLife, that source is always a prim.

Any prim can emit particles, though some shapes, sizes and rotation work better than others depending on what you're trying to do.

There are two things to remember when choosing a prim to put particles on:

1) SIZE: Use small with small and big with big. Tiny particle effect? pick tiny particles and tiny prims. BIG particle effect? pick BIG prims and BIG particles. (why will be explained later)

2) ROTATION and SHAPE: Some 'angular' particle displays are sensitive to the rotation of their source prim. Some prims, like Sphere, Torus, Ring and Tube are created turned on their side, others aren't.

Particle Anatomy - The llParticleSystem Function
Each particle setting has a default value. If you send llParticleSystem an EMPTY LIST, it will use all the defaults. Incidentally, using ALL the default settings will turn a particle emitter off, like this:

default { state_entry { llParticleSystem( [ ] ); } }

To override one setting you must specify the name of the setting and the new value for it: Like COLOR and RED.

.... llParticleSystem( [ PSYS_PART_START_COLOR, < 1.0, 0.0, 0.0 > ] ); ...

If you want to override two settings it could look like this:

... llParticleSystem( [ PSYS_PART_START_COLOR, < 1.0, 0.0, 0.0 >, PSYS_PART_START_SCALE, < 2.5, 2.5, 0 > ] ); ...

Each time you add something to the LIST, you do so as pairs of NAME and VALUE.

As you go through the lab you'll learn each of the setting NAMES as well as their default and legal VALUES.

Some names start with PSYS_SRC_ (mostly for emitter settings) others start with PSYS_PART_ (mostly for particle settings).

Advanced Note: In reality, each PSYS_ name is really just an integer number. If you were to include a line like: llOwnerSay( (string) PSYS_SRC_PATTERN ); You would get the integer number for that parameter. You don't NEED to use the PSYS_ constants if you don't want to. For example, the below script is completely legal... but will be very difficult to debug or adjust later:

default { state_entry { llParticleSystem( [ 7,5.500, 0,371, 1,<1.113,0.21,1.107>, 3,<0.52,0.61,0.49>, 5,<0.0,0.0,0.0>, 6,<5.500,5.500,0.0>, 9,8, 13,0.1, 8,<0.0,0.0,0.0>, 15,1, 16,0.0, 17,2.228, 18,2.228, 22,1.157, 23,1.157, 21,<0.0,0.0,0.0>, 19,0.0, 12,"", 2,0.80, 4,0.0 ] ); } }

Particle Anatomy - Emitters
There is an invisible emitter at the center of every prim.

The emitter will point at the top of its prim by default, (or it will rotate after every burst of particles)

How to turn an Emitter OFF: You must use llParticleSystem to turn off an emitter. Simply deleting the particle script is not enough! The default setting for an emitter is off, so all you need to do is send an empty list of to llParticleSystem, like this:

default { state_entry { llParticleSystem( [ ] ); } }

How to turn an Emitter ON: You must override the default setting for PATTERN to turn on an Emitter. Pattern types are DROP, ANGLE, ANGLE_CONE and EXPLODE. For example, the absolute minimum you need to start creating particles is this script:

default { state_entry { llParticleSystem( [ PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE ] ); } }

Particle SCALE
The script in this example is:

default { state_entry { llParticleSystem( [ PSYS_PART_START_SCALE,< 4.0, 0.1, 0>, PSYS_PART_END_SCALE, < 0.1, 4.0, 0>,

PSYS_SRC_BURST_PART_COUNT, 2, PSYS_SRC_BURST_RATE, 3.00, PSYS_PART_MAX_AGE, 5.0, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,

PSYS_PART_FLAGS, PSYS_PART_INTERP_SCALE_MASK ] ); } }

(Ignore the middle section with COUNT, RATE, AGE and PATTERN until later.)

SCALE: maximum: < 4.00, 4.00, 0 > default: < 1.00, 1.00, 0 > minimum: < 0.04, 0.04, 0 > (*)

The 'z' part of the vector is ignored because particles are flat!

Particles in this example start wide/short and end tall/narrow.

The option to resize particles, like all flags, is OFF by default. To enable it, you must include the PSYS_PART_INTERP_SCALE_MASK as one of the PSYS_PART_FLAGS as shown above. (No other flags are used in this example so this is very simple.)

(*) - Particles shorter or narrower than 0.04m seem to not be drawn at all... UNLESS at some point in the particles life it is both wider and taller than 0.04m, your milage may vary.

Particle COLOR
The script in this example is:

default { state_entry { llParticleSystem( [ PSYS_PART_START_COLOR,< 0.0, 1.0, 0.0 >, PSYS_PART_END_COLOR, < 1.0, 0.0, 0.0 >,

PSYS_PART_START_SCALE,< 3.0, 3.0, 0 >, PSYS_SRC_BURST_PART_COUNT,2, PSYS_SRC_BURST_RATE,5.2, PSYS_PART_MAX_AGE,5.0, PSYS_SRC_PATTERN,PSYS_SRC_PATTERN_DROP,

PSYS_PART_FLAGS, PSYS_PART_INTERP_COLOR_MASK ] ); } }

(Ignore the middle section with SCALE, COUNT, RATE, AGE and PATTERN until later.)

COLOR < red, green, blue >: maximum: < 1, 1, 1 > (white, the default) minimum: < 0.0, 0.0, 0.0 > (black)

Particles in this example start green and end red.

The option to re-color particles, like all flags, is OFF by default. To enable it, you must include the PSYS_PART_INTERP_COLOR_MASK as one of the PSYS_PART_FLAGS as shown above. (No other flags are used in this example)

Particle color CAN be affected by nearby light sources. One of the most common particle options causes particles to be 'full brightness'. To add it to this script you would change the flags line to be:

PSYS_PART_FLAGS, PSYS_PART_INTERP_COLOR_MASK | PSYS_PART_EMISSIVE_MASK

See the example on FLAGS and MASKS for an explanation.

If you're not familiar with color vectors, it's helpful to know that: red is <1,0,0>, green <0,1,0>, blue <0,0,1> yellow is <1,1,0>, cyan <0,1,1> and magenta <1,0,1> Pink is <1,0.5,0.75>, etc...

Particle ALPHA
The script in this example is:

default { state_entry { llParticleSystem( [ PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 0.0,

PSYS_PART_START_SCALE,< 3.0, 3.0, 0 >, PSYS_SRC_BURST_PART_COUNT,3, PSYS_SRC_BURST_RATE,4.0, PSYS_PART_MAX_AGE,3.9, PSYS_SRC_PATTERN,PSYS_SRC_PATTERN_DROP,

PSYS_PART_FLAGS,PSYS_PART_INTERP_COLOR_MASK ] ); } }

(Ignore the middle section with COUNT, RATE, AGE and PATTERN until later.)

ALPHA: maximum: 1.0 (opaque, the default) minimum: 0.0 (fully transparent)

Particles in this example start opaque and fade away.

The option to fade particles, is off by default but enabled when you enable the ability to change particle color. (See the previous example).

Particles can only fade away, they can't fade "in", unfortunately. So keep values for START_ALPHA greater than END_ALPHA. Maybe someday LL will let particles fade in.

Particle ALPHA (Windlight Viewer ONLY)
The script in this example is:

default { state_entry { llParticleSystem( [ PSYS_PART_START_ALPHA, 1.0, PSYS_PART_END_ALPHA, 0.0,

PSYS_PART_START_SCALE,< 3.0, 3.0, 0 >, PSYS_SRC_BURST_PART_COUNT,3, PSYS_SRC_BURST_RATE,4.0, PSYS_PART_MAX_AGE,3.9, PSYS_SRC_PATTERN,PSYS_SRC_PATTERN_DROP,

PSYS_PART_FLAGS,PSYS_PART_INTERP_COLOR_MASK ] ); } }

(Ignore the middle section with COUNT, RATE, AGE and PATTERN until later.)

ALPHA: maximum: 1.0 (opaque, the default) minimum: 0.0 (fully transparent)

Particles in this example start opaque and fade away.

The option to fade particles, is off by default but enabled when you enable the ability to change particle color. (See the previous example).

Particles can only fade away, they can't fade "in", unfortunately. So keep values for START_ALPHA greater than END_ALPHA. Maybe someday LL will let particles fade in.

The FOLLOW_VELOCITY option - also known as "Tilt"
This example has a bit more going on here than just 'tilting' the texture, but it's included in this group because it's the last of the settings that affect how a particle looks.

Particle textures appear in one of two ways, straight up and down, (no tilt) or tilted towards the direction they're going.

If the particle texture isn't rotated in a direction you want, you may need to use (or create!) a different texture for your purpose.

The on/off switch that enables texture 'tilt' is called:

PSYS_PART_FOLLOW_VELOCITY_MASK

For this option to work... particles have to have some velocity. Without movement, turning on FOLLOW_VELOCITY usually results in no particles being seen.

TEXTURE and the EMISSIVE mask
The script in this example is:

default { state_entry { llParticleSystem( [ PSYS_PART_START_SCALE,< 0.1, 0.1, 0 >, PSYS_PART_END_SCALE,< 3.0, 3.0, 0 >, PSYS_PART_START_COLOR,<1,1,0>, PSYS_PART_END_COLOR,<1,0,1>, PSYS_PART_START_ALPHA,1.0, PSYS_PART_END_ALPHA,0.3,

PSYS_SRC_TEXTURE, "f8e2c2f0-7d5e-bb9a-68d0-7a3e87984784",

PSYS_SRC_BURST_PART_COUNT, 3, PSYS_SRC_BURST_RATE, 4.0, PSYS_PART_MAX_AGE, 3.9, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,

PSYS_PART_FLAGS, ( PSYS_PART_INTERP_COLOR_MASK | PSYS_PART_INTERP_SCALE_MASK ] ); } }
 * PSYS_PART_EMISSIVE_MASK )

(Ignore the middle section with COUNT, RATE, AGE and PATTERN.)

Now we're getting somewhere. These particles start off as Little Yellow (and different?), and become big and magenta as they fade away partly. Texture, in this example, is the key of a texture. In this case, a lightning bolt-like image.

Texture can also be the NAME of a texture... for example:

PSYS_SRC_TEXTURE, "My Texture Name", //only works if you put the texture in the prims inventory!

but the name must match a texture stored in that prim's contents. (note, you can't put a texture into the contents of a prim that you are wearing, or one that's in your inventory... it must be a prim in the world!)

Note: No-Transfer textures must be stored in the prim's inventory and referred to by name because their Asset UUID key's can't be seen.

The EMISSIVE mask makes particles full bright, and unaffected by nearby lightsources. They don't actually shed any light onto nearby prims or particles however.

You can use EMISSIVE without TEXTURE and vice versa, they were just shown together in this example to economize on exhibits.

Not that you would ever need it but the asset UUID or 'key' for the default particle texture seems to be: 168e6813-096e-07ea-97ae-fd416826f627//

Particle FLOW
These four settings control the "heartbeat" of all particle displays

PSYS_SRC_BURST_COUNT = particle quantity per burst PSYS_SRC_BURST_RATE = the delay interval between bursts PSYS_PART_MAX_AGE = how long each particle lives PSYS_SRC_MAX_AGE = how long the emitter will create new bursts

It is very easy to create 'wasteful' particle effects if you are not careful with these parameters. Tune them carefully to use as few concurrent particles as you can. If try to use too many particles, the excess simply will not be seen, which can cause your particle display to suffer.

The default maximum number of particles is 4096. (that's from all emitters inside of a player's draw distance, not per emitter!). When emitters try to create more than 4096 particles all at the same time, the result turns ugly. Big gaps, faint displays, really slow computer performance, and emitter failure results.

You can't control the number of particles being displayed nearby, so it's up to you to make sure that your particle display 'plays well with others'. This means sharing... and not trying to hog all 4096 particles to yourself.

10 particles per burst, each living for 10 seconds with bursts every tenth (0.1th) of a second = 1000 particles.

You can calculate how many particles your emitter is responsible with this formula:

( age / rate ) * count

Even just one emitter can use up all 4096 particles, creating 1 at a time at a burst rate of 0.01, if the particles live for 40.96 seconds.

Using a burst rate of 0.00 is not recommended unless count = 1 and the age for the particles is 5 seconds or less.

PSYS_SRC_MAX_AGE

This setting says how many seconds to wait before turning the emitter off. 0 = never shut off. The maximum is 60 seconds. Sometimes it's better to turn particles off completely rather than use this to shut them off.

If this setting is not 0, the shut-off count-down is restarted everytime the prim is rezzed. If you fly away and come back it starts over for you, (but not for the other people near the emitter that didn't leave!). If you are wearing it and cross a sim boundary, the count-down starts over too.

Particle Placement - PATTERN
Radius sets how far away from the emitter each new particle will be created. Default is 0.0m, maximum is 50.0m.

Radius has no meaning with the DROP pattern.

If you use FOLLOW SOURCE (described in the next section), then RADIUS will be forced back to 0.0m.

Particle Placement - PATTERN
There are 4 particle PATTERN types: DROP, ANGLE, ANGLE_CONE and EXPLODE

DROP - particles appear at the emitter with no initial speed.

ANGLE - Sprays particles in a flat 'fan' shape.

ANGLE_CONE - sprays particles out in a cone shape

EXPLODE - sprays particles in all directions.

Comments: Explode seems to be everyone's favorite pattern, it's big and splashy, but gives less control.

I rarely use ANGLE_CONE, I find most of what I'm trying to accomplish I can do better with ANGLE.

DROP - can be useful for stationary effects, like a 'glow' around a candle flame, or, with the WIND and ACCEL parameters, smoke.

ANGLE - is my favorite, particularly with omega, you can make anything from spirals to dancing flames with a little practice. :)

If you do not specify a pattern type, your emitter will default to OFF.

The DROP Pattern
The simplest of the 4 patterns, that just creates new particles at the center of the prim with no initial velocity or heading.

They have no initial velocity or direction. If you use none of the MOVEMENT controls (defined in the next section) the particle would just stay exactly were it was created. (step on the green demonstrator next to the spigot here to see that effect).

This example uses the ACCEL parameter to create a small but constant downward force on particles. It also has the WIND option turned on, so droplets are being blown from side to side by the wind a little.

DROP patterns are good for 'glow' effects and light trails that are left behind by moving objects.

The DROP pattern is not compatible with several of the settings listed next, like the placement controls: RADIUS, OMEGA and ANGLE_BEGIN and _END. DROP also disables MIN_ and MAX_SPEED,

Creates a blinking 'glow' dropped particle effect default { state_entry { llParticleSystem( [ PSYS_SRC_BURST_RATE, 2.0, PSYS_PART_MAX_AGE, 1.0, PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP ] ); } }

Particles - USING ANGLES
These work only with the ANGLE or ANGLE_CONE patterns.

ANGLE_BEGIN and ANGLE_END are left undefined, they default to 0.0. This creates a stream of particles shooting straight up.

Using only ANGLE_BEGIN, or ANGLE_END (but not both) creates a fan shape or cone shape of particles around the upward Z axis of the prim.

Using both ANGLE_BEGIN and ANGLE_END results in a fan or cone with a gap where particles don't appear. The area between the ends of one arc and the other arc are where new particles are created.

If ANGLE_BEGIN and ANGLE_END values are the same.. the result is particles created only at the edges of the fan or cone shape. It doesn't matter if ANGLE_BEGIN is smaller or larger than ANGLE_END, if it's 1,2 or 2,1 the result is identical.

Common settings for ANGLE_BEGIN and ANGLE_END :

0.0, 0.0 : 1 stream straight up. PI/4, PI/4 : two thin streams 45 degrees (the arc is 90 wide) away from the prim's upward Z axis (for angle patterns) or a empty cone shape.

PI_BY_TWO, PI_BY_TWO : 2 streams of particles, one goes right, the other left., exactly opposite each other. (for angle patterns) A flat disk of particles going out in all directions perpendicular to the Z axis.

PI, PI : a stream shooting straight down the prim's Z axis.

0.0, PI (or PI, 0.0) : A flat disk of particles perpendicular to the prim's X axis (not Z!) for angle patterns. for cone patterns the effect looks very much like the explode pattern with BOUNCE turned on.

Particles appear randomly anywhere within the area they're allowed to be created. If that area is wide, it becomes difficult to see that there's any ANGLE control in use without using MANY particles. I prefer to use very narrow areas when I use angle settings to focus streams into more visible results.

If you're an advanced particle type, feel free to take a look at the older and depreciated INNERANGLE and OUTERANGLE exhibit.

Using PSYS_SRC_OMEGA
PSYS_SRC_OMEGA is used to continuously spin the aim of your particle emitter around a global axis. The direction your emitter faces is rotated around the X, Y and Z axis the amount you specify after each burst of particles.

OMEGA sets the rotation amount but BURST_RATE sets the rotation frequency. Re-tune your OMEGA values whenever you adjust your emitter's BURST_RATE.

OMEGA is only useful with ANGLE and CONE patterns. (it has no visible effect with DROP or EXPLODE)

PSYS_SRC_OMEGA utterly ignores the orientation/rotation of the emitter prim!

//a very simple omega script default { state_entry { llParticleSystem( [ PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE, PSYS_SRC_ANGLE_BEGIN, 0.1, PSYS_SRC_OMEGA, <0.3, - 0.2, 0.1 > ] ); } }

If you want to disable OMEGA rotation, give it a ZERO_VECTOR ( like: <0,0,0> ).

If you want the axis of rotation to be aligned with the prim's local rotation, try this://

Sample omega script that adjusts to the prim's rotation. default { state_entry { llParticleSystem( [ PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE, PSYS_SRC_ANGLE_BEGIN, 0.1, PSYS_SRC_OMEGA, <0.3, - 0.2, 0.1 > * llGetRot ] ); } }

NOTE: This is a one time compensation. You will need to restart the particle effect each time the prim's rotation changes. You may have to reset OMEGA each time too! This is neither ideal nor pleasant, but it is possible, though not without a cost that creates some to sim and network lag.

Using PSYS_SRC_ACCEL
PSYS_SRC_ACCEL is used to continuously nudge particles in a certain global direction, regardless of which way your emitter prim is rotated. It's most useful for simulating the effect of 'gravity' (or 'anti-gravity' ) on your particles. It can also be used to simulate a controlled and constant 'wind'.

//a very simple ACCEL script default { state_entry { llParticleSystem( [ PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP, PSYS_SRC_ACCEL, <0.3, - 0.2, 0.1 > ] ); } }

If you want to disable ACCEL rotation, give it a ZERO_VECTOR ( like: <0,0,0> ), (which is also the default ).

How do I make ACCEL 'local' instead of 'global' ?

If you want the direction of force to be aligned to the rotation of your emitter prim, try this://

Sample accel script that sets direction relative to prim rotation: default { state_entry { llParticleSystem( [ PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE, PSYS_SRC_ANGLE_BEGIN, 0.1, PSYS_SRC_OMEGA, <0,0, -0.5 > * llGetRot ] ); } }

NOTE: If you rotate the prim after the particles have started, the direction that ACCEL pushes particles won't change. You must call llParticleSystem AGAIN anytime the prim rotates in order to adjust the direciton that ACCEL pushes particles.

<span style="color: #000080; font-family: 'Comic Sans MS',cursive;">Particles - Push Tricks - By Jopsy Pendragon - 5/12/2004
BOUNCE is meaningless unless particles are moving downwards, so you often need to have them spray up, and then use PUSH (or PSYS_SRC_ACCEL) to smash them back down again so that they will bounce, like this volcano here.

Particles shoot up... push overcomes their upward momentum and shoves them back down. When they hit the altitude their emitter is at, BOUNCE flips them back up again. This example also has WIND turned on, so as particles bounce they drift further away from the emitter.

Many of my favorite tricks involve turning the emitter prim to face a specific direction, and using ANGLE or ANGLE_CONE with very small values, and using a push to throw particles back towards the emitter. Quite often I'll also add a TARGET and WIND. For longer lived particles this can mean 3 or more changes in direction as the particle ages, and a much more intriguing result than an ever expanding spray of particles. :)

Tuning Min&Max Speed against a push in the opposite direction is delicate work, to adjust the height of this volcano, I have to adjust both at the same time. I keep 'push' just slightly more than the averate between min and max speed usually to ensure that some particles will bounce.

-

<span style="color: #ff0000; font-family: 'Comic Sans MS',cursive;">Play & Practice
---

Getting started with your first experimentation script can be tricky. So many settings to twiddle!

You can start with the APPEARANCE (white settings) at any point, I usually start with them, to determine the particle size, color, alpha and texture before I experiment with the rest.

Setting the style of a display: Look throught the PLACEMENT (green examples) and MOVEMENT (blue examples) to pick a few effects you would like to try.

Tuning the display: Adjusting the PRODUCTION (red examples) values is very tricky, you will also have to adjust some blue settings like MIN and MAX SPEED, and perhaps ACCEL increasing or decreasing them as you adjust the AGE of your particles up or down.

Making sure your particles are moving fast (or slow) enough so that they fill a desired space before they evaporate can take a lot of tweaking, but once you get the hang of it you'll be turning out masterful particle displays in no time.

Once you get the effect you like, try tuning it a little more and see if you can keep the illusion but using fewer particles! :) If you master this art, you can have more of your particle exhibits near each other without running out of display able particles! :)

(The scripts in these template rings are free for you to re-use/re-sell as you like! But please, put the script in a new prim that you created! I get asked often where I sell things that I've never heard of because my name sometimes appears as the object's Creator! :)

Have fun! And good luck! :)

-

<span style="color: #ff0000; font-family: 'Comic Sans MS',cursive;">Trouble Shooting
---

(A). No particles! (B). Too many Particles! Help!

(A) NO PARTICLES? Make sure you can say yes to the following things:

Do you see any particles at all anywhere? Make sure you haven't disabled particles! Check: Edit -> Preferences -> Adv. Graphics -> Max Particle Count: 4096)

1. Did you SAVE the script? 2. Are there script errors? (skip to next section for common script errors) 3. Is the the script running? (check the "[ ] Running" checkbox in the lower left of the script window)

4. Is SCALE larger than < 0.0384, 0.0384, 0.0 >? 5. Is START_ALPHA less than 0.1 ?

6. Is BURST_COUNT greater than 0? 7. Is PART_MAX_AGE less than 1.0 second? 8. IS SRC_MAX_AGE 0.0 or greater 1.0 ? 9. Is BURST_RATE less than 30.0 second?

10. Are SPEED_MIN and MAX greater than 0.0? 11. Are your particles large enough, and fast enough to be seen outside your emitter prim?

When in doubt... select the object, and try: Tools -> Reset All Scripts in Selection

SCRIPTING ERRORS:


 * ERROR : Syntax error -- You may be missing a comma between items in your particle definition list.

Look for where the cursor is when you hit (SAVE), and your error is usually at or just before the cursor.

Object: PSYS error: rule # error, PSYS_(something) needs float data You used an integer when a floating number was expected. (add a decimal point to the number)! Or... your value for that parameter may be missing entirely!

(B) TOO MANY PARTICLES!

If you can't see your emitter in the particle cloud, press CTRL-ALT-SHIFT-EQUALSIGN (=) to hide all particles. (You may have to enable the debug "Client & Server" menus with Ctrl-Alt-Shift-D for this to work)

View -> Beacons -> Particle Sources is useful too for finding prims that emit particles. (May have to toggle with Control-N)

(previous debugging tips... notecard still in draft form)

Pull down Debug -> Rendering -> Types -> You should see an 'X' by 'Particles', if not, select that option.

Script running? Open your particle script up, on the bottom left you should see an checkmark for '[x] Running'

Particles too small? Particles must be at least 0.04 wide and tall at some point in their life to be displayed.

Particles to faint? Is your ALPHA setting really low? (below 0.1?) Make sure you have PSYS_PART_INTERP_SCALE_MASK and PSYS_PART_INTERP_COLOR_MASK enabled if your particles are supposed to change color/size/transparency.

Particle drought? Is AGE really small? Is COUNT = 0? Is your RATE really long? These can trip you up too.

Particles hidden inside their emitter? Try setting your emitter prim transparent, the particles may just be trapped inside!

Particles going nowhere? Unless you use DROP, particles MUST have a minspeed/maxspeed of at least 0.01, or they don't appear.

Particles going too far, too fast to be seen? Faster than the speed of light? What's your minSpeed set to? They might be too far away or too fast to see. Check your RADIUS setting? if it's larger than 10, look further away from the emitter for your particles.

Emitter not being rendered? Small prims far from the viewer often don't get drawn, and when they don't, neither do the particles on that prim. This effect happens especially with small prims under water closer to the viewer too. You can use this to your advantage! Make small delicate particle effects on small prims so that they don't show up unless someone is nearby and can appreciate it!

Particle overload? Too many particles going on nearby? Each client can only display so many particles at a time. If there are several emitters near a viewer all pumping out lots of particles, your emitter may be creating so few that it seems broken. Give a hoot, don't pollute!

Typo? If all else fails, look for misplaced decimal points. :)