Source-checkedMaps & scenarios

EasyTeleport

by s6652289 · for Valheim

[AI-generated] Vanilla-styled world-map buttons: teleport back to your bed, or click anywhere on the map to teleport there. Hold Ctrl to drag the buttons anywhere; position is saved. Safe landing: no burying, no fall damage, water is fine. Client-only.

527Downloads
47d agoLast updated
BepInExLoaders
ThunderstoreSource

About EasyTeleport

From Thunderstore

[AI-generated] Vanilla-styled world-map buttons: teleport back to your bed, or click anywhere on the map to teleport there. Hold Ctrl to drag the buttons anywhere; position is saved. Safe landing: no burying, no fall damage, water is fine. Client-only.

EasyTeleport

大地图上的传送按钮。 打开地图(M),画面左上角出现两个按钮 —— 外观默认与游戏原生控件同化(运行时继承原版面板底图),不会显得像外挂的贴纸。

| 按钮 | 做什么 | | --- | --- | | 传送回床 | 传送到你记录过的床(在床上睡过觉设下的出生点)。 | | 任意传送 | 按一下 → 按钮变绿进入待选 → 再点地图上任意位置,就传送到那里。
再按一次按钮可取消。 |

> 挪位置:按住 Ctrl 用左键拖拽按钮组,可以放到画面任意位置,松手自动保存。 > 按住 Ctrl 时按钮文字会变成淡黄色,表示"现在可以拖"。

传送落地是安全的:陆地自动落到地面上方、点水面会浮在水上游泳、永远不会摔死。 传送在任何状态下都能用 —— 游泳、奔跑、跳跃、在船上、在水里都行。

> AI 生成声明:本模组由 AI 智能体(WorkBuddy)在用户的明确需求与逐项验收下编写; > 需求描述、交互设计与发布决定均由用户主导。


用法

传送回床

  1. 先在床边上按 E 睡一觉(这一步会在角色档案里记下出生点;不睡就点按钮会提示"还没有记录过床")。
  2. 按 M 打开大地图 → 右下角点 「传送回床」 → 黑屏淡入淡出 → 人已经在床边。

任意传送(地图上点哪去哪)

  1. 按 M 打开大地图。
  2. 点 「任意传送」 —— 按钮变成绿色并显示「取消 · 点地图选点」,同时左上角弹一条提示。
  3. 在地图上点任意位置 → 直接传送过去。
  • 点偏了?再点一次地图就行(待选状态会保留到你成功传送或主动取消)。
  • 不想传了?再点一次按钮取消,或者按 M 关掉地图(也会自动取消)。

> ⚠️ 游戏对传送有 2 秒冷却(原版传送门同款)。刚传送完立刻再传会被拒绝, > 屏幕上会提示"传送被游戏拒绝 —— 通常是因为刚传送过"。此时待选状态不会丢,等一两秒直接再点地图即可。


落点是怎么保证安全的

这一块没有自己写地形算法 —— 而是利用了原版 Player.UpdateTeleport 里本就有的一套落地校正流程, 再喂给它一个"在什么地形上都成立"的高度值。所有结论都来自对 assembly_valheim.dll 的反汇编。

原版的流程(Player.UpdateTeleport,distantTeleport = true 时)

①  player.position = 我们给的 (x, Y, z)          ← 这里 Y 是我们唯一能控制的
②  等 ZNetScene.IsAreaReady(target)              ← 远处传送就是在这里等区域加载
③  if (ZoneSystem.FindFloor(target, out floor))  ← Raycast(target + up×1, down, 1000 m)
        return;                                  ← ★ 命中就结束,玩家高度 = 我们给的 Y(不再校正)
④  else(没命中)
        player.y = ZoneSystem.GetSolidHeight(target) + 0.5
                                                 ← Raycast(target + up×1000, down, 2000 m)

同时,在搬运玩家的那一刻原版会执行 Character.m_maxAirAltitude = transform.position.y; 摔落伤害 = 当前高度 − 历史最高滞空高度,所以传送落地时该差值恒为 0 ⇒ 不会摔伤。

我们取的 Y = ZoneSystem.c_WaterLevel

ZoneSystem.c_WaterLevel 是一个 public const,从 DLL 的 Constant 表里读出来是 30.0f(Valheim 海平面)。 取这个值,两条分支在地形上的表现是:

| 地形 | ③ FindFloor | 最终落点 | | --- | --- | --- | | 陆地(地面高于水面) | 射线从水面上方往下打够不到地面 → 未命中 | 走 ④ → 精确落到地面 +0.5 米 | | 海洋 / 湖泊(水底低于水面) | 射线命中水底 → 命中 | 高度保持水面 → 玩家浮在水面游泳 |

