Well I had to fix this in just the stupid little RoH source I messed around with for years, since it used the s_damage code which doesn't cache even just attacking quickly by yourself could cause lag, not to mention when you used mass attack spells 1 player with about 10 icon operations(or less) could lag the game in single player when using s_damage.

I am now making my own game & fixed the lag in RoH by caching the icons instead and the game runs ten thousand times smoother & even hosting off my personal pc(although with fast internet speeds & a decent pc) the server is reported to run pretty fast with nobody noticing slow-downs/lags when 20 people are on & playing now.

Another game had JUST HAIR color transformations & they told theirs to cache all the colors because they were tired of slow-downs as well.

Whether your using a dedicated server or using your own pc at home I have had many people report these icon operations are killer, they just waste your cpu & take forever when their not being used sparingly(1 icon operation every 5 seconds at least) if you want no lag.
I guess the biggest problem with this is that icon operations can get complicated. Some things make sense to be done on the client, some things make sense to be done on the server. If you want to change the color of an icon or rotate it, that should be easily handled by the client. I'd imagine this as simply being a var of the atom. For example, you change the value of atom.opacity to 0.3 and the client draws the atom as being partially transparent.

I can see how complex icon operations could be more easily handled by the server. If you want to take two icons, color them differently, cut them in half and blend the halves together, then rotate it and change the color again, it would be difficult to pass all of these instructions to the client. This is almost a different kind of icon operation. When you rotate an icon you're not generating a "new icon" in the same sense, you're just rotating an existing one. These simple operations can be controlled by atom vars instead of icon operations.

I don't see this as being a way to offload calls to Turn and Blend to the client. They'll still be done on the server, but there will be new vars that allow the same effect to be done by the client.
Just a heads up: we're re-implementing and testing this so we'll see what kind of results we get this time. Lummox JR has put in some heuristics to determine when to compute on server vs. client. I also think we can avoid computation entirely in some cases by doing the operation in GDI (eg, rotating an icon prior to blitting) rather than as part of the icon data itself.
Holy f***-awesome, Batman!

Just for clarification, which icon functions will and will not be passed onto the client?
The dynamic DMI format basically uses a sequence of instruction codes, whose length varies depending on what they're actually being told to do. Once the instruction codes reach 256 bytes, the server figures it's better off handling things itself, and it does all the work up to that point and from there on out.

The longest opcode by far would have to be MapColors(), which uses either 50 or 82 bytes depending on whether you're using the full alpha format or not. Others, like insertion and extracting a named state from an icon, might be longer depending on the name of the state. The kinds of changes this is meant to help, like color swaps and simple blends, will see less work on the server as it offloads this to the clients, but intensive stuff like DmiFontsPlus operations will be done server-side for the most part.

Also as a side note, I managed to find a way to improve the speed of SwapColor() as well so whether that runs on the client or the server it'll have a boost.
Is there a way for developers to grab the length of the instruction codes? Otherwise it'll be a lot of guesswork for us to optimize our icon procedures in such a way where they'll be mostly offloaded to the client.
SilkWizard wrote:
Will the players need to upgrade to 483 as well for this to work correctly?

Yes. 483 servers will not allow older clients to connect due to the incompatible formats.

SuperAntx wrote:
Is there a way for developers to grab the length of the instruction codes? Otherwise it'll be a lot of guesswork for us to optimize our icon procedures in such a way where they'll be mostly offloaded to the client.

There's no real way to get that information, but I can share some of the basics:

- Actual function calls are 1 byte, including one to open the icon.
- Colors are 4 bytes plus a 1-byte opcode.
- Icons are the same except they contain an additional byte for the number of directions.
- Strings are stored as a 1-byte opcode, plus the string in null-terminated form (so length()+2).
- Most other numbers that are used as arguments to the functions are either 1 or 2 bytes; directions and simple flags always use 1, as does the frame # in the extraction operation. Turn() and MapColors() are among the few functions that use floating point though.

With that information you should be able to ballpark the length of any instructions. When blending or inserting, the other icon will be represented by a stack reference if possible (6 bytes), or otherwise its full instruction set. Icon operations work by pushing icons (and sometimes strings and colors) onto a stack, and popping stuff off the stack as needed. So this is a rough translation of how it works:

