☰
Fantasy Map Generator v1.72.1 深度解析:城镇年度温度图表(Burg Temperature Graph)与动态数据导入(Dynamic Import)
2026/10/4 1:59:12 网站建设 项目流程
  • 前端
  • 图形学
  • 3D渲染

【免费下载链接】Fantasy-Map-Generator

Web application generating interactive and highly customizable maps

项目地址:https://gitcode.com/gh_mirrors/fa/Fantasy-Map-Generator
点击查看免费下载

本篇文章围绕 Azgaar's Fantasy Map Generator(下称 FMG)v1.72.1 版本的两项核心更新展开:一是基于机器学习气候模型的全新城镇年度温度图表,可查询任意城镇在一年中任意一天的平均温度(含白天与夜晚);二是应用架构层面的动态数据导入改造,让样式预设等数据按需加载。读完本文,你将掌握温度估算模型的数据流与计算原理、图表的交互方式,以及动态导入在 控制器注册表 与 样式预设模块 中的落地实现,并能按仓库提供的 本地运行指南 在本地复现这套环境。

一、版本更新概览

v1.72.1 是一次兼顾"功能纵深"与"架构演进"的发布:

更新项说明版本归属(据 Changelog)
Burg 温度图表为所有城镇提供详细的年度温度信息,以折线图渲染v1.72
动态数据导入样式预设等资源按需加载,每个预设为独立 JSON 文件v1.72.1
本地运行限制源码级本地使用需启动本地 Web 服务器v1.72.1
新增 Cyberpunk 样式预设基于社区用户地图风格的赛博朋克预设v1.72.1

其中温度图表功能由社区开发者Kerravitarr实现,官方作者负责重构与 UI 修复。整个更新记录可参见 docs/wiki/Changelog.md。

二、Burg 温度图表:从真实气候数据到任意城镇的全年温度

2.1 功能目标:任何城镇、任何一天、白天或夜晚的温度

此前 FMG 的每个格子和城镇只有年平均温度这一单一数值。v1.72.1 之后,你可以得到任意城镇在一年中任意一天的平均温度、白天温度和夜间温度——这对世界观构建(story-building)、农耕设定、旅行叙事等场景都非常实用。

其核心思路是:用机器学习分析真实世界约 1000 个城市的气候数据,得到一组插值常量,再把这些常量套用到 FMG 生成的城镇温度与纬度上,从而把单一年均温度"展开"成完整的年度温度曲线。

2.2 如何打开温度图表

在城镇编辑器中,选中任意城镇后,点击温度数值旁的图表图标(带data-tip="Show temperature graph for the burg"的icon-chart-area按钮),即可弹出标题为Average temperature in <城镇名>的对话框,展示该城镇的全年温度曲线。入口与调用链如下:

  • UI 按钮定义与事件绑定:burg-editor.ts、burg-editor.ts
  • 点击后经showTemperatureGraph()调用Controllers.TemperatureGraph.open(id):burg-editor.ts
  • 图表实现主体:temperature-graph.ts

2.3 模型原理:三层神经网络的温度插值

图表背后的温度展开逻辑完整地写在 temperature-graph.ts 中,可以还原出清晰的数学模型。

输入特征(2 维):城镇纬度与降水。其中纬度由城镇屏幕坐标反算:

const lat = options.map.geography.coordinates.latN - (b.y / options.map.graph.height) * options.map.geography.coordinates.latT;

输入归一化:将纬度与年均降水映射到约 [-1, 1] 区间:

const In1 = [(Math.abs(lat) - 26.950680212887473) / 48.378128506956, (prec - 12.229929140832644) / 29.94402033696607];

网络结构:三层全连接前馈网络(weights数组),每层输出经sigmoid激活(1 / (1 + Math.exp(-x)))后作为下一层输入:

  • 第 1 层:2 → 10(10 个权重向量,各含 2 个系数)
  • 第 2 层:10 → 6(6 个权重向量,各含 10 个系数)
  • 第 3 层:6 → 3(3 个权重向量,各含 6 个系数),输出 3 个统计量

输出参数(3 维,再经线性映射还原为物理含义):

