ID:802467
 
Applies to:Dream Maker
Status: Open

Issue hasn't been assigned a status value.
I've recently witnessed several projects move away from BYOND in favor of other languages and engines. They all chose not to use BYOND for various reasons, but one big reason they all shared was BYOND's lack of particle effects. Big, juicy particle effects are a huge factor in a game's slickness and addictiveness, I think it's something worth giving some thought.

Particle effects can certainly be user-made, but they're always heavily dependent on network conditions and use up valuable bandwidth. If you wanted to do something like show damage text you'll have to create some numbers then update their pixel offset every tick. You would have to do the same with smoke for example and raise its pixel_y every tick while maybe swaying it to the left and right. The thing is, if there are any connection hitches the particles will jump several pixels at a time, ruining the whole effect. In a worst case scenario with a choppy connection you would only see a few "snapshots" out of the entire animation.

What I'd like to see is BYOND add some sort of particle datum to fill this role. It wouldn't have to use true client-side processing, it would just need to offload some of the processing from the server to the client. It would need to take predefined variables and animate particles in a predictable fashion. I have a good idea of how I'd like some of the effects to work, but I'm just one developer so please chime in if you think of something better.

The way I see it, there are three main variables a particle needs. Angle, Speed, and Duration. After being created the particle needs to know which direction to travel in, how fast, and for how long. With these variables you have your basic "line" particle animation. Expanding on that, there would be a Tilt variable which determines how much Angle should be adjusted each tick. With this extra variable you could change a line into a circular shape. From here it gets a little more complicated depending on how advanced the particles should be. If you could stack effects on the same particle you could do something like take a circular particle animation then add a line animation to it, creating a spiral animation. If you took a circle animation then flipped it every 180 degrees you would get an wave animation.

I think the key here is robustness, a few very simple rules which can be combined in different ways would cover most use cases. The particles should be visual-only, they should be super cheap and efficient to use. They wont replace standard projectile effects which have collision properties, but they'll be able to act as the bullet shell flying out of the weapon, the smoke from the barrel, the vapor trail left by the bullet, the blood splatter from the victim, and finally the damage numbers flying over the victim's head.
I like the suggestion, but I am afraid that this would open a huge can of worms because the limited effects are going to beget tremendous feature creep. I'm not saying that is reason to avoid exploring such a thing (it is very similar to the excellent idea of having transformation variables associated with atoms). But I would want to see if there is a more general solution first.

I don't know if such a thing exists, but the ideal thing here would be using an existing particle engine on top of the client. It would have to be an interpreted language, of course, and I'm not sure how it would handle icons. But in theory, if one could just give a pixel "start" location and a set of commands to pass to the engine, BYOND could have more powerful effects without having to reinvent the wheel.

Is there such a thing?
There's Spark which seems to be an open source C++ particle engine.

It's capable of some really nice effects.
In response to SuperAntx (#2)
I believe Tom is looking for an implementation that works with an interpreted language, not something compiled like C++.
So LUA, for instance.
In response to Murrawhip (#3)
That's just something I'm too out of touch with. There are a bunch of free/open source particle engines but I don't know of any using interpreted languages.
I'd love to see the ability to do this with BYOND but I'd hate to see it implemented this way. It'd be too limited and it'd almost be easier to create a more solid, useful feature.

BYOND desparately needs variables to control the rotation, opacity, color, and size of objects (even if those vars can only be manipulated by the server). This alone puts you a good way towards being able to create these effects. The rest of it is being able to execute code on the client. It seems like it'd be difficult but it's actually very straightforward. Unfortunately, it'd require modifications to the DM language/compiler that I don't think the BYOND staff can make.

Dream Seeker can already execute compiled DM code, you just need a way to pack procs that can be executed on the client in the .rsc. Changes made client-side would only exist on the client (they wouldn't be propagated back to the server), they'd only affect display (changing pixel offsets, rotation, opacity, etc.), they'd take priority over changes made by the server, and they'd have a limited scope (if the proc needs to read a var, pass it as a parameter - you're not going to be doing things like for(var/mob/m in world) in a client-side proc).

This also has other uses. If you want to change the way a mob appears to certain players you don't have to create an image object and attach it to the mob, you just run a client-side proc that modifies the mob's icon or icon_state. Since the changes made by the client-side proc take priority over changes made by the server, that's all you'd have to do.

Another important thing is that procs that run client-side can generate particles. If particles are generated by the server, even if their movement and updating is handled on the client it can take a lot of bandwidth just to create all of the particles. Some effects can require tons of particles. If you could execute a single proc on the client and have it know how to generate the particles, lots of bandwidth would be saved.
This is so amazing lol.
It would make more sense to have the ability to do something like client << some_command_script("script stuff"). The script could either be something entirely new, interpreted language (DM? LUA?) or a special script datum (/script)

The script datum could allow us to pack some references that we want to effect, for example. The client would execute the script procedure on its end, processing-wise. The client could then respond to the server saying the script was completed, or you could even develop it so that each script "step" gets some sort of AK.

Here's sort of a pseudo example case:

obj/effect
icon = 'something.dmi'
icon_state = "whatever"

script/fireball //new script titled fireball
//variables defined here allows DM to know the size of the script and how much memory it can expect.
var/tmp/obj/effect = new // the client will create a new /obj/effect which will be strictly visual and won't interact with the server of anyway.
// alternately, you could just only support images or icons

New() //new is called on the client when the client receives the command to run the script
//dm initializes the obj for us on the client side
//the client see's a "obj" just like it would if the
//server had made one, but the server knows nothing
//about it and it is purely visual
spawn(30) del(src)
while(src)
//script allows us to use regular dm code like
//normal
obj.step_y++ //rising effect
//we can interact with this object client side
//and control it just like the server would, but
//its only happening on this client's computer
sleep(world.tick_lag)

mob/verb/see_effect()
src.client << new/script/fireball(src.loc) //or something? i don't know what the syntax would be


At each step of the script, the client could tell the server what step of the script it's on, or just AK when it gets the script, runs the script, and ends the script. I'm sure LummoxJR / Tom, and other really active members could think of a lot of different ways this could work and what could be possible with this type of concept.

Considering the client has the ability to create "types" on the screen and do what the server tells it to do without actually knowing anything about those "types" means this is currently entirely possible, someone just needs to flesh it out and implement it.</<>