Skip to content

Commit 228df35

Browse files
committed
docs(readme): update architecture comparison tables
1 parent 0270233 commit 228df35

2 files changed

Lines changed: 109 additions & 8 deletions

File tree

README.md

Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434

3535
- [Overview](#overview)
3636
- [Core Capabilities](#core-capabilities)
37+
- [Multi-World Architecture Comparison](#architecture-tradeoffs)
3738
- [Version Matrix](#version-matrix)
38-
- [Architecture](#architecture)
39+
- [Runtime Architecture](#architecture)
3940
- [Quick Start](#quick-start)
4041
- [Launcher Reference](#launcher-reference)
4142
- [Publisher Reference](#publisher-reference)
@@ -58,7 +59,7 @@ Compared with approaches that push this coordination outside process boundaries,
5859
This shared listener-and-coordination model reduces the extra overhead and complexity introduced by cross-process relays, making cross-world interaction, data interchange, and unified operations easier while still leaving enough routing control to define the default join target and take over later world-switch flows.
5960

6061
From the player's side, this still behaves like a normal Terraria entry point: clients connect to one shared listener port, and `UnifiedServerCoordinator` routes each connection to the selected world inside the same process. If you push this model further, you can build more gameplay-driven setups: fully connected multi-instance world clusters, elastic worlds that load or unload region-sized shards on demand, or private worlds tuned per player for logic and resource budgets.
61-
These are reachable directions, even though the launcher does not currently ship them as default out-of-the-box features, and heavier implementations like these may stay out of the launcher core itself; you can still expect usable example plugins to land under `plugins/` over time.
62+
These are reachable directions, even though the launcher does not currently ship them as default out-of-the-box features, you can still expect usable example plugins to land under `plugins/` over time.
6263

6364
---
6465

@@ -79,6 +80,55 @@ These are reachable directions, even though the launcher does not currently ship
7980

8081
---
8182

83+
<a id="architecture-tradeoffs"></a>
84+
## ⚖️ Multi-World Architecture Comparison
85+
86+
> Here, `proxy-based` broadly refers to the common family of designs built around a front proxy, multiple independent backend server processes, packet-level relays or rewriting, and optional shared storage or control-plane components.
87+
88+
<details>
89+
<summary><strong>Deployment and Lifecycle</strong></summary>
90+
91+
| Dimension | UnifierTSL (single-process unified coordination) | Proxy-based (front proxy + multiple backend processes) | Stronger Fit |
92+
|:--|:--|:--|:--|
93+
| Failure isolation | Worlds share one host process; isolation between contexts exists at the thread/runtime-context level | Process-level isolation; one backend crash usually does not directly take down other backends or the proxy itself | Proxy-based |
94+
| Instance-level restart | World contexts can be started and stopped freely | A single backend can be restarted, replaced, or moved while the front entry point stays up | Depends on the operational goal |
95+
| Plugin hot reload | The runtime provides standard support; whether a plugin can hot reload depends on the plugin's own design, and players are usually unaffected | Backend plugins can be reloaded cleanly by restarting only the target backend instance, though that may require moving players to a temporary backend | Depends on the operational goal |
96+
| Horizontal elasticity | The core design targets multi-world coordination inside one host; instances can be created freely, but they still share one process resource pool | Naturally suited to cross-machine, cross-container, or cross-device scale-out | Proxy-based |
97+
| Existing plugin ecosystem reuse | Requires adaptation to the Unifier runtime model | Directly uses the existing plugin ecosystem | Proxy-based |
98+
99+
</details>
100+
101+
<details>
102+
<summary><strong>Runtime Coordination and Transfer</strong></summary>
103+
104+
| Dimension | UnifierTSL (single-process unified coordination) | Proxy-based (front proxy + multiple backend processes) | Stronger Fit |
105+
|:--|:--|:--|:--|
106+
| World customizability | World contexts are fully customizable and can be changed dynamically at runtime | Depends on the backend implementation; in practice, most setups are relatively static after startup | UnifierTSL |
107+
| Server-side consistency | World existence, routing targets, and connection ownership are resolved directly inside one runtime, so the consistency surface is narrower | Depends on cross-process topology, registration, shared storage, or an external control plane, so the race surface is wider | UnifierTSL |
108+
| State awareness and switch orchestration | One coordinator can see source world, target world, and player connection state together, so fallback and recovery logic can be centralized | Target readiness, transfer failures, disconnect recovery, and rollback may require cross-process coordination | UnifierTSL |
109+
| Data transfer and entity migration | Temporary state, plugin-attached data, and runtime objects can be transferred or coordinated directly inside one runtime | State often has to be serialized, protocolized, or moved through shared databases or custom packets first | UnifierTSL |
110+
| Connection-state maintenance | One listener keeps ownership of the client connection throughout world switches | The proxy must maintain both client-side and backend-side connections and recover from failures on either side | UnifierTSL |
111+
| Cross-world plugin interoperability | Feels more like “one plugin working across many `ServerContext` instances,” with direct reuse of in-process events and APIs | Feels more like distributed-systems work, usually requiring message protocols, shared storage, or sync layers first | UnifierTSL |
112+
113+
</details>
114+
115+
<details>
116+
<summary><strong>Operations and System Shape</strong></summary>
117+
118+
| Dimension | UnifierTSL (single-process unified coordination) | Proxy-based (front proxy + multiple backend processes) | Stronger Fit |
119+
|:--|:--|:--|:--|
120+
| Unified management cost | Entry point, world lifecycle, default join policy, and config application all live on one coordination plane | Management is usually split across the proxy, backend instances, and external orchestration pieces | UnifierTSL |
121+
| Monitoring and observability | Logs, status bars, event flow, and per-world runtime metrics aggregate naturally | Observability is often split across proxy, backend, and external control layers, so correlation costs more | UnifierTSL |
122+
| Debugging and incident handling | A single process gives you a more continuous timeline for debugging, log correlation, and reproduction | Failures can be spread across proxy, backend, shared storage, and deployment orchestration layers | UnifierTSL |
123+
| Network and serialization overhead | Critical coordination paths can stay in-process and avoid extra hops or auxiliary protocols | Player transfers and extended state propagation may introduce extra packets plus related interception strategies, or rely on side channels | UnifierTSL |
124+
| Single-node capability density | A single host can already cover routing, coordination, linkage, plugin interoperability, and unified operations | A single node is more of a routing shell, with heavier behavior often shifted toward backends or external systems | UnifierTSL |
125+
126+
</details>
127+
128+
It is important to note that UnifierTSL and proxy-based topologies are not mutually exclusive. Because UnifierTSL already organizes many worlds behind a single external listener, it can still sit behind a higher-level gateway or proxy as a stronger single-node backend. In the end, the better choice depends on your needs: proxy-based stacks have a higher ceiling for cross-device, cross-process scaling and isolation, so if you prefer elastic multi-machine deployment with basic cross-server features, proxy-based is likely the better fit. By contrast, UnifierTSL has more natural advantages in single-node multi-world consistency, migration, and coordination. If you want to build a more structured and interactive multi-world group, UnifierTSL is likely the more interesting option to try today.
129+
130+
---
131+
82132
<a id="version-matrix"></a>
83133
## 📊 Version Matrix
84134

@@ -88,7 +138,7 @@ The baseline values below come straight from project files and restored package
88138
| Component | Version | Source |
89139
|:--|:--|:--|
90140
| Target framework | `.NET 9.0` | `src/UnifierTSL/*.csproj` |
91-
| Terraria | `1.4.5.6` | restored `OTAPI.dll` resolved via `src/UnifierTSL/obj/project.assets.json` (assembly file version) |
141+
| Terraria | `1.4.5.6` | `OTAPI.dll` from the OTAPI USP package referenced by this project |
92142
| OTAPI USP | `1.1.0-pre-release-upstream.30` | `src/UnifierTSL/UnifierTSL.csproj` |
93143

94144
<details>
@@ -117,7 +167,7 @@ Additional dependency baselines:
117167
---
118168

119169
<a id="architecture"></a>
120-
## 🏗 Architecture
170+
## 🏗 Runtime Architecture
121171

122172
<p align="center">
123173
<img src="./docs/assets/readme/arch-flow.svg" alt="Architecture flow" width="100%">

docs/README.zh-cn.md

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434

3535
- [概览](#overview)
3636
- [核心能力](#core-capabilities)
37+
- [多世界架构横向比对](#architecture-tradeoffs)
3738
- [版本矩阵](#version-matrix)
38-
- [架构](#architecture)
39+
- [运行架构](#architecture)
3940
- [快速开始](#quick-start)
4041
- [启动器参考](#launcher-reference)
4142
- [Publisher 参考](#publisher-reference)
@@ -58,7 +59,7 @@ UnifierTSL 把 [OTAPI Unified Server Process](https://github.com/CedaryCat/OTAPI
5859
这种共享监听入口与协调平面的方式,减少了跨进程中转带来的额外开销与复杂度,既方便建立跨世界联动、数据互通和统一运维,也保留了足够的路由控制空间,用于定义默认入服目标并接管后续的世界切换流程。
5960

6061
从玩家视角看,它依然像一个普通的 Terraria 服务器入口:客户端只需要连到同一个监听端口,随后由 `UnifiedServerCoordinator` 在同一进程内把连接路由到目标世界;如果继续把这套模型往前推,你可以做出更偏玩法的形态:完全互通的多实例世界集群、按需加载/卸载区域分片的弹性世界,或为单个玩家定制逻辑和资源预算的私人世界。
61-
这些是可达方向,尽管启动器目前并未直接提供这些开箱即用的默认能力;而这类较重实现也未必会放进启动器核心本体,但你仍可以期待后续在 `plugins/` 下逐步补上的可用示例插件。
62+
这些是可达方向,尽管启动器目前并未直接提供这些开箱即用的默认能力,但你仍可以期待后续在 `plugins/` 下逐步补上的可用示例插件。
6263

6364
---
6465

@@ -79,6 +80,56 @@ UnifierTSL 把 [OTAPI Unified Server Process](https://github.com/CedaryCat/OTAPI
7980

8081
---
8182

83+
<a id="architecture-tradeoffs"></a>
84+
## ⚖️ 多世界架构横向比对
85+
86+
> 这里的 `proxy-based` 泛指“前置代理 + 多个后端独立服务器进程 + 协议级转发/改写 + 可选共享存储或控制面”的常见可能形态。
87+
88+
<details>
89+
<summary><strong>部署与生命周期</strong></summary>
90+
91+
| 维度 | UnifierTSL(同进程统一协调) | proxy-based(前置代理 + 多后端进程) | 更占优 |
92+
|:--|:--|:--|:--|
93+
| 错误域隔离 | 多世界共享宿主进程;上下文之间有线程级隔离 | 进程级隔离,单个后端崩溃通常不会直接拖垮其他后端或代理本身 | proxy-based |
94+
| 实例级重启 | 支持世界上下文自由启停 | 可单独重启、替换、迁移某个后端实例,外层入口可继续存活 | 视具体需求而定 |
95+
| 插件热重载 | 运行时提供标准支持,由插件自身设计决定是否可热重载,通常玩家端无感 | 可单独重启后端实例完成后端插件干净重载,可能需要迁移玩家到临时后端 | 视具体需求而定 |
96+
| 水平弹性部署 | 核心设计目标为单宿主内多世界协调,可任意创建实例,但共享同一进程资源 | 天然适合跨设备、跨容器、跨主机扩展 | proxy-based |
97+
| 现有插件生态复用 | 需要按 Unifier 运行时模型适配 | 直接使用当前插件生态 | proxy-based |
98+
99+
</details>
100+
101+
<details>
102+
<summary><strong>运行时协同与迁移</strong></summary>
103+
104+
| 维度 | UnifierTSL(同进程统一协调) | proxy-based(前置代理 + 多后端进程) | 更占优 |
105+
|:--|:--|:--|:--|
106+
| 世界定制化 | 完全可定制并可在运行中动态更改的世界上下文 | 视具体后端实现而定,通常启动后不再变动 | UnifierTSL |
107+
| 服务器一致性 | 世界存在性、路由目标、连接归属都在同一运行时里直接判定,一致性面更窄 | 依赖跨进程拓扑、注册信息、共享存储或控制面,竞态面更宽 | UnifierTSL |
108+
| 感知与切换编排 | 同一协调器可同时感知来源世界、目标世界与玩家连接状态,回退与兜底可集中处理 | 可能需要跨进程协同处理目标就绪、切换失败、掉线恢复和回滚 | UnifierTSL |
109+
| 数据传输与实体迁移 | 临时状态、插件附加数据、运行时对象可以在统一运行时内直接转移或协调 | 往往必须先序列化、协议化,或借共享数据库 / 自定义数据包搬运 | UnifierTSL |
110+
| 连接状态维护 | 单一监听入口持续持有客户端连接,切世界时不需要把连接所有权交给其他进程 | 代理需同时维护前后端连接,并处理任一侧掉线、重连与状态复原 | UnifierTSL |
111+
| 插件跨服互操作 | 更像“同一插件面对多个 `ServerContext`”,跨服协作可以直接复用进程内事件与 API | 更像分布式系统开发,通常要先定义消息协议、共享存储或同步层 | UnifierTSL |
112+
113+
</details>
114+
115+
116+
<details>
117+
<summary><strong>运维与系统形态</strong></summary>
118+
119+
| 维度 | UnifierTSL(同进程统一协调) | proxy-based(前置代理 + 多后端进程) | 更占优 |
120+
|:--|:--|:--|:--|
121+
| 统一管理成本 | 入口、世界生命周期、默认入服策略、配置应用都集中在同一协调平面 | 管理面通常分散在代理、后端实例和外部编排组件之间 | UnifierTSL |
122+
| 状态监测与观测 | 日志、状态栏、事件流、各世界运行指标天然可聚合 | 观测往往分散在代理层、后端层和外部控制面,拼接成本较高 | UnifierTSL |
123+
| 调试与故障定位 | 单进程时间线更连续,调试会话、日志关联和问题复现更集中 | 故障可能散落在代理、后端、共享存储和运维编排多个层面 | UnifierTSL |
124+
| 网络与序列化开销 | 关键协调路径可留在进程内,避免额外 hop 和附加协议 | 玩家迁移与扩展状态传播可能引入额外数据包和相关拦截策略、或通过旁路信道实现 | UnifierTSL |
125+
| 单节点能力密度 | 单机内即可覆盖路由、协调、联动、插件互通与统一运维 | 单节点更像路由壳层,复杂能力常转移到后端或外部系统 | UnifierTSL |
126+
127+
</details>
128+
129+
必须说明的是,UnifierTSL 与 proxy-based 并不互斥。由于 UnifierTSL 已经把多世界组织成单一对外监听入口,它完全可以作为一个更强的“单节点后端”继续挂到更外层的 gateway / proxy 前面。总之,具体的选择取决于你的需求,proxy-based 在跨设备、跨进程的伸缩与隔离问题上具备更高上限,如果你倾向于跨设备弹性部署并体验基础跨服功能,proxy-based会是你的最优选择。相比之下 UnifierTSL 可能在单节点内部的多世界一致性、迁移和协同能力方面具备天然优势,如果你想设计更具组织性和交互能力的多世界群组,也许现在就可以尝试UnifierTSL来搭建你的多世界服务器。
130+
131+
---
132+
82133
<a id="version-matrix"></a>
83134
## 📊 版本矩阵
84135

@@ -88,7 +139,7 @@ UnifierTSL 把 [OTAPI Unified Server Process](https://github.com/CedaryCat/OTAPI
88139
| 组件 | 版本 | 来源 |
89140
|:--|:--|:--|
90141
| 目标框架 | `.NET 9.0` | `src/UnifierTSL/*.csproj` |
91-
| Terraria | `1.4.5.6` | 通过 `src/UnifierTSL/obj/project.assets.json` 定位已还原的 `OTAPI.dll`(程序集文件版本) |
142+
| Terraria | `1.4.5.6` | 项目引用的 OTAPI.USP 包中的 `OTAPI.dll` |
92143
| OTAPI USP | `1.1.0-pre-release-upstream.30` | `src/UnifierTSL/UnifierTSL.csproj` |
93144

94145
<details>
@@ -117,7 +168,7 @@ UnifierTSL 把 [OTAPI Unified Server Process](https://github.com/CedaryCat/OTAPI
117168
---
118169

119170
<a id="architecture"></a>
120-
## 🏗 架构
171+
## 🏗 运行架构
121172

122173
<p align="center">
123174
<img src="./assets/readme/arch-flow.svg" alt="Architecture flow" width="100%">

0 commit comments

Comments
 (0)