// 全年平均温度的离散度(标准差) const yearSig = lstOut[0] * 62.9466411977018 + 0.28613807855649165; // 全年最高温与最低温之差的标准差(受 yearSig 约束) const yearDelTmpSig = lstOut[1] * 13.541688670361175 + 0.1414213562373084 > yearSig ? yearSig : lstOut[1] * 13.541688670361175 + 0.1414213562373084; // 全年最高温与最低温之差的期望值 const yearDelTmpMu = lstOut[2] * 15.266666666666667 + 0.6416666666666663;

年温度范围:以城镇年均温度(来自grid.cells.temp[pack.cells.g[b.cell]])为基准,向两侧展开:

const delT = yearDelTmpMu / 2 + (0.5 * yearDelTmpSig) / 2; const minT = burgTemp - Math.max(yearSig + delT, 15); const maxT = burgTemp + (burgTemp - minT);

月度曲线生成:对 12 个月份采样余弦波形(北半球反转相位,即lat > 0时取负),得到每月的平均温度与昼夜温差:

const rate = index / 11; // 0 → 一月, 1 → 十二月 let formTmp = Math.cos(rate * 2 * Math.PI) / 2; if (lat > 0) formTmp = -formTmp; // 北半球:一月最冷 const tempAverage = formTmp * yearSig + burgTemp; // 月均温 const tempDelta = yearDelTmpMu / 2 + (formTmp * yearDelTmpSig) / 2; // 昼夜温差

由此得到三条曲线:月均温(tempMean)、夜间温度(tempAverage - tempDelta)、白天温度(tempAverage + tempDelta)。

2.4 图表渲染与交互细节

图表使用 D3.js 绘制(源码引用d3的scaleTime、scaleLinear、line().curve(curveBasis)、axisBottom/axisLeft等),关键呈现要素包括:

  • 三条曲线:橙色 = 平均温度(Mean)、蓝色 = 夜间温度(Night,即低温端)、红色 = 白天温度(Day,即高温端),曲线下方带颜色图例;
  • 坐标轴:X 轴按月份标注(timeFormat("%B"),即 January 至 December),Y 轴默认 5 个刻度;
  • 0 度参考线:当温度范围跨越 0°C 时自动绘制灰色参考线;
  • 悬停提示:鼠标悬停任意曲线时,按指针位置反算温度与月份,弹出形如Average day temperature in June: 21°C的提示,见 temperature-graph.ts;
  • 尺寸自适应:图表宽度取Math.max(window.innerWidth / 2, 520),高度固定 300。

温度单位换算:Y 轴与提示中的温度并非固定摄氏温度,而是通过convertTemperature()按用户设置的温标实时换算(见 unitUtils.ts)。该工具函数支持 8 种温标:°C、°F、K、°R、°De、°N、°Ré、°Rø,并有对应的单测覆盖 unitUtils.test.ts。温度显示遵循options.map.units.temperature.unit配置,可在单位编辑器中切换。

2.5 架构意义与未来扩展

该模型的一大特点是灵活可扩展。作者在更新说明中明确指出两条演进路径:

  1. 降水建模:用同样的机器学习方法处理降水数据,即可回答"这个月是雨季吗?"之类的问题;
  2. 真实世界气候对标:为 FMG 生成的每个城镇找到真实世界的气候对应城市,并直接输出这些详细的气候数据。

从实现看,temperature-graph.ts 将模型常量、网络推断、图表绘制封装在单个控制器内,未来替换或叠加新的气候模型时,改动面非常小。

三、动态数据导入:按需加载与本地服务器

3.1 动机:为什么用户必须加载全部数据?

v1.72.1 之前,作者一直希望在离线、纯静态(无需服务器)的场景下运行 FMG,因此大量数据(样式预设、纹理、地图等)被提前打包进应用,用户哪怕只用到其中一小部分,也得加载全部资源。动态导入技术本身并不复杂,真正复杂的是在"不开服务器、双击 index.html 即用"的旧式约束下做按需加载。

最终作者决定:放开"必须本地服务器"的限制,换来简单可靠的动态数据导入。代价是源码级本地使用需要运行一个本地 Web 服务器。

3.2 本地运行方案

仓库中提供了完整的本地运行指引,见 docs/wiki/Run-FMG-locally.md。核心步骤为:

# 安装依赖并启动 Vite 开发服务器 npm install npm run dev

