There were two places where we were doing unaligned reads: one when
computing the hash for the material identifier, and one when parsing
the chunk in ShaderReplacer.
We also had a potential overflow since civetweb does not add a trailing
null to incoming WebSockets messages.
We're only caching textures (not render targets yet), and we're
evicting cache entries older than 30 allocations.
This should cut down on texture allocation / gl calls.
The cache should get in a stable state very quickly (less than half
second).