Skip to content

Repository files navigation

PocketStrata(口袋地层)

在同一世界坐标保存建筑结构,并在「真实地形」与「口袋子世界」之间切换。支持单人存档与多人联机:进入者与旁观者可在同一片区域看到不同的方块布局。

版本:0.1
作者:Mornia-Cherry
依赖:ArknightsMod


功能概览

能力 说明
结构采集 手持「地形采集记录器」框选区域,保存为 .pstrata 文件
快速放置 F9 在玩家脚下应用当前选中的结构
子世界会话 在指定矩形区域内用口袋结构替换真实地形(服务端为权威)
多会话并存 服务端可同时开多个子世界,区域互不重叠,各有各的成员
多人视角 成员看到并能改口袋地形;其他人仍看到真实地形,也改不动那片区域
改动持久化 可修改的结构,改动存进本世界存档;只读结构关闭即还原
箱子与装置 箱子内容、招牌文本、TileEntity 一并采集与还原
自动还原 退出存档、世界写盘、成员全部离线时都会写回真实地形

快速开始

1. 采集并保存结构

  1. 制作或获取 地形采集记录器
  2. 手持记录器:
    • 左键拖拽:框选地形;
    • 右键:切换「与(增加选区)/ 非(减少选区)」模式。
  3. 在聊天栏执行:
/ps save <结构名称>

结构文件保存在:

Documents/My Games/Terraria/tModLoader/ModData/PocketStrata/Structures/

2. 选择结构并放置

/ps list              # 列出已保存结构
/ps select <名称>     # 设为 F9 使用的结构
/ps apply <名称>      # 等同于 select 后按 F9

在合适位置按 F9,会在脚下以玩家脚底为锚点放置结构(多人时由服务端分块同步)。

3. 关闭子世界

  • 再次按 F9(当前在子世界里时)请求关闭。
  • 或执行 /ps close

只有会话成员能关掉自己所在的子世界,别人关不了。


聊天命令 /ps

命令 作用
/ps save <名称> 将当前框选保存为 .pstrata
/ps list 列出结构库中的名称
/ps select <名称> 选中结构,供 F9 使用
/ps apply <名称> 选中并应用(同 F9)
/ps close 关闭自己所在的子世界
/ps readonly <名称> [on|off] 查看或设置结构是否只读
/ps reset <名称> 清除该结构在本世界里的改动,回到 .pstrata 原样
/ps clear 清空当前框选
/ps folder 在聊天中显示结构目录路径
/ps messages / /ps msg 开关屏幕提示(聊天回复不受影响)

完整流程:从零录一个结构并测试

模组不自带任何 .pstrata,第一次用必须自己录一个。目录在第一次用到时才自动创建。

单人流程(先在这里跑通)

  1. 进单人世界,用作弊工具给自己一个 地形采集记录器TerrainRecorderItem),或直接用 HERO's Mod / Cheat Sheet 搜「地形采集记录器」。
  2. 找一片有辨识度的地方(最好带箱子和招牌,好验证实体捕获),手持记录器:
    • 左键拖拽框选,松开即写入选区;
    • 右键在「与(增加)/ 非(减少)」之间切换;
    • 选区边界会有蓝色粒子,拖拽预览是黄色。
  3. /ps save 测试屋
    • 回复里会告诉你尺寸、选区格数、初始点(你脚下相对结构左上角的偏移)和文件路径。
    • 初始点决定以后按 F9 时结构相对你站的位置往哪放,所以存的时候站在你希望以后出现的那个位置
  4. 走到另一片空地,按 F9。结构会带飞入动画落在你脚下,聊天出现「子世界已生成」。
  5. 在里面挖两下、往箱子里塞个东西。
  6. 再按 F9 关闭 → 原地形带飞出动画还原。
  7. 再按 F9 开一次 → 上一步的改动应该还在(可修改结构的改动存进了世界存档)。

该验证什么

项目 怎么看
地形还原 关闭后原来的地形、墙、液体、电线、油漆都回来了
箱子 结构里的箱子能打开,内容和录制时一致;关闭后原地的箱子也回来了
招牌 文本还在
掉落抑制 结构出现和消失时不应该掉一地物品
只读 /ps readonly 测试屋 on 后,改动不再保存,每次都是原样
重置 /ps reset 测试屋 清掉本世界的改动
存档污染 关闭会话前直接「保存并退出」,重进世界那片地形应该是原样,不是口袋方块

多人流程

用两个客户端连同一个服务器(可以本机开 tModLoaderServer + 两个游戏实例,或主机模式 + 一个客户端)。

  1. 两个玩家都要有同一份 .pstrata 文件在各自的 ModData/PocketStrata/Structures/ 下 —— 结构是从客户端上传给服务端的,服务端本地没有文件。
  2. 玩家 A 按 F9 开启。聊天会显示「开始上传 xxx:N 块」→「上传完毕」→「子世界已生成」。
  3. 关键验证点
    • 玩家 B 站在同一片区域,应该看到原来的地形,完全看不到 A 的建筑;
    • 玩家 B 拿镐去敲那片区域,敲不动,而且一个物品都不应该掉(尤其不能掉出子世界建筑里的方块——那是能无限刷材料的漏洞);
    • 玩家 B 往那片区域扔炸弹,同样不应该炸出任何东西;
    • 反过来,玩家 A 在自己的子世界里挖矿应该正常掉落(这条一起验,别把成员的掉落也误伤了);
    • 玩家 B 打开大地图,那片区域不应该有蓝框(蓝框只给成员看);
    • 玩家 B 也按 F9 开另一个结构,如果位置和 A 的重叠,应该收到「和已有子世界 xxx 重叠了」的提示;错开位置则两个子世界并存,各看各的。
  4. 玩家 A 断线 → 服务端应自动收摊,那片地形还原。
  5. 让服务器跑到自动存档(或 /ps close 后手动存),检查 .wld 没被口袋方块污染。

