Skip to content

Internationalization

AUTHOR: Seggan HAS CONTEXT: Seggan

Right... where do I even start...

Translation in Paper

The Paper server translates most things for us already, as they are translated on the server before being sent to the client. This includes chat messages, bossbars, and action bars. However, for some strange reason, this does not extend to item names and lore. That leaves us with two options: either we translate items on the server side (which is what we do now), or we send the client a resource pack with translations included. One of the implicit goals of Pylon is to avoid requiring resource packs, so we went with server-side translation.

Packet injection

Now for obvious reasons we cannot translate the item stacks themselves, as different people may use different languages and that would cause confusion. Instead, we inject a handler into the player's Nettey channel to intercept both incoming and outgoing packets.

The following outgoing packets are intercepted:

  • ClientboundContainerSetContentPacket: sent when opening an inventory, contains the items in the inventory
  • ClientboundContainerSetSlotPacket: sent when an item in an inventory changes, contains the new item
  • ClientboundSetCursorItemPacket: sent when the item on the cursor changes, contains the new item
  • ClientboundRecipeBookAddPacket: sent when recipes are added to the recipe book, contains the items of the recipes
  • ClientboundMerchantOffersPacket: sent when opening a villager trade GUI, contains the items in the trades
  • ClientboundPlaceGhostRecipePacket: sent when placing a ghost recipe in a crafting grid, contains the items in the recipe

When the packet is intercepted, we translate the item stack(s) in the packet, using the Paper translation API to translate the name and lore of the item stack. As these items are copies, we can freely modify them in-place without affecting the actual item stacks.

Unlike outgoing, only two incoming packets are intercepted: ServerboundSetCreativeModeSlotPacket and ServerboundContainerClickPacket. These packets are intercepted to un-translate the item stacks back to their original names and lore, so that when the server receives them, it can process them correctly. This is done by looking up the original item stack in the Pylon item registry