The messages are probably of varying lengths in all languages.
You probably hope you don't have to waste a lot of bytes.
You want a flexible system that will permit revising any message in any language. And you probably don't want to recalculate new lookup tables after each revision.
This method assumes that you assign an ID number to each message. And an ID number to each language.
This method assumes your machine is fast enough that there will be no perceptible delay as searches through memory.
Messages can be stored in any order, any mix of languages.
Each message begins with a '00' null byte. Then two identification bytes.
The first ID byte is the language ID number (example, '01' for English, '02' for French, etc.). You can have up to 255 languages.
The second ID byte is your message ID number. You can have up to 255 messages. If you have more messages then you'll need to use two bytes which will allow 65,535 messages.
Then for instance to display message #5 in language #3, you'll start searching through memory for the first occurence of any byte containing '00'.
Then peek the next byte of memory. If it doesn't contain '03', it isn't in language #3. Resume searching for the next null byte.
When you find a '03', peek the following byte to see if it contains '05'. Etc.
When you find '05' start reading bytes, building the message. Continue until you find a byte containing '00'. Display the message.
If speed bogs down with this method, then you'll have to create shortcuts in the form of (a) lookup tables, (b) putting all messages with the same ID number in a contiguous block of memory, or (c) using a contiguous block of memory for all messages in the same language, etc.