Sorted it - I was trying to be a little too smart.
RTF::Writer formats the strings it gets sent, and assumes they are plain text. I was trying to do the inline formatting before giving it to the writer, so it was reformatting - hence the mangled strings!
By sending it plain old \n instead of \line or \par, it behaves.