Yeah, I ended up reimplementing them from the host source, and then trying with UTF16, didn’t seem to help, which is why I think it’s either the storage layer itself doing something odd or probably more likely the code I’m using to create a linefeed-delimited string array I can store in a single slot. Perhaps something odd about that interacts with the .split and .join methods?
I had hoped I wouldn’t be able to break it, though, because it’s a managed string and I’m not trying to modify individual bytes.
To be clear, though I did test with certain high-bit letters known to cause corruption in some circumstances, the case in which I found it involved regular English text.
To demonstrate it here is a test case and responses:
create roomscript test=export function onActivate(): void {
Room.listen()
Store.setString('test', 'Á Í Ï Ð Ý 🙃')
}
// Required because AS doesn't support closures yet
function reduceList(acc: string, cur: string, index: i32, self: Array<string>) : string {
return acc += '\n' + index.toString() + ': ' + cur
}
export function onRoomEvent(addr: string, ev: string): void {
const FORM_FEED = String.fromCodePoint(0xA)
let eventType = Event.getType(ev)
if ('ooc' != eventType) return
let ooc = JSON.parse<Event.OOC>(ev)
let msg = ooc.msg.split(' ', 3)
let test = Store.getString('test')
if (test) Room.describe('Retrieved from store: ' + test)
if (3 == msg.length && 'add' == msg[1]) {
// Because split() stops after the last selected group
let noise = ooc.msg.slice(ooc.msg.indexOf('add') + 4)
Room.describe('To be concat: ' + noise)
if (test) {
test += FORM_FEED + noise
} else { test = noise }
Room.describe('To store: ' + test)
Store.setString('test', test)
}
if (test) {
let split = test.split(FORM_FEED)
let list = ''
let join = split.reduce<string>(reduceList, list)
Room.describe('Split and reduced string: ' + join)
}
}
Created script “test” for room “test”.
set roomscript test : active = yes
Successfully updated room script “test”.
ooc test
⌈Retrieved from store: Á Í Ï Ð Ý ⌋
⌈Split and reduced string:
0: Á Í Ï Ð Ý ⌋
ooc noises add A small shamrock-leafed plant unfolds a set of pink star-shaped blooms.
⌈Retrieved from store: Á Í Ï Ð Ý ⌋
⌈To be concat: A small shamrock-leafed plant unfolds a set of pink star-shaped blooms.⌋
⌈To store: Á Í Ï Ð Ý
A small shamrock-leafed plant unfolds a set of pink star-shaped blooms.⌋
⌈Split and reduced string:
0: Á Í Ï Ð Ý
1: A small shamrock-leafed plant unfolds a set of pink star-shaped blooms.⌋
ooc test
⌈Retrieved from store: Á Í Ï Ð Ý
A small shamrock-leafed plant unfolds a set of pink star-shaped blooL⌋
⌈Split and reduced string:
0: Á Í Ï Ð Ý
1: A small shamrock-leafed plant unfolds a set of pink star-shaped blooL⌋
If I put const FORM_FEED = String.fromCodePoint(0xA)
at global scope the output ended:
1: A small shamrock-leafed plant unfolds a set of pink star-shaped blool
Perhaps the copy to/from store does not account in some way for the eight-byte header, i.e. it allocates or copies the size of the ArrayBuffer (rtSize) when it should consider rtSize + 8 including the header?