Tales of Pirates [Unity]

I would choose the approach without backward compatibility with the original client, because in 2026 it is barely relevant anymore and would bring a huge amount of legacy baggage with it. In other words, we would prepare only Unity-friendly assets.

At the same time, modding could remain similar to the classic version. We could keep table-based data files, such as JSON, as well as textures, models, and effects in an open format—or package them into containers to improve read and write performance.

Unity is an excellent engine, and we should take full advantage of its capabilities instead of relying on outdated approaches inherited from the original game. However, this would require a significant amount of manual work.

For example, hitboxes are currently stored separately for each item worn by a character. Instead, we could attach them directly to the skeleton. This would make them accurate at all times, regardless of the equipped clothing, and would eliminate a well-known bug.

In my experiments, I also created a round-trip Blender–Unity–Blender model format. Yes, it is a custom format, but it makes it possible to load any model into a 3D editor at any time and, for example, create a new animation while keeping the rig consistently correct.

We could also use all existing clients and their resources as a foundation. This would allow us to collect every original game asset ever released in one place. However, this would require manual sorting because there are filename collisions.

In the future, this would also allow us to create universal weapons for all four races. For example, a staff could use a single model shared by all four races.

The dummy points that are currently embedded in LGO files could be moved into JSON files. Their positions and scale could then be configured directly in the client for each race. This would allow us to remove an enormous number of unnecessary duplicate weapon models from the client.

The same approach could be used when one model has multiple textures: we would simply create different variants based on the same model.

All of these changes make backward compatibility impossible, but I do not believe it is necessary anymore.
 
I love where this has gone. Honestly, I think I'm going to archive my bgfx client work for this. I asked some people in real life what they liked, and everyone who wasn't already familiar with ToP/PKO preferred the Unity client's modern look. Nostalgia gets me, but I see the upside of the migration to Unity. Could be a real way to get more people into the community too. It looks like Magic Sea has done something similar, and if more of us get behind it, more people might be interested in playing this game again.

Since milten asked for thoughts on the operational models, here's the view from the server-operator side. Strong vote for #2 (runtime loading of original formats), and I'd push back gently on dropping original-client compatibility. The reason a Unity client is exciting to people who actually run servers is precisely that it can point at an existing server and play. We add items, maps, and models constantly. With runtime loading, all of that content just works on day one. The moment the client requires converted assets (JSON tables, a new model format), every server needs a conversion pipeline in its content loop before its stuff exists in the new client, and the client stops being a drop-in choice for players.

That said, awezx211's ideas don't have to conflict with compatibility. Original formats as the floor, open formats as an opt-in override layer (which is basically milten's Tier-1 modding concept already): the client loads .lgo/.lab/etc. natively, and where a server ships a JSON/glTF override for the same ID, that wins. New projects get the clean pipeline, existing servers keep working, and things like skeleton-attached hitboxes or shared weapon models live in the override layer without breaking anyone. Compatibility and modernization as layers, not a fork in the road.

Two write-path landmines from building our own Blender round-trip tooling for these formats. These never bite when reading files for rendering, only when writing files the original engine must load (relevant to any editor/conversion tooling, including round-trip format work):

  1. The helper/dummy block in .lgo/.lmo is load-bearing and can't be regenerated from mesh data. We proved this the hard way: a round-tripped rigged model that was bit-identical in every render-driving field (zero vertex/normal drift, identical indices and skin weights, same FVF/declarations, original .lab kept) but with a rebuilt helper block still rendered wrong in the original client. Carry the original helper block through untouched. Reconstructing it from bounding data looks right and fails invisibly.
  2. Stale section sizes on version-upgrading re-saves. Re-save an older 0x1004 asset at 0x1005 and the anim block grows (+64 bytes per geom object) while the geom header keeps its stored anim_size, so the offsets desync and the file won't load. Recompute every section size from the bytes actually emitted.

And for completeness on the write side (imports that render fine can still export broken): the engine<->glTF basis change is exactly (x,y,z)->(x,z,y) with det = -1, so it also flips triangle winding. Invert both or exports come back inside-out.

We're working in this direction ourselves and are happy to contribute where we've already solved things, or where we solve them ahead of you. The UI is a good example: milten mentioned porting it is significant effort, and I already rebuilt the entire client UI in RmlUi (HTML/CSS-style markup and stylesheets), so there's a complete, working modern UI for this game to match 1:1. If you hit walls we've been through, reach out. From your recent PoC video you're still ahead.