Firstly, I've been inspired by all the singleton debates raging on this forum to desingletonise my system, as in nearly every case they weren't needed. I've got a few things that need global access and a lot of things that need only a single one to exist, but nothing that needs both.
Secondly, I've upgraded the sprites with a bit more functionality; sprites can now be put into groups and manipulated as a unit. I've made a new object type called a "sprig", short for sprite group, except it's a bit more fundamental than that. Sprites themselves are defined in terms of the sprig class, and I'm envisaging the entire game will consist of a series of "sprig trees"; groups clustered within groups.
While in essence this change is pretty simple, it did require a complete restructure of the internals of the sprite system and several attempts at the proper way to define the relationship between sprigs and sprites (having the graphics module own the memory of both of them makes things a bit tricky), but I think it's working now.
The basic idea is that sprites (or sprigs) can now specify their position relative to a parent sprig. If the parent changes location, so does all of its children. This will make it simpler to implement many features, such as cameras (just put all the game sprites as children), text boxes, windows and any other game elements made from many sprites.
This simple test shows a bunch of rotating disc sprites decreasing in size, with each one in the chain defined in the frame of reference of the previous. Since every sprite is rotating, the result is a spiralling effect, with the discs at the end moving along at a fair speed.
Now I've got the basics done, I can integrate these improvements into the text module and start working towards the GUI system.