离线场景矩阵验证(scripts/verify_landing.py,12 个场景)全部通过:

高山(Deep North 峰)   地面 420.0 → GetSolidHeight 校正 → 落点 420.5  OK 落在地面 +0.5 米
山地                    地面 180.0 → GetSolidHeight 校正 → 落点 180.5  OK 落在地面 +0.5 米
平原 / 草原             地面  50.0 → GetSolidHeight 校正 → 落点  50.5  OK 落在地面 +0.5 米
略高于水面的海岸         地面  32.5 → GetSolidHeight 校正 → 落点  33.0  OK 落在地面 +0.5 米
刚好在水面              地面  30.0 → FindFloor 命中      → 落点  30.0  OK
浅滩(水下 5 米)        地面  25.0 → FindFloor 命中      → 落点  30.0  OK 落在水面(可游泳)
沼泽低地(水下 12 米)    地面  18.0 → FindFloor 命中      → 落点  30.0  OK 落在水面(可游泳)
浅湖底(水下 25 米)     地面   5.0 → FindFloor 命中      → 落点  30.0  OK 落在水面(可游泳)
深海海床                地面 -55.0 → FindFloor 命中      → 落点  30.0  OK 落在水面(可游泳)
最深海床                地面 -95.0 → FindFloor 命中      → 落点  30.0  OK 落在水面(可游泳)
世界最高峰(极端假设)    地面 900.0 → GetSolidHeight 校正 → 落点 900.5  OK 落在地面 +0.5 米
超出校正范围的极端高      地面1100.0 → 两条都失败          → 落点1030.0  FAIL(Valheim 无此地形)

⚠️ 这也解释了为什么 UseDistantTeleport 必须保持 true: 只有远距离传送模式才会在 FindFloor 未命中时执行第 ④ 步校正。 把它关掉,跨半张地图传送就可能"人到了但地面还没来",或者停在未校正的高度上。


位置与外观

位置:按住 Ctrl 拖拽就行

按住 Ctrl + 左键拖动按钮组 → 放到画面任意位置 → 松手自动保存到 easyteleport.client.only.cfg 的 LeftAnchor / TopAnchor,不必手动改配置。

  • 按住 Ctrl 时按钮文字变淡黄,表示"现在可以拖"。
  • 拖拽跟手:从按钮组的哪一点起拖,那一点就一直跟着鼠标(不会跳到鼠标中心)。
  • 拖到屏幕外面会被夹在边界内,不会把按钮甩丢。
  • 拖拽期间、以及松手后 0.25 秒内按钮功能被抑制 —— 不会"想挪位置却把自己传走了"。
  • 不想要这个功能就把 AllowDrag 设为 false。

坐标用比例锚点(画面宽的 LeftAnchor、高的 TopAnchor),默认 0.084 / 0.392 = 1920×1080 下大约 (162, 423)。用比例而不是像素边距,是为了换分辨率时位置不会跑偏。

外观:继承游戏原生 UI

UseGameStyle = true(默认)时,模组会在运行时从大地图已有的控件里翻一个"面板/按钮底图" sprite 过来复用:

| 优先级 | 来源 | | --- | --- | | ① | 名字里带 button / panel / background / _bg / frame 的 Image | | ② | 有九宫格边界(Sprite.border != 0)的 Image —— 这种才是可拉伸的面板底图 | | ③ | 任意带图的 Image | | ④ | 都没有 → 退回纯色半透明深灰 |

拿到之后就按九宫格(Image.Type.Sliced)铺满按钮,所以圆角、渐变、描边都跟原版控件一致。 文字用米白色 + 1 像素黑描边,和原版 UI 的文字处理方式一致。

⚠️ 开着 Verbose 可以在日志里看到底图具体取自哪个控件(按钮底图取自 … sprite=… 九宫格=True)。 万一某次更新后取到的图不合适(比如拿到一个小图标铺开变形),把 UseGameStyle 改成 false 即可退回干净的纯色底 —— 这时按钮的长相由 ArmedColor 等配置控制。

为什么中文字体不能跟着游戏走

游戏内置字体 AveriaSansLibre 不含 CJK 字形,用它画中文会是一排方块。 所以字体默认走系统字体(微软雅黑),并从系统字体清单里按名字找。 观感上和原版 UI 已经很接近(都是无衬线体),但确实不是同一个字体 —— 这是中文环境下的必然取舍。


配置

BepInEx/config/easyteleport.client.only.cfg

