Today I enhanced the Sprite class to store a temporary, rotated/zoomed version of their image, as I was thinking about on Day 38. This temporary image is regenerated whenever the sprite's rotation/size change beyond a certain threshold, compared to the rotation/size depicted in the temporary image. The result is a significant boost in performance compared to before, especially in the case of many, mostly-stationary sprites. And the code actually got slightly cleaner as a result of this optimization, albeit slightly more complex (as one would expect when adding a new feature).
All this goes on behind the scenes, so developers don't even have to think about it (but if they do want to think about it, they can adjust the threshold for regenerating the image. The default threshold will cause the image to be regenerated if the rotation changes by 0.03 radians (~2 degrees), or if the size changes by 0.1 (that's multiples of the original size, e.g. a change from 3x to 3.1x size).
So, that's all well and good, but it's really just thought-practice for making the background image rotate/zoom when the camera does. Right now, the background stays static even as the objects in the scene change, which is somewhat disconcerting, and a big potential surprise for developers.
My approach for this is going to be mostly the same as it was for sprites: store a temporary rotated/zoomed version of the background. I'm anticipating room for optimization later, because backgrounds can be rather large (and thus extra slow to rotozoom), and the entire background may not be visible at once. Rotating a 1600x1200 background image in real time out of the question, but if only 640x480 of that would show on the screen, the whole background doesn't need to be rotated, just the part that you'd see.
But, I don't think that particular optimization will be in 3.0.0; instead, I'll hide behind an interface so I can sneak it in later without breaking compatibility.
Speaking of which, don't be surprised if I "clamp down" the interfaces for certain classes. In the past, Rubygame classes have been rather lax about interfaces, letting developers play fast and loose with its innards. ("Attr_accessors all around! Huzzah!"). The problem there, as I hinted, is that any changes to those innards would break compatibility.
So, the moral of the story is: keep your nose clean and your interface separate from your implementation.
See you ruby cowboy.