Vite 会打印访问地址(通常为http://localhost:5173/Fantasy-Map-Generator/),并支持热更新。若要构建生产版本:

npm run build # 生成静态构建到 dist/ npm run preview # 在本地预览该构建

说明:已经构建好的dist/目录也可以用通用的 Python/PHP 静态服务器托管,但源码树仍须依赖 Vite 环境。此外也可用npm run electron以桌面应用方式运行,npm run electron dist打包当前系统的安装包到release/。如果只是想离线使用生成器,可以直接下载桌面应用安装包,无需构建。

3.3 落地实现:样式预设的按需加载

动态导入的收益最先体现在样式预设(Style Presets)上,v1.72.1 之后:

  • 每个系统预设是一个独立的 JSON 文件,存放于 public/styles/ 目录(如ancient.json、cyberpunk.json、cinderwood.json等),不再整体打包;
  • 只加载当前使用的预设:切换预设时才fetch对应文件;
  • default 预设例外:它内置于构建产物中(src/generators/default-styles.json),无需网络请求,见 style-presets.js 中的注释与实现。

加载逻辑的核心代码位于 style-presets.js:

async function fetchSystemPreset(preset) { // default 预设随 bundle 内置,不走 fetch if (preset === "default") return Styles.defaults; try { const res = await fetch(`./styles/${preset}.json?v=${VERSION}`); return await res.json(); } catch (err) { throw new Error("Cannot fetch style preset", preset); } }

预设还分为两类:系统预设(硬编码列表,含 default、ancient、gloom、pale、light、watercolor、clean、atlas、darkSeas、cyberpunk、night、monochrome、ink、cinderwood、frostbite,见 style-presets.js)与自定义预设(保存在浏览器 localStorage 中,键名以fmgStyle_开头)。getStylePreset()会先判断目标预设是否属于系统列表:自定义预设从 localStorage 读取并校验 JSON 合法性,失效时回退到 default;系统预设才走上面的fetchSystemPreset()。预设文件的格式校验与解析逻辑可参见 styles.test.ts 与样式持久化端到端测试 style-persistence.spec.ts。

3.4 控制器级别的动态导入

动态导入并不局限于样式数据。v1.72.1 的控制器体系同样采用按需加载:所有控制器都注册在 src/controllers/index.ts 的createRegistry中,通过() => import("@/controllers/...")形式延迟加载,例如:

TemperatureGraph: () => import("@/controllers/temperature-graph").then(m => m.TemperatureGraph),

这意味着温度图表模块本身也只在使用时才被拉取,与应用体积优化一脉相承。

3.5 未来方向

作者明确表示:动态导入机制未来将允许在项目中加入更多预制数据,例如样式预设、纹理、地图、模块等。此前并非完全做不到,但管理成本高;拆分文件之后,新增数据只需在对应目录放一个 JSON/资源文件并注册即可,维护与扩展都更简单。

四、新增样式预设:Cyberpunk

为验证动态导入方案的实际效果,v1.72.1 同时新增了Cyberpunk样式预设。它基于社区(Discord 用户Terraria Eyeball with Salt in it)制作的赛博朋克地图风格,以独立 JSON 文件形式存在于 public/styles/cyberpunk.json,并已被加入系统预设列表 style-presets.js 与 UI 文档中的预设清单(docs/wiki/User-Interface.md)。

该预设并非面向所有用户的刚需,但它填补了默认列表此前缺失的一种鲜明风格。FMG 内置的 Style 编辑器本身功能丰富,支持对地图观感进行彻底定制;社区若提供更多风格方案,也可按同样方式扩充到默认预设列表。

五、延伸阅读

  • 温度图表控制器源码:神经网络权重、推断与 D3 绘制全流程
  • 城镇编辑器入口:温度图表按钮与调用链
  • 样式预设 UI 模块:系统/自定义预设的加载与切换
  • 控制器注册表:全局按需加载的控制器清单
  • 本地运行指南:开发服务器、生产构建与桌面应用
  • 更新日志:v1.72/v1.721/v1.722 相关条目
  • 用户界面文档:预设列表与 Style 编辑器说明
  • 前端
  • 图形学
  • 3D渲染

【免费下载链接】Fantasy-Map-Generator

Web application generating interactive and highly customizable maps

项目地址:https://gitcode.com/gh_mirrors/fa/Fantasy-Map-Generator
点击查看免费下载

相关推荐

上一篇:Jazz² Resurrection 是什么?开源C++复刻1998年经典《爵士兔2》的完整入门指南
下一篇:NetBox Docker终极部署指南:从零到精通的容器化网络管理

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询