常用命令速查

/ps save <名称>          # 把当前框选存成 .pstrata
/ps list                 # 列出所有结构,带 [只读] 标记
/ps select <名称>        # 设为 F9 要用的结构
/ps apply <名称>         # 选中并立刻应用
/ps close                # 关闭自己所在的子世界
/ps readonly <名称> on   # 锁成只读
/ps reset <名称>         # 清掉本世界的改动
/ps clear                # 清空框选
/ps folder               # 打开结构目录
/ps messages             # 开关屏幕提示(默认是关的)

提示默认是静默的,调试时先 /ps messages 打开,否则看不到上传进度和错误原因。

F9 可以在设置里改键(键位名「开关子世界」)。


结构的只读与可修改

.pstrata 文件里带一个只读标记(文件格式 v4):

  • 可修改(默认):玩家在子世界里做的改动(包括箱子内容),在会话关闭时写进当前世界的存档.twld),下次在同一世界开同一个结构会接着上次的样子。.pstrata 模板文件本身始终不变,所以同一个结构在不同世界里各改各的。
  • 只读:关闭时直接丢弃改动,每次都从模板重新生成。
/ps readonly 我的房子        # 查看当前状态
/ps readonly 我的房子 on     # 设为只读
/ps reset 我的房子           # 清掉本世界存的改动

/ps reset 只能由服主或单机玩家执行,因为改动存在服务端。


多人联机原理(简述)

  • 服务端在每个会话矩形内的 Main.tile 里放口袋结构,这是权威数据。多个会话并存,区域不允许重叠。
  • 成员客户端通过分块包收到口袋地形和真实地形备份,把口袋写进本地 Main.tile
  • 非成员的 Main.tile 模组一个字都不动。服务端两头堵:
    • SendSection:玩家首次加载该区段时,临时把真实地形换回去再发;
    • SendData:会话区内的瓦片更新对非成员直接丢弃。 之所以能丢,是因为会话期间那片区域的真实地形不会变,非成员手上那份一直是对的。
  • 非成员对会话区的挖掘/放置包会被 HijackGetData 丢掉,并立即回发一小片真实地形,把客户端已经做掉的本地预测打回来(否则那边会看到方块凭空消失)。
  • 光按包类型挡不全(客户端发的 TileSquare、炸弹爆炸都不走那几个包)。服务端没有 Main.myPlayerWorldGen.KillTile 也不带发起人,所以 PocketActor 在两处记下当前责任人:处理某客户端的包时(hook MessageBuffer.GetData)、以及某弹幕爆炸时(hook Projectile.Kill)。GlobalTile.CanKillTile / CanPlace 据此判定,CanDrop / KillTile 再兜一层——责任人不是该会话成员时一律不掉落,杜绝对着看不见的方块反复敲来刷材料。
  • 世界写盘(含服务器自动存档)期间,所有会话区会被临时换回真实地形,写完再放回口袋,避免口袋方块被存进 .wld
  • 箱子 / 招牌 / TileEntity 不在瓦片数据里,单独存一份清单跟着会话一起换。箱子内容靠原版的「点开时才向服务端要」机制同步,所以成员能正常开箱,非成员的开箱请求会被拦掉。

所有玩家需使用相同版本的本模组。


从源码构建

  1. 将本目录放入 tModLoader 的 ModSources 文件夹。
  2. 先关闭游戏内 tModLoader,或在游戏内禁用本模组后再编译(否则可能出现 TML003 文件占用错误)。
  3. 在项目目录执行:
dotnet build

或在 tModLoader 模组开发环境中直接 Build/Rebuild。


项目结构

PocketStrata/
├── Content/
│   ├── Commands/          # /ps
│   ├── IO/                # .pstrata 读写与结构库
│   ├── Items/             # 地形采集记录器
│   ├── Players/           # 框选、进入者视角 ModPlayer
│   └── Systems/           # 会话管理、分块网络、地形同步、箱子装置、过渡动画
├── Localization/          # 中/英本地化
├── PocketStrata.cs          # 网络包分发
└── README.md

常见问题

F9 后看不见建筑?(多人)

  • 只有开启会话的人是成员,其他人看不到也进不去(目前没有「邀请他人进入」的入口)。
  • 等待聊天出现「子世界已生成」提示;大结构要几秒才能传完。
  • 全员模组版本一致。

单人退出后地形被写进存档?

  • 模组在世界写盘期间会把会话区换回真实地形,服务器的定时自动存档也一样。

编译提示 TML003?

  • 关闭 Terraria/tModLoader 或禁用模组后重新 build。

许可与说明

本仓库为 tModLoader 模组源码。description.txt 为工坊简介;详细玩法以游戏内提示与上述命令为准。

若与 ArknightsMod 一同使用,请确保两个模组均已启用且版本兼容。

About

泰拉瑞亚模组:在同一坐标保存建筑结构,支持与多人「进入者看子世界、旁观者看真实地形」的口袋会话。

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages