Right now, pure-visual particle effects have overhead that they really don't need to be adding to the engine.
There are currently two ways to take advantage of animated particle effects:
1) movable atoms
2) images
Unfortunately, both have some slight problems with additional overhead that could otherwise be avoided.
/image objects would be perfect for animated particle effects if you didn't have to explicitly show them to people. Explicitly showing them to people requires that the developer either simply show all of these image objects to every user in the world, or manually iterate through each player that would feasibly be in view of the particle effects and add the images to their viewing list.
Instead of doing this, it would be much preferable if there were some kind of a flag for image objects that made them always visible to all players without inducing the same overhead as adding them to the images list of all players. In other words, they would act similarly to normal atoms, but wouldn't have a bounding box, wouldn't trigger Move()/Cross()/Uncross() behavior, etc.
Unfortunately, spawning several dozen physical atoms within a very small space can bog the engine down with a large number of calls to the movement-related functions, making physical atoms not very ideal for particle effects.
ID:1813265
Mar 18 2015, 5:31 pm
|
|||||||
| |||||||
Mar 18 2015, 5:43 pm
|
|
This sounds a lot closer to missile(). Kind of a similar concept anyway.
|
Similar, but allowing us to control the positioning and transformation via animate() as opposed to it just being a linear animation like missile() provides.
|
One thing that occurs to me about this concept: I don't see how it'd be a problem to simply use objs but not call Move() for them. Ultimately anything that might be developed to handle this would be so indistinguishable from real atoms, there's almost no point. missile() is just a fire-and-forget effect, but anything you can animate() would have more permanence by definition.
|
Well the problem is that you can't set the location as you can for images, since when you set the location for image objects to be the mob for example, it keeps following it around aka acting as an overlay, where as an object would merely try to enter the contents of said mob. No?
|
One thing that occurs to me about this concept: I don't see how it'd be a problem to simply use objs but not call Move() for them. Ultimately anything that might be developed to handle this would be so indistinguishable from real atoms, there's almost no point. missile() is just a fire-and-forget effect, but anything you can animate() would have more permanence by definition. In addition to being able to use images as mutable overlays, there's also the issue that even a small number of particles will cause all sorts of problems when something tries to Cross() them. Regardless of whether you have Cross()/Uncross() defined, they still slow down movement-related procs for other objects. It seems nonsensical to me to use atoms as particles unless they do what movable atoms are supposed to do: be physical. Unfortunately, BYOND really lacks a means of providing visible-to-all purely visual objects, and the images having to be in the client's images list to be rendered adds an extra level of overhead for view sending that would be unnecessary for a visible-to-all image. |
Also, one of the other major problems with particle effects and animate() is that objects' apparent rendering positions are not calculated based upon transform. This makes things like particle effects render incorrectly, or suddenly appear when you move and the particle's origin is now within your view.
It's a really troubling problem, and really causes developers quite a few headaches when it comes to making a game that isn't clunky. What we wind up having to do is basically avoid using animate() for what it was intended for and manually make certain that objects are rendered in the correct positions by manually changing the location of the object rather than relying on animate() to get objects to the right viewers (which it doesn't). |
I'm not familiar enough with the subject to offer much commentary, but I definitely support working out a way to get this in. It could be pretty useful for a lot of things.
|
In response to Ter13
|
|
Ter13 wrote:
Also, one of the other major problems with particle effects and animate() is that objects' apparent rendering positions are not calculated based upon transform. This makes things like particle effects render incorrectly, or suddenly appear when you move and the particle's origin is now within your view. Wouldn't it be good to just have animate() work as expected? I don't really understand it much but I'd definitely want to rely on animate() to render properly and show to the right viewers. The only thing I noticed is that I can't use animate for effects that occur over an entire z level, it definitely would pop to existence in certain places and not show entirely in others. I don't know how hard it'd be to change that though. |
If there are issues with animate() not working intuitively, please post a separate bug report with a demo.
|
@Rotem: Basically, the way that BYOND currently handles view sending, is tiles/objects are obtained by checking for tiles within range of the client. Tiles are marked "interesting" if they are larger than the tile size of the world.
In order to make everything function reliably (and efficiently), Lummox/Tom would basically have to go in and implement a quadtree structure for tracking viewport rendering. When an object is changed visually (bounds, loc, pixel offsets, or transform), its visual_bounds would need to be calculated: (This is an incredibly non-optimal solution. It could be cleaned up quite a lot) var/w = icon.width/2 After you've calculated the bounding box for the object, crawl downwards through the quadtree until you find the last node in the chain that fully contains the object's visual bounding box. var/node = quadtree.topnode Of course, you'd want to set a minimum granularity such that the end of the chain isn't a single tile, but rather, probably a group of either 32x32 or 64x64 tiles. When constructing a view list for the client, you'd need to normalize the viewport edges of the client against the quadtree's minimum granularity, and grab all the nodes that are within the client's viewport's range. Then, you basically subscribe the client to the node's list of watchers. When a client starts watching the node, the node will send a message containing all of the objects within that node. When an update happens to a node, it's stored in a list of updates that have happened during that frame, and at the end of the frame, visual updates are sent to the clients watching the node. If a node doesn't have watchers, it simply doesn't track updates. This method would decrease network overhead by quite a bit and make the client-server interaction much smoother and easier to work with. Unfortunately, I don't think Tom and Lummox are much interested in doing this, as forcing it into an existing implementation can be incredibly problematic. |