| 分区 | 键 | 默认 | 说明 | | --- | --- | --- | --- | | 1 - General | Enabled | true | 总开关 | | 2 - Buttons | BackToBedText | 传送回床 | 按钮文字 | | | AnywhereText | 任意传送 | 按钮平时显示的文字 | | | ArmedText | 取消 · 点地图选点 | 待选状态显示的文字 | | | ArmedColor | 深绿 | 待选状态下按钮的绿色调(UseGameStyle = false 时作为底色) | | | UseGameStyle | true | 按钮外观继承游戏原生 UI 底图(见下节) | | | AllowDrag | true | 允许按住 Ctrl 拖拽调整位置 | | | LeftAnchor | 0.084 | 按钮组左上角的横向比例位置(0=最左,1=最右)· 拖拽会自动写入 | | | TopAnchor | 0.392 | 按钮组左上角的纵向比例位置(0=最上,1=最下)· 拖拽会自动写入 | | | ButtonWidth / ButtonHeight | 190 / 40 | 按钮尺寸(像素) | | | Spacing | 6 | 两按钮间距 | | | FontSize | 16 | 字号 | | | FontName | Microsoft YaHei UI | 字体(见下) | | 3 - Teleport | CloseMapOnTeleport | true | 传送后自动关掉大地图(回到小地图) | | | UseDistantTeleport | true | 远距离传送 —— 落地安全的前提,别关 | | | ShowMessages | true | 屏幕左上角提示 | | 4 - Debug | Verbose | false | 详细日志 |

关于字体:游戏内置字体(AveriaSansLibre)不含中文字形,直接画中文会变方块, 所以默认走系统字体(微软雅黑)。查找顺序: 配置里的名字 → 一组常见中文字体 → 游戏内置字体 → 已加载的任意字体。 想让按钮跟游戏 UI 完全统一(但只能显示英文),把 FontName 改成 AveriaSansLibre, 同时把按钮文字改成英文即可。

⚠️ 改完配置必须重启游戏(BepInEx 只在插件 Awake 里读一次)。 装了 BepInEx.ConfigurationManager 的话可以按 F1 直接改,那种是即时生效的。


兼容性

  • 纯客户端:无 Jotunn、无 ServerSync、无 NetworkCompatibilityAttribute(= NotEnforced)。
  • 联机:主机和其他玩家都不需要装;没装的人完全不受影响。

本模组只调用游戏自己的接口(Player.TeleportTo),不改任何主机权威数据。

  • 与地图类模组(如 BetterMap)不冲突 —— 按钮挂在游戏自己的大地图根节点下,

只占屏幕右下角一块;位置撞了改 MarginBottom / MarginRight 即可。

  • 传送门附近也可以用,本模组与本机已装的 QuickTeleport 无交互。

实现要点(全部来自 IL 实证,2026-09-18)

床的坐标从哪来

Read the full description on Thunderstore →

Highlights

From source data

Loaders

Runs on BepInEx.

Footprint

Rated a light load on a server.

Last update

Its author last shipped an update 47d ago.

EasyTeleport on Nxeon

From our catalogue
One-click install
Supported on Nxeon Valheim servers, for BepInEx servers. We download it from Thunderstore, place it, and restart the server.
Server type needed
BepInEx
Server load
light
Smallest plan we suggest
Valheim — 4 GB (4 GB RAM). This follows our own load rating above, not a benchmark.
Latest build
1.3.0, released 2026-09-18

Game versions by loader

LoaderGame versionsNewest
BepInEx

From 2 recorded builds of EasyTeleport.

Recent builds

BuildReleasedGame versionsLoaders
1.3.02026-09-18n/aBepInEx
1.2.02026-09-18n/aBepInEx

Dependencies

Declared by the newest build that lists any. Required ones are installed with it on one-click installs.

Run EasyTeleport on a Valheim server

Pick a server or deploy a new one above; it is installed in one click.

What kind of mod it is

From the catalog
Listed on Thunderstore as “Content”

Maps & scenarios

Custom maps, arenas and scenarios to play on.

Compatibility

Game
Valheim
Loaders
BepInEx
Requires
One-click install needs a BepInEx server.

Verified at the source

  • ✓ThunderstoreOfficial listing, checked 2026-10-01Open ↗
  • ✓Authors6652289, as published on Thunderstore
  • ✓LicenseNot published by the sourceFree

EasyTeleport, answered

Generated from the mod’s own source data.

Which loaders does it support?

BepInEx.

Is it free?

Yes. EasyTeleport is free to download from Thunderstore.

How do I add it to my Nxeon server?

Use “Add to a server” on this page, or open NxLabs from your dashboard. We install it, restart your server and switch it on.

NxLabs

Run EasyTeleport on a Valheim server.

Deploy in about a minute from $9.99 a month, then add EasyTeleport in one click.