ID:151781
 
We've all screwed around with the rgb() proc once in a while, and sometimes we find a pretty good use for it. The only problem with it is that no matter how to try to do it, its always going to be CPU-intensive; therefore underused and less appreciated.

So, whats the point of using rgb() if its just going to drain sources and cause considerable lag?

This brings me to a post a made a while ago when talking about dynamically changing the color of text box windows in game. The best solution was to draw the sprites before hand in separate colors, limiting the selection of colors as opposed to allowing the user full control over the color itself. Regardless of how CPU intensive it is, it won't sway me from using it; however, I feel as though it will only subtract from the players value of the game when they see even a half-of-a-second lag.

Therefore, I pose a question: Is it possible to create the same effect without using as many resources and without having to draw the sprites separately, or are we doomed to the existence of an inefficient procedure?
Are you sure it's not how you're using it that is inefficient? As far as I can tell, all rgb() does is return the color in HTML hex form.
In response to Slurm
Then do me a favor and create yourself a little demo.

In that demo, make a box on the screen that goes from, I dunno, perhaps the 3 tiles high, 12 tiles wide. Then, try to change the color of all of them using the rgb() proc to anything and see if it doesn't take more than a couple ticks.

It may seem like no big deal, by try to imagine a game designed to do that constantly, like any of the FF games for example.
In response to ArcaneDragonX
ArcaneDragonX wrote:
Then do me a favor and create yourself a little demo.

In that demo, make a box on the screen that goes from, I dunno, perhaps the 3 tiles high, 12 tiles wide. Then, try to change the color of all of them using the rgb() proc to anything and see if it doesn't take more than a couple ticks.

It may seem like no big deal, by try to imagine a game designed to do that constantly, like any of the FF games for example.

ADX, Slurm is right. rgb() just returns a hex value.
Icon arithmetic is the subject you're trying to get at (I think). It often involves rgb(), but isn't isolated to that:
icon += rgb( 255, 0, 0 )

It's the '+=' that's causing the processing delay you're seeing.

Edit: as a general solution, if the colors aren't being picked on the fly (such as by the player), you can do the arithmetic when the player won't mind the delay, such as loading or any pause in the action.
As Slurm said, rgb() is not CPU-intensive at all, and it's also highly optional. What you're thinking of are the icon operations themselves. Small such operations shouldn't pose a problem, though if problems arise, provided you've already tried to handle things as efficiently as possible, the answer to prevent such relatively heavy operations from bogging down your world is indeed to precompute them, cache their results and reuse them. With icons, including the commonly used changes as premade in the icon would indeed be ideal. The only difference between doing that and generating them at runtime is that you don't go through the slow operation of recreating them again each time, and instead of players downloading them in the middle of the game after they're created (which is undesirable and often disrupts gameplay) they download them with all of the other resources when they initially login into the game. This should be somewhat needless to say, but you don't have to pre-generate the icons by hand. You can easily make a temporary verb to do the needed icon operations and then insert them into a DMI file which is saved; essentially the basic workings hasn't changed - the icons were still computed in game. But the difference is that they have only been generated once at a certain time, and the results were saved to be reused for all eternity later, without needing to be computed again.
Of course, you gave no useful info whatsoever on the extent of the icon operations you're doing at all, so we can only talk about it generally. You didn't specify what you find to cause slowdowns; I doubt it's allowing a player to choose his hair color at character creation or something of that extent.
ArcaneDragonX wrote:
The only problem with it is that no matter how to try to do it, its always going to be CPU-intensive; therefore underused and less appreciated.

So, whats the point of using rgb() if its just going to drain sources and cause considerable lag?

rgb() neither drains resources or causes lag. I can call it 100,000 times (code sample follows) and it will only take 0-1 ticks to complete; it takes me 2 ticks to complete 1,000,000 calls to it.
client/verb/Test1()
set name = "rgb() * 100,000"
var/t1 = world.timeofday
var/hex

for(var/i in 1 to 100000)
hex = rgb(128, 128, 128)

src << "[world.timeofday-t1] tick(s) to resolve [hex] 100,000 times."

client/verb/Test2()
set name = "rgb() * 1,000,000"
var/t1 = world.timeofday
var/hex
for(var/i in 1 to 1000000)
hex = rgb(128, 128, 128)

src << "[world.timeofday-t1] tick(s) to resolve [hex] 1,000,000 times."


As has been said, the delay you're seeing is caused from icon arithmetic. There is a reason for this: you change some icon data, and then each client has to receive dynamic resource information regarding the changes. If you have multiple operations this can be even worse; you send out the entire generated icon for every dynamic change you apply.
ArcaneDragonX wrote:
(...)dynamically changing the color of text box windows in game. The best solution was to draw the sprites before hand in separate colors, limiting the selection of colors as opposed to allowing the user full control over the color itself.

Since I suppose you meant using client.screen, as opposed to real windows (as in interface elements), you could do something like that without using rgb() at all.

turf
tt
icon = 'tt.dmi'

t1
icon_state = "1"
t2
icon_state = "2"
t3
icon_state = "3"

mob
verb
Swamp()
var/col = input("Please select a colour", "Choice") as color
var/icon/i = new('tt.dmi')
i.SwapColor("#0000ffff", col)
for(var/turf/tt/s)
s.icon = i


Just a simple example and not as resource intense as you describe it.
Though, I confess, I don't know how optimized BYOND handles this procedure, or in other terms, if the icon is sent as "change palette", or as new icon.
In response to Schnitzelnagler
Schnitzelnagler wrote:
Since I suppose you meant using client.screen, as opposed to real windows (as in interface elements),

And I'd add on that note that if he's experiencing major slowdowns, other than not handling the icon modification efficiently it could also be handling screen badly, as every single little change causes the entire list to be updated and so you should attempt to cause as few separate updates as possible, which there are a couple of ways to go about doing.
I made some quick testing code that can modify (by icon arithmetic) 120 identical icons (note distinction from icon files) in a tick or so, so while icon handling is slower than other things it's still certainly manageable.

Though, I confess, I don't know how optimized BYOND handles this procedure, or in other terms, if the icon is sent as "change palette", or as new icon.

There is limited client-side processing in BYOND (which is mainly the internal stuff like working with verbs and as such), and I don't think there is any at all in regard to icon modification. The modified icon is treated like a new resource file and sent in whole if/when applied.