TL;DR: You can't display hundreds of animationParts without suffering a performance penalty. I've been working on a mod that allows independent control of pixels on a tiny, modular screen. I have made an "LCD" object that I can place on the background. Here is a gif to explain what I mean: These characters aren't sprites; this display is made up of a matrix of 8x8 independent pixel sprites as animationParts inside an object. I found a bitmap font online and wrote code to convert it to pixels. Right now, it just cycles through the 128 characters of the font, but I could make it display anything I wanted as each pixel is individually addressable. Here is a bigger example: This gif shows 10 LCDs (5 across, 2 high) cycling through the font. With a GTX 560 on an i7 2600k, I get around 17 FPS here. With 8 LCDs, I get 50 FPS. I have tried different scriptDeltas and optimizations to setAnimationState, but the framerate doesn't change, so I can assume that the rendering speed is purely a result of the game rendering an extra 512 or 640 animationParts (depending on # of LCD objects) every frame. I imagine this framerate varies based on the beefiness of the machine it is running on. As you can see, it is working. However, I have put the project on hold and ceased my efforts toward getting it to work on a larger scale because its performance is so poor. In case you were curious about the details, here is some of my methodology. This is what the animationParts segment of my lcd.object file looks like: Code: "animationParts" : { "screen" : "lcd.png", "pixel_0_0" : "pixels.png", "pixel_0_1" : "pixels.png", "pixel_0_2" : "pixels.png", "pixel_0_3" : "pixels.png", "pixel_0_4" : "pixels.png", "pixel_0_5" : "pixels.png", "pixel_0_6" : "pixels.png", "pixel_0_7" : "pixels.png", ...and so on, (64 total) lcd.animation has a bunch of these in "animatedParts": Code: "pixel_0_0" : { "default" : "off", "states" : { "on" : { "frames" : 1 }, "off" : { "frames" : 1 } } }, "pixel_0_1" : { "default" : "off", "states" : { "on" : { "frames" : 1 }, "off" : { "frames" : 1 } } }, "pixel_0_2" : { "default" : "off", "states" : { "on" : { "frames" : 1 }, "off" : { "frames" : 1 } } }, ...and so on (64 total again) and these in "parts": "pixel_0_0" : { "properties" : { "offset" : [0.000, 0.875], "centered" : false, "zLevel" : 1 }, "partStates" : { "pixel_0_0" : { "on" : { "properties" : { "image" : "pixels.png:green" } }, "off" : { "properties" : { "image" : "pixels.png:black" } } } } }, "pixel_0_1" : { "properties" : { "offset" : [0.000, 0.750], "centered" : false, "zLevel" : 1 }, "partStates" : { "pixel_0_1" : { "on" : { "properties" : { "image" : "pixels.png:green" } }, "off" : { "properties" : { "image" : "pixels.png:black" } } } } }, "pixel_0_2" : { "properties" : { "offset" : [0.000, 0.625], "centered" : false, "zLevel" : 1 }, "partStates" : { "pixel_0_2" : { "on" : { "properties" : { "image" : "pixels.png:green" } }, "off" : { "properties" : { "image" : "pixels.png:black" } } } } }, ...and so on. Guess how many? pixels.png is just a small graphic with a bunch of single pixels of various colors. If the mod were more performant, I might expand the mod to allow different colors of pixels. Right now, there's just green and black. Some excerpts from my lcd.lua. I use a lot of temp variables where I could compact the code, but I code long-form so I can test stuff along the way since debugging is hard in Starbound. Code: in init: myfont = {} fontdata = {} loadFontData() -- loads hex strings into a table for i,j in ipairs(fontdata) do -- this loads the hex strings into a table of binary strings, ("000101101" etc) local mycharset = {} for k, l in pairs(j) do local decnumber = tonumber(l, 16) -- converts font hex data to decimal local binary = basen(decnumber, 2) -- and then to a zero-padded binary string (took me a while to get this right!) table.insert(mycharset, binary) end local tempchar = table.concat(mycharset,"") table.insert(myfont, tempchar) end main runs cyclefont() once every scriptDelta: function cyclefont() if fontcount == 0 or fontcount == nil or fontcount == 128 then -- belt and suspenders! fontcount = 64 -- start at the common glyphs else fontcount = fontcount + 1 end display(myfont[fontcount]) end function display(character) -- character is a 64-character string of 0s and 1s for i=0,7 do for j=0,7 do local position = i*8 + j + 1 setpixel(j,i,binToOnOff(string.sub(character, position, position))) end end end function setpixel(xpixel, ypixel, pixelstate) if entity.animationState("pixel_".. xpixel .. "_" .. ypixel) ~= pixelstate then entity.setAnimationState("pixel_".. xpixel .. "_" .. ypixel, pixelstate) end end function loadFontData() fontdata = { -- characters of a bitmap font in hex format -- slightly more compact than 64-character binary strings; could be better, but it's what I found. { "00", "00", "00", "00", "00", "00", "00", "00" }, { "00", "3E", "41", "55", "41", "55", "49", "3E" }, { "00", "3E", "7F", "6B", "7F", "6B", "77", "3E" }, ...and so on. Right now, my opinion is that a pixel-based display using animationParts is just not practically feasible with the current state of Starbound's rendering engine. I will not release or work further on this mod until a way is found to improve performance. In my mind, only 8 usable characters (a 32x16 pixel display, essentially) at a good framerate even on a beefy machine just isn't performant enough to be practical, since most people will probably want more than just a few characters. It's only useful if it's practical at scale for the majority of hardware that can run Starbound comfortably, especially with multiplayer in mind. I figured this might happen, so I ain't even mad. It was a fun experiment and I enjoyed trying to push the envelope and see what the engine is capable of. Perhaps further down the road, the game will optimize animationParts and objects, and improve rendering on items that do not change between frames, or provide an alternate method of rendering arbitrary pixels. I would welcome any comments or suggestions for improving performance in this thread. Or, alternate rendering methods. Edit: Minor rewrite for clarity, and to add some comments in the code.
I decided to start working on a replacement that uses a single sprite per character instead of pixels. It's going to be much simpler than the other mod, and may provide some graphing/graphical capability.
Progress... 32 8x8 pixel sprite objects, each with 128 states (One for each character in the font.) No FPS slowdown. This is the Commodore 64 font, btw, hence the weird symbols. And it's backwards because we can't control the orientation of animated wired objects.