@paramat: Nope, still has an important bug, see description.
I don't know what the cause of the bug is. I'm guessing it's something in formatChatLine, but it's really hard to understand what that code is doing.
I just rewrote formatChatLine from scratch. Now it works and the code is much simpler.
Also, I removed the age field from chat messages and replaced it with a monotonic time_raw value that doesn't have to be constantly updated. I also switched the getTime helpers to 64-bit so that overflow won't be an issue.