news 2026/9/9 21:41:04

把家乡变成 Minecraft 世界:Arnis 现实城市生成工具实用指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
把家乡变成 Minecraft 世界:Arnis 现实城市生成工具实用指南

把家乡变成 Minecraft 世界:Arnis 现实城市生成工具实用指南

【免费下载链接】arnisGenerate any location from the real world in Minecraft with a high level of detail.项目地址: https://gitcode.com/GitHub_Trending/ar/arnis

Arnis 是一款开源工具,用真实的 OpenStreetMap 地理数据和海拔数据,把家乡、大城市甚至自然景观复刻到 Minecraft Java 版、基岩版和 Luanti(Minetest)里。本文追踪一份地理数据从经纬度到方块的完整旅程,讲清它内部怎么运作、哪些设计让"1:1 还原现实"成为可能。

先认识 Arnis:一份地理数据的旅行

一句话定位:Arnis 把现实世界"扫描"成一个可以走进去的体素城市。🌍

整个过程像寄一封跨次元的快递:

  1. 输入:你在地图上圈一个矩形范围(比如你的小区、一座老城),Arnis 向 OpenStreetMap 服务器要这个范围里的地图数据——哪些是建筑轮廓、哪些是道路、哪些是水域;同时下载真实海拔数据。
  2. 翻译坐标:地球是球面,用经纬度描述;Minecraft 世界是扁平网格,用 x/z 整数格子描述。这一步把每个经纬度点换算成游戏坐标,误差越小,建筑落点越准。
  3. 逐个要素加工:建筑轮廓被"挤"成有墙有窗的方块楼体,道路按等级生成不同宽度的路面,水域填成深浅不同的水体,树木从内置的树种库里挑合适的栽上。
  4. 写入世界:所有方块按 Minecraft 的存档格式(Java 版的 Anvil 区块结构、基岩版的 .mcworld 包或 Luanti 世界)逐格落盘。
  5. 输出:生成完直接把文件夹丢进.minecraft/saves,开游戏就能看到 1:1 比例的家乡。

下图就是 Arnis 生成的城市预览,密集的建筑群、绿地和路网都来自真实地图数据。

核心链路拆解

从地球一角到数字网格:坐标换算

coordinate_system 下分成两套坐标类:地理坐标(llpoint,经度+纬度的点)和笛卡尔坐标(xzpoint,游戏里的 x/z 平面点)。经纬度之间算距离要用球面三角,而游戏里的计算只需要简单的加减乘除,所以必须先把前者"展平"到后者。Arnis 走的是 Web Mercator 投影(也就是主流网络地图用的那种投影),因为它的网格切割方向和 OSM 瓦片一致,后续按瓦片取数据时可以直接对齐。

这套换算还支撑着一个实用功能:边界框工具。

界面上拖出的矩形,实时换算成min_lat,min_lng,max_lat,max_lng四个数——这正是命令行模式需要的参数。界面上的所见即所得,本质上就是这一层坐标换算在做双向翻译。

取数:一次圈选,三类数据

r(数据获取模块)负责所有网络请求。这里有个容易忽视的取舍:三种生成模式取的数据量差异极大。

  • geo-terrain(默认):OSM 要素 + 真实海拔,生成带地形的完整城市;
  • geo-only:只取 OSM,地面是平的,适合城市地形不重要的场景;
  • terrain-only:只取海拔,完全不碰 OSM,连公开服务器都不打扰。

海拔数据按瓦片分块下载并缓存到本地,因为同一区域反复生成(或调整参数重跑)时,重新拉一遍海拔纯属浪费。取 OSM 数据时程序还会带上带版本号的 User-Agent 标识自己,这是对公开服务的礼貌——大批量取数时,让服务器管理员知道流量来自哪个版本、哪个用户。

从地图标签到方块:要素加工流水线

OSM 数据本身只是标签:一条建筑轮廓线带height=24,一条路带highway=residential。真正的工作是把标签变成方块布局,这块逻辑集中在 element_processing,按要素类型拆成独立文件:buildings.rs 管楼房、highways.rs 管道路、water_areas.rs 管水域,还有桥梁、树木、历史建筑等二十多个子处理器。

几个关键手法:

  • 建筑:把二维轮廓沿高度方向"挤出"成楼体(extrusion,类似剪纸插起来),再根据屋顶标签决定平顶还是坡顶,墙面贴窗、贴门,避免"一整面灰墙"的塑料感;
  • 道路:按 highway 等级映射到不同宽度和路面材质,主干道自然比小巷宽;
  • 区域填充:像"建筑占住哪几格"这类判断由 floodfill(洪泛填充,从边界点出发逐格扩散标记内部)完成,配合位图缓存避免重复计算——因为一个城市的建筑可能上万栋,每栋都重新做区域判断会慢到不可接受。

插件化的拆分带来实际好处:想加新要素类型(比如新的公共设施),只需要新写一个处理器并注册,不用动建筑或道路的逻辑。

落盘:一套逻辑写三种存档格式

Minecraft Java 版存成 Anvil 格式的 region 文件,基岩版打成单个 .mcworld 压缩包,Luanti 又是第三种结构。如果三种格式各写一套生成逻辑,任何一处修改都要改三遍。所以 world_editor 用 common.rs 定义统一的"世界待修改"数据结构——上层只管"在 (x, y, z) 放一个方块",由 java.rs、bedrock.rs、luanti.rs 分别负责把它编码进各自的区块格式。