var/icon/I = new('smile.dmi', "happy")
I.Blend(rgb(20,0,0), ICON_ADD)


That translates roughly to:

- Open 'smile.dmi' and push to stack
- Push "happy" to stack
- Extract (pops "happy" and modifies icon on top of stack)
- Push #140000 to stack
- Blend (pops color from stack and uses opcode for operation type)

The blend operation has two different opcodes; one of them is used for the positional blend, and has 4 more bytes for the x and y positions.

I should also note that the icon_states() operation will force a limited evaluation of the icon, but it can skip most of the operations. GetPixel() however requires full evaluation, so if you use it you're going to be stuck with server-side work for that icon.
Keep in mind that our goal is that the improvements here pass the "eyeball test" in hosted games with a lot of icon operations (exacerbated by a lot of players). Hopefully you won't have to worry about the intrinsics and the system will just work better. Either way, please let us know what you see.
Would it be feasible to add logs of when icon operations are (not) offloaded to the client while games are running in DEBUG mode? It's just to be certain of what is and isn't taking advantage of this update.
I don't think it would be very feasible at this time. But basically, you can expect that very complex procedures like that done by DmiFontsPlus are pretty much always going to be done server-side. (In Incursion I did see an exception on the buttons at the start of the game, which use such a big font that they had relatively few operations per individual icon.) Like for example, in the recent forum thread about creating icons with various rotations, if you wanted an icon rotated in 5° increments you'd be looking at a load (6 bytes), turn (5 bytes IIRC), and insert (6 plus state length) repeated 72 times; that passes the 256 limit handily. But if you're just doing a few color swaps or blends you won't come anywhere near it.

A typical place this new functionality will show up is in generating character icons. Even if you're coloring in each piece of equipment and body part and layering it together, chances are you're probably not going to hit the limit unless you're doing a lot of that.

[edit]
To throw some numbers at you, in a typical character generation you'd start with 6 bytes for the load if you're not extracting a specific state. Any color blends will be 7 bytes. Blending another icon (without position) will be the cost of that icon plus 2 bytes. Any extraction (when you pare an icon down to just a single state, dir, frame, and/or movement) will be 6 bytes plus the length of the icon state (if any). Insertions are the cost of the inserted icon plus 10 bytes plus the length of the icon state (I forgot about delay earlier).

Since a typical character generation is only going to stick to color blends and icon blends, you can basically say you're starting with 6 bytes for the main icon, and then doing a color blend and overlay which gives you another 6+7+2 for each one. So you'd have to do that a lot to run into trouble. MapColors() is more costly since the simple format uses 12 floats and is 50 bytes (opcode + number of floats + floats), and the long alpha form uses 82.
If the text rendering library were to use separate objects for each letter, I would imagine that the instructions would be simple enough to handle on the client side.
Yota wrote:
If the text rendering library were to use separate objects for each letter, I would imagine that the instructions would be simple enough to handle on the client side.

Unfortunately this isn't the case. The old DmiFonts is relegated to using shifts and DmiFontsPlus can use positional blends (slightly cheaper in combination), but if every letter was represented by a cache entry for just the 6-byte load, a positional blend would still cost that plus 6 bytes, so that's 12 bytes per letter. That adds up a bit. But this is actually a good thing, because the client really isn't very smart about handling this stuff.

What I found in testing, which is how I settled on the 256-byte limit, was that the server really is a lot smarter about knowing what it needs to keep in memory and how to manipulate it cheaply than the client could ever reasonably be expected to. The server is the best place to do any complex work for that reason.

Where this upgrade is intended to make an improvement to performance is in the much more common garden-variety color changes and basic blends.
We've been running this on two of the NEStalgia servers for a couple hours now. The difference is very noticeable - icon procs that used to lag the entire server are now much improved.

I was spamming the character customization commands that are heavy on Blend and SwapColor and players barely noticed any slowdown. Prior to this update that would have made the server chug and hang for everyone.
Fantastic news. I think the improvements to SwapColor() would have made a decent difference on their own but all that saving and then transferring the modified icons was kinda pointless and now your .dyn.rsc file can be smaller. These are exactly the operations we hoped to speed up.
Page: 1 2 3