值得细看的设计决策

确定性随机数,保证分块计算不"穿帮"。生成大区域时,世界按区块分块并行处理,一栋跨区块边界的楼可能在不同区块里各被处理一次。如果随机数靠全局状态(比如墙的颜色、树的品种),同一栋楼两个区块里会抽到不同结果,拼起来就是半边红墙半边蓝墙。deterministic_rng.rs 的解法很干净:用 OSM 元素 ID 本身做随机种子,同一个元素无论被处理几遍、在哪个线程处理,抽到的"随机值"都相同。代价是几乎没有——一次哈希换来了并行分块下的结果一致性,这对"流式/分块"架构是必要条件而非优化项。

基岩版方块映射表,抹平两个版本的分歧。Java 版和基岩版对同一方块的命名、ID、数据值并不完全一致(比如玻璃、石砖的变体)。bedrock_block_map.rs 维护了一张"Java 方块 → 基岩方块"的映射表,让同一份生成逻辑在两个版本里产出视觉一致的世界。没有这张表,要么为基岩版重写生成逻辑,要么玩家打开世界看到一片"缺失材质"。

内存与并行的工程取舍。大城市生成时同时活跃的方块数据量轻松达到数 GB,主程序用 mimalloc 替代系统分配器,注释里写明了原因:并行分块处理产生大量小对象分配,mimalloc 在这种"高并发小块"负载下表现更好;线程池则限制在 90% CPU 占用,留出余量保证系统流畅。这类选择用户感知不到,但直接决定了"普通硬件能不能跑动一座城市"。

上手与延展

图形界面:下载 release 包运行,用矩形工具在地图上圈选区域,选目标世界格式,点 Start Generation 即可。

可调参数包括世界缩放比例(1:1 或放大)、出生点位置、是否生成建筑内部房间等。

命令行:适合自动化和服务器场景,核心就两个参数——输出目录和范围框。

cargo run --release -- --output-dir="~/.minecraft/saves/worldname" --bbox="min_lat,min_lng,max_lat,max_lng"

想只要地形加--mode terrain-only,要平地面加--mode geo-only;加--bedrock则输出基岩版世界。

能往哪走:代码库里已经能看到延伸方向的痕迹——models_3d/wikidata_3d_models.json表明项目正在用 Wikidata 数据把现实地标(比如雕像、纪念碑)以精细 3D 模型的形式摆进世界,而不是只给个简化方块体;assets/tree-packs/下按大洲组织的数千棵树种模型,说明植被还原也在走"真实物种 → 体素模型"的路线。对贡献者来说,最自然的切入点也是这两处:给某类要素补一个处理器,或者往树库里添模型。作者已用同一套核心逻辑推出了浏览器端生成服务(无需安装、支持更大地图),这也印证了"取数—加工—落盘"严格分层后,换一套运行载体不需要重做核心管线。

【免费下载链接】arnisGenerate any location from the real world in Minecraft with a high level of detail.项目地址: https://gitcode.com/GitHub_Trending/ar/arnis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 21:40:14

如何为 uBOLite 将过滤列表转换为声明式 ruleset?

如何为 uBOLite 将过滤列表转换为声明式 ruleset? 【免费下载链接】uBlock uBlock Origin - An efficient blocker for Chromium and Firefox. Fast and lean. 项目地址: https://gitcode.com/GitHub_Trending/ub/uBlock uBlock Origin 仓库中包含一个 MV3 分…

作者头像 李华
网站建设 2026/9/9 21:39:21

ZLMediaKit 传输协议选型:TCP 与 UDP 快速选择指南

ZLMediaKit 传输协议选型:TCP 与 UDP 快速选择指南 【免费下载链接】ZLMediaKit WebRTC/RTSP/RTMP/HTTP/HLS/HTTP-FLV/WebSocket-FLV/HTTP-TS/HTTP-fMP4/WebSocket-TS/WebSocket-fMP4/GB28181/SRT/STUN/TURN server and client framework based on C11 项目地址: …

作者头像 李华
网站建设 2026/9/9 21:38:51

ERTEC硬件过滤器:PROFINET实时通信的帧过滤与中断优化实战

刚入行PROFINET开发的那阵子,我踩过一个大跟头。设备在实验室跑得好好的,一挂到现场总线上就开始偶发丢包,CPU中断占用高得吓人,示波器抓出来的时序跟狗啃过一样。后来查了几天才发现,问题根本不在栈写得好不好&#x…

作者头像 李华
网站建设 2026/9/9 21:38:31

STM32电子密码锁Proteus仿真:矩阵键盘、EEPROM与状态机实战解析

简介:基于STM32设计的电子密码锁仿真与源码工程,面向嵌入式系统学习者、电子设计竞赛选手以及相关课程设计/毕业设计学生,用于掌握单片机密码锁系统的完整设计流程。资源共277个文件,以C语言源码(70个.c)和…

作者头像 李华
网站建设 2026/9/9 21:38:02

西门子S7-200 SMART恒压供水系统:PID整定与泵组调度实战解析

简介:西门子S7-200 SMART恒压供水项目程序包,面向电气工程师、自动化调试人员及水务相关从业者,主要解决多泵恒压供水系统的电机投切、频率调节与压力稳定控制问题。系统采用一台变频器控制一台水泵,共四台主泵、一台辅泵&#xf…

作者头像 李华