diff --git a/addons/game_base/controllers/game_api.py b/addons/game_base/controllers/game_api.py index 6917d2b..444330d 100644 --- a/addons/game_base/controllers/game_api.py +++ b/addons/game_base/controllers/game_api.py @@ -5,11 +5,19 @@ from odoo.http import request, Response def _json(data): - """返回 UTF-8 JSON 响应。""" - return Response( + """返回 UTF-8 JSON 响应,并附加本地跨域调试头。""" + origin = request.httprequest.headers.get('Origin', '') + resp = Response( json.dumps(data, ensure_ascii=False), content_type='application/json; charset=utf-8', ) + # 允许 127.0.0.1:8888 本地前端跨域调试(生产环境走 nginx 同域,无需此头) + if origin.startswith('http://127.0.0.1:') or origin.startswith('http://localhost:'): + resp.headers['Access-Control-Allow-Origin'] = origin + resp.headers['Access-Control-Allow-Credentials'] = 'true' + resp.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' + resp.headers['Access-Control-Allow-Headers'] = 'Content-Type' + return resp def _post_body(): @@ -76,6 +84,52 @@ class GameApiController(http.Controller): }) return _json({'groups': groups}) + @http.route('/game/api/currencies', type='http', auth='public', methods=['GET'], csrf=False) + def currencies(self, **kw): + """货币等级:按 level 排序返回。""" + recs = request.env['game.currency'].sudo().search_read( + [], ['id', 'level', 'name', 'desc', 'rate'], order='level asc' + ) + return _json({ + 'items': [{ + 'id': r['id'], + 'level': r['level'], + 'name': r['name'], + 'desc': r['desc'] or '', + 'rate': r['rate'] or 1, + } for r in recs] + }) + + @http.route('/game/api/pages', type='http', auth='public', methods=['GET'], csrf=False) + def pages(self, **kw): + """页面板块:返回所有生效板块及其条目。""" + pages = request.env['game.page'].sudo().search_read( + [('active', '=', True)], + ['id', 'key', 'title', 'subtitle', 'body_html'], + order='sequence asc' + ) + out = [] + for p in pages: + items = request.env['game.page.item'].sudo().search_read( + [('page_id', '=', p['id'])], + ['id', 'icon', 'title', 'desc'], + order='sequence asc' + ) + out.append({ + 'id': p['id'], + 'key': p['key'], + 'title': p['title'], + 'subtitle': p.get('subtitle') or '', + 'body_html': p.get('body_html') or '', + 'items': [{ + 'id': it['id'], + 'icon': it.get('icon') or '', + 'title': it.get('title') or '', + 'desc': it.get('desc') or '', + } for it in items], + }) + return _json({'items': out}) + @http.route('/game/api/threads', type='http', auth='public', methods=['GET'], csrf=False) def threads(self, **kw): """论坛主题(含回复),按置顶+时间排序。""" diff --git a/addons/game_base/data/game_base_data.xml b/addons/game_base/data/game_base_data.xml index fbf7460..9e589ad 100644 --- a/addons/game_base/data/game_base_data.xml +++ b/addons/game_base/data/game_base_data.xml @@ -4,50 +4,50 @@ - world1蒙昧 - + world1凡墟 + - world2聚落 - + world2灵启 + - world3王国 - + world3玄界 + - world4文明 - + world4穹冥 + - world5飞升 - + world5溯元 + - faction1部族 - + faction1墟族 + - faction2城邦 - + faction2灵聚 + - faction3公国 - + faction3玄邑 + - faction4王国 - + faction4冥朝 + - faction5帝国 - + faction5穹统 + - faction6星盟 - + faction6溯盟 + @@ -64,6 +64,32 @@ character11圣者 character12永恒 + + + 1墟铢100 + + + + 2灵币100 + + + + 3玄锭100 + + + + 4冥玉100 + + + + 5穹鎏100 + + + + 6元玺1 + + + race龙裔龙裔传说 @@ -106,4 +132,121 @@ 宇森官网第一阶段上线:介绍 / 规则 / 图鉴 / 论坛 / 公告 五块,单页切换呈现。欢迎园丁们入驻。

]]>
+ + + + features + 游戏特色 + CORE FEATURES + 10 + + + + 10 + 🌐 + 垂直五层世界 + 从地心熔岩到陨石星空,文明在五个垂直切面中同时生长,每一层都有独立的生态、资源与事件池。 + + + + 20 + 🌱 + 自发演化 + 不是脚本,不是关卡。文明自己生长、分裂、兼并、飞升——每一次开局都是一部独一无二的编年史。 + + + + 30 + 🧑‍🌾 + 园丁视角 + 你不是英雄,也不是上帝。你是园丁——播种灵气、引导势力、守望文明,在关键节点轻推一把,让世界自洽前行。 + + + + 40 + ⚖️ + 三维等级联动 + 世界等级定舞台上限,势力等级定群体进度,角色等级定个体极限。三者交叉构成无限策略空间。 + + + + 50 + 💰 + 六档货币体系 + 从墟铢到元玺,百进制兑换贯穿五层世界。跨层贸易、资源调度、神器交易构成完整经济闭环。 + + + + 60 + 🎭 + 活的个体 + 每个 NPC 都有独立的天赋、性格与成长轨迹。英雄在历练中觉醒,传奇在时间中自发生成,无人是棋子。 + + + + + background + 世界起源 + BACKGROUND + 20 + 天地初开,混沌未分。一缕灵气自地心涌出,沿垂直切面向上攀爬——穿透岩层、跨越地表、掠过云海、直抵星空。五层世界自此苏醒。

+

地表层最先活过来。灵气稀薄,但足够点燃文明的火种。各族散居荒野,狩猎采集,以血缘结群,在蒙昧的凡土上挣扎求生。这是凡墟

+

而后灵气渐浓,天地共振。聚落涌现,分工萌芽,物物交换催生最早的势力。灵启的时代,文明开始有了形状。

+

再往后,是兼并、是征伐、是道统与造物的竞逐。玄界的大地上,多元族群共治的完整疆域成形,传奇事件如潮涌来。

+

直到有一天,有人掘穿了地表之下的黑暗,有人驾着浮空石飞上了云海。地下深渊与浩瀚星空同时向文明敞开——穹冥时代,天地上下尽数纳入管辖。

+

最终,顶尖文明勘破了这片天地的诞生本源。他们追溯灵气的源头,在地心深处找到了答案。飞升、轮回、更高维度的演化实验——溯元,不是终点,而是新的起点。

+

而你,是这一切的园丁。

]]>
+
+ + + 10 + + 星空层 + 陨石科技带 · 穹鎏产地 + + + + 20 + + 天空层 + 云朵地基块 · 浮空城邦 + + + + 30 + + 地表层 + 文明发源地 · 主舞台 + + + + 40 + + 地下层 + 矿脉深渊 · 冥玉产地 + + + + 50 + + 地心层 + 本源之地 · 元玺凝聚 + + + + + letter + 致园丁 + A LETTER TO GARDENERS + 30 + 致每一位踏入宇森的园丁:

+

感谢你来到这里。

+

宇森不是一款传统的策略游戏。这里没有关卡,没有通关,没有固定的胜利条件。我们想做的,是一个会自己呼吸的世界——你播下一颗种子,它自己长成一片森林;你引导一个族群,它自己走出一段历史。

+

你是园丁,不是上帝。你不能命令谁去做什么,但你可以改变土壤、调节灵气、在关键节点轻轻推一把。文明的走向由无数个体的选择汇聚而成,而你只是其中一股温柔的力。

+

这个世界有五层。从地心到星空,每一层都有自己的生态和故事。文明会从地表的凡墟开始,一路向上向下生长,直到触及世界的本源。这个过程可能很慢,也可能充满意外——但那正是我们想要的。

+

我们还在生长。宇森目前处于早期阶段,很多系统仍在打磨。但你看到的每一个种族、每一件神器、每一段传奇事件,都是这个世界真实存在的一部分。它们会随着版本的推进越来越厚,越来越活。

+

如果你在这里找到了哪怕一刻的沉浸感,那就是我们最大的成功。

+

欢迎播种。

]]>
+
+ diff --git a/addons/game_base/models/__init__.py b/addons/game_base/models/__init__.py index 1e5fe2a..ebfc125 100644 --- a/addons/game_base/models/__init__.py +++ b/addons/game_base/models/__init__.py @@ -2,3 +2,5 @@ from . import codex from . import forum from . import announcement from . import rule +from . import currency +from . import page diff --git a/addons/game_base/models/currency.py b/addons/game_base/models/currency.py new file mode 100644 index 0000000..4e4e0fd --- /dev/null +++ b/addons/game_base/models/currency.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +from odoo import models, fields, api + + +class GameCurrency(models.Model): + _name = 'game.currency' + _description = '游戏货币等级' + _order = 'level asc' + + level = fields.Integer(string='等级', required=True) + name = fields.Char(string='名称', required=True) + desc = fields.Text(string='描述') + rate = fields.Integer( + string='兑换比例', + default=1, + help='多少单位本货币可兑换 1 单位下一等级货币。例如 100 墟铢 = 1 灵币,则墟铢的 rate 为 100。' + ) + + @api.model + def convert(self, amount, from_level, to_level): + """按等级汇率将 amount 从 from_level 换算为 to_level 货币。 + + 汇率方向:低等级 → 高等级 为除以 rate,高等级 → 低等级 为乘以 rate。 + 最高等级货币(元玺)的 rate 固定为 1,仅作占位。 + """ + if from_level == to_level: + return amount + currencies = self.search_read([], ['level', 'rate'], order='level asc') + rate_map = {c['level']: c['rate'] or 1 for c in currencies} + + if from_level < to_level: + # 低等级 → 高等级:逐级除以兑换比例 + result = amount + for lv in range(from_level, to_level): + result = result / rate_map.get(lv, 1) + return result + else: + # 高等级 → 低等级:逐级乘以兑换比例 + result = amount + for lv in range(to_level, from_level): + result = result * rate_map.get(lv, 1) + return result diff --git a/addons/game_base/security/ir.model.access.csv b/addons/game_base/security/ir.model.access.csv index 6dca7cf..b8bb0c4 100644 --- a/addons/game_base/security/ir.model.access.csv +++ b/addons/game_base/security/ir.model.access.csv @@ -9,3 +9,9 @@ access_game_announcement,game.announcement public,model_game_announcement,base.g access_game_announcement_user,game.announcement user,model_game_announcement,base.group_user,1,1,1,1 access_game_rule,game.rule public,model_game_rule,base.group_public,1,0,0,0 access_game_rule_user,game.rule user,model_game_rule,base.group_user,1,1,1,1 +access_game_currency,game.currency public,model_game_currency,base.group_public,1,0,0,0 +access_game_currency_user,game.currency user,model_game_currency,base.group_user,1,1,1,1 +access_game_page,game.page public,model_game_page,base.group_public,1,0,0,0 +access_game_page_user,game.page user,model_game_page,base.group_user,1,1,1,1 +access_game_page_item,game.page.item public,model_game_page_item,base.group_public,1,0,0,0 +access_game_page_item_user,game.page.item user,model_game_page_item,base.group_user,1,1,1,1 diff --git a/addons/game_base/views/game_base_views.xml b/addons/game_base/views/game_base_views.xml index 90a90fd..503195f 100644 --- a/addons/game_base/views/game_base_views.xml +++ b/addons/game_base/views/game_base_views.xml @@ -60,6 +60,68 @@ + + + 货币等级 + game.currency + list,form + + + + game.currency.list + game.currency + + + + + + game.currency.form + game.currency + +
+
+
+ + + + 页面板块 + game.page + list,form + + + + game.page.list + game.page + + + + + + + + game.page.form + game.page + +
+ + + + + + + + + + + + + + + +
+
+
+ diff --git a/assets/game-api.js b/assets/game-api.js index d114327..f047e6d 100644 --- a/assets/game-api.js +++ b/assets/game-api.js @@ -1,42 +1,61 @@ // 宇森游戏 · 前端与 Odoo 通信层 -// 所有接口同源(yt.pengyuthon.cn),由 nginx 代理 /game/* 到 Odoo(game 库)。 -// 关键点:Odoo 通过 URL 上的 ?db=game 选定数据库(与 game.conf 的 /web/login?db=game 一致), -// 否则请求到达时未选中库,控制器路由找不到 → 404。因此所有调用都带 ?db=game。 -// 登录态通过 Odoo session cookie 保持,fetch 带 credentials:'same-origin'。 +// 本地调试:前端 8888 -> Odoo 8069(跨域,带调试 CORS 头) +// 生产部署:前端与 Odoo 同域,由 nginx 代理 /game/*。 + +const API_CONFIG = { + base: (location.hostname === '127.0.0.1' && location.port === '8888') + ? 'http://127.0.0.1:8069' + : (location.hostname === 'localhost' && location.port === '8888') + ? 'http://127.0.0.1:8069' + : '', + db: (location.hostname === '127.0.0.1' && location.port === '8888') ? 'study' : 'game', +}; + +const _cred = API_CONFIG.base ? 'include' : 'same-origin'; + +function _url(path) { + return `${API_CONFIG.base}${path}?db=${API_CONFIG.db}`; +} const API = { async me() { - return (await fetch('/game/api/me?db=game', { credentials: 'same-origin' })).json(); + return (await fetch(_url('/game/api/me'), { credentials: _cred })).json(); }, async login(login, password) { - return (await fetch('/game/api/login?db=game', { - method: 'POST', credentials: 'same-origin', + return (await fetch(_url('/game/api/login'), { + method: 'POST', credentials: _cred, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ login, password }), })).json(); }, async register(payload) { - return (await fetch('/game/api/register?db=game', { - method: 'POST', credentials: 'same-origin', + return (await fetch(_url('/game/api/register'), { + method: 'POST', credentials: _cred, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload), })).json(); }, async logout() { - return (await fetch('/game/api/logout?db=game', { - method: 'POST', credentials: 'same-origin', + return (await fetch(_url('/game/api/logout'), { + method: 'POST', credentials: _cred, })).json(); }, async codex() { - return (await fetch('/game/api/codex?db=game', { credentials: 'same-origin' })).json(); + return (await fetch(_url('/game/api/codex'), { credentials: _cred })).json(); }, async rules() { - return (await fetch('/game/api/rules?db=game', { credentials: 'same-origin' })).json(); + return (await fetch(_url('/game/api/rules'), { credentials: _cred })).json(); + }, + async currencies() { + return (await fetch(_url('/game/api/currencies'), { credentials: _cred })).json(); + }, + async pages() { + return (await fetch(_url('/game/api/pages'), { credentials: _cred })).json(); }, async threads() { - return (await fetch('/game/api/threads?db=game', { credentials: 'same-origin' })).json(); + return (await fetch(_url('/game/api/threads'), { credentials: _cred })).json(); }, async announcements() { - return (await fetch('/game/api/announcements?db=game', { credentials: 'same-origin' })).json(); + return (await fetch(_url('/game/api/announcements'), { credentials: _cred })).json(); }, }; diff --git a/assets/site-app.js b/assets/site-app.js index 2fc071b..a6199d1 100644 --- a/assets/site-app.js +++ b/assets/site-app.js @@ -1,6 +1,43 @@ // 宇森官网 · 公开页数据打通(图鉴/规则/论坛/公告 从 Odoo 取数) // 依赖 assets/game-api.js +// ---------- 页面板块(特色 / 背景 / 致玩家) ---------- +async function loadPages(){ + try { + const d = await API.pages(); + const pages = (d && d.items) || []; + pages.forEach(p => { + if (p.key === 'features') renderFeatures(p); + else if (p.key === 'background') renderBackground(p); + else if (p.key === 'letter') renderLetter(p); + }); + } catch (e) { /* 失败时保留 HTML 中的静态兜底内容 */ } +} + +function renderFeatures(p){ + const sec = document.getElementById('features'); + if (!sec) return; + const items = (p.items || []).map(it => + `
${it.icon || ''}

${it.title || ''}

${it.desc || ''}

` + ).join(''); + sec.innerHTML = `
${p.title || '游戏特色'}${p.subtitle || ''}
${items}
`; +} + +function renderBackground(p){ + const sec = document.getElementById('background'); + if (!sec) return; + const layers = (p.items || []).map((it, idx) => + `
${it.title || ''}
${it.desc || ''}
${it.icon || '✦'}
` + ).join(''); + sec.innerHTML = `
${layers}

${p.title || '世界起源'}

${p.body_html || ''}
`; +} + +function renderLetter(p){ + const sec = document.getElementById('letter'); + if (!sec) return; + sec.innerHTML = `

${p.title || ''}

${p.subtitle || ''}
${p.body_html || ''}
—— 宇森开发组
`; +} + // ---------- 规则 ---------- async function loadRules(){ const el = document.querySelector('#rules .rules-scroll'); @@ -8,7 +45,7 @@ async function loadRules(){ try { const d = await API.rules(); const groups = (d && d.groups) || []; - if (!groups.length){ el.innerHTML = '
暂无规则数据
'; return; } + if (!groups.length){ return; } el.innerHTML = groups.map(g => { const rows = (g.items || []).map(it => { const lvl = (it.level != null) ? ('Lv.' + it.level) : (g.key === 'world' ? '阶段' : ''); @@ -63,6 +100,7 @@ async function loadAnnounce(){ } document.addEventListener('DOMContentLoaded', () => { + loadPages(); loadRules(); loadForum(); loadAnnounce(); diff --git a/index.html b/index.html index 6c5b90f..2a35e57 100644 --- a/index.html +++ b/index.html @@ -166,12 +166,25 @@ .note .body{font-size:14px;color:var(--text);line-height:1.7;} .note.pin{box-shadow:var(--glow);} + /* ===== 致玩家 ===== */ + #letter{align-items:center;justify-content:center;} + #letter .letter-wrap{max-width:680px;width:100%;overflow-y:auto;padding:10px 20px;} + #letter .letter-wrap h2{font-family:"ZCOOL QingKe HuangYou",sans-serif;font-size:30px;letter-spacing:4px;color:#fff;text-shadow:0 0 18px rgba(139,92,246,.5);margin-bottom:6px;text-align:center;} + #letter .letter-wrap .lt-sub{text-align:center;font-family:"Press Start 2P",monospace;font-size:9px;color:var(--magenta);letter-spacing:1px;margin-bottom:28px;} + #letter .letter-wrap .lt-body{font-size:15px;color:var(--text-dim);line-height:2.1;} + #letter .letter-wrap .lt-body p{margin-bottom:16px;} + #letter .letter-wrap .lt-body p:first-child{font-size:17px;color:#fff;font-weight:500;} + #letter .letter-wrap .lt-body .hl{color:var(--gold);font-weight:500;} + #letter .letter-wrap .lt-sign{text-align:right;margin-top:28px;font-size:14px;color:var(--magenta);font-style:italic;} + @media (max-width:900px){ .grid{grid-template-columns:repeat(2,1fr);} #background,#forum{flex-direction:column;overflow-y:auto;} .layers,.f-cats{flex:none;} .hero .copy h1{font-size:42px;} .nav button{padding:8px 10px;font-size:13px;} + .nav{overflow-x:auto;scrollbar-width:none;} + .nav::-webkit-scrollbar{display:none;} } @@ -181,10 +194,13 @@
@@ -210,38 +226,41 @@ - +
- +
等级制度TIERS & RANK SYSTEM
+

① 世界等级 · 五阶段

-

世界从蒙昧到飞升的整体进化阶段,决定可解锁的内容深度与事件池上限。园丁对世界施加的影响会推动阶段跃迁——这是文明能"发生什么"的舞台上限。

+

世界从凡墟到溯元的整体进化阶段,决定可解锁的内容深度与事件池上限。园丁对世界施加的影响会推动阶段跃迁——这是文明能"发生什么"的舞台上限。

-
阶段一蒙昧文明萌芽,仅基础采集与居住,无势力概念,事件以自然为主。
-
阶段二聚落出现村落与分工,解锁基础建造与贸易,可建立首个势力。
-
阶段三王国统一政权成形,解锁军事/宗教/科技分支,传奇事件开始频现。
-
阶段四文明跨层互通成熟,地下与星空纳入治理,神器与装备体系全开。
-
阶段五飞升文明触及世界本质,可开启飞升轮回,进入更高维的演化实验。
+
阶段一凡墟万物生灵尚处蒙昧凡土,天地灵气稀薄,各族散居荒野,无族群联盟与政权,只求狩猎采集求生,一切秩序遵循自然法则。
+
阶段二灵启天地灵气复苏觉醒,各族聚拢形成聚落,诞生劳作分工、屋舍营建与物物交换,不同族群率先凝聚部族,世间初代势力自此诞生。
+
阶段三玄界各族部落兼并融合,广袤大地形成多元族群共治的完整疆域,征伐、道统、造物三大发展路线并行;各族大能、上古秘闻等传奇事件不断现世,玄荒文明迎来鼎盛割据时代。
+
阶段四穹冥生灵突破地表桎梏,打通地底深渊与浩瀚星空,天地上下各界尽数纳入族群管辖;各类上古神器、本命法器完整解锁,文明疆域遍布天地穹苍。
+
阶段五溯元各族顶尖文明勘破这片天地的诞生本源,挣脱本世界规则束缚,可踏上飞升之路、往复轮回,前往更高维度开启全新文明演化。
+

② 势力等级

文明内部群体的聚合度,由人口、领土、影响力累计。势力等级越高,可调动的世界资源与外交权重越大——决定文明"能调动什么"。

-
Lv.1部族血缘纽带的小群体,无正式制度。
-
Lv.2城邦多聚落联盟,出现雏形治理与税收。
-
Lv.3公国领地整合,常备军与法典成型。
-
Lv.4王国统一王朝,跨层资源调度能力。
-
Lv.5帝国大陆级霸权,可发起跨世界行动。
-
Lv.6星盟联结多方世界,参与宏观文明博弈。
+
Lv.1墟族血缘小群体,蛮荒无制度。
+
Lv.2灵聚灵气聚落联盟,初步治理与贸易。
+
Lv.3玄邑疆域整合,军法、道规体系完善。
+
Lv.4冥朝一统大地,掌控地下浅层资源调度。
+
Lv.5穹统天地大陆霸主,穿梭星空深渊作战。
+
Lv.6溯盟多维文明联合体,触及世界本源博弈。
+

③ 人物角色等级 · 十二阶段

个体(英雄 / 领袖 / 特殊 NPC)的成长阶序,通过历练、天赋点亮与装备积累提升,影响可承担的职责与战力——决定个体"能做成什么"。

@@ -260,10 +279,24 @@
Lv.12永恒超越生死的世界锚点。
+

④ 制度说明

三者相互独立又彼此加成:世界等级是舞台上限,决定能发生什么;势力等级是群体进度,决定能调动什么;角色等级是个体成长,决定能做成什么。园丁的核心策略,是在三者间分配有限的引导资源,让文明自洽地向上演化。

跃迁逻辑:角色历练与装备积累→提升势力实力→推动世界阶段跃迁→解锁更深内容(更深的地下层、更远的星空层、更强的神器)。每一级提升都会扩大可叙事的事件池,世界因此越活越厚。

+ +
+

⑤ 货币等级 · 六档

+

文明流通的价值尺度,从凡俗零钱到本源货币,越稀有的货币可交易的资源层级越高——决定文明"能交换什么"。

兑换规则:100 低等级货币 = 1 高等级货币。

+
+
Lv.1墟铢凡俗通用零钱,以贝壳、骨片、碎石铸成。100 墟铢 = 1 灵币
+
Lv.2灵币蕴含微量灵气的金属铸币,聚落以上势力日常使用。100 灵币 = 1 玄锭
+
Lv.3玄锭刻有玄纹的稀有锭块,用于高价值交易与功法图纸。100 玄锭 = 1 冥玉
+
Lv.4冥玉产自地底深渊的幽暗玉石,蕴含浓郁能量。100 冥玉 = 1 穹鎏
+
Lv.5穹鎏来自星空矿脉的稀有鎏金晶体,跨层贸易硬通货。100 穹鎏 = 1 元玺
+
Lv.6元玺追溯世界本源凝聚而成的至高货币,可兑换神器、传说事件与维度权限。
+
+
@@ -314,13 +347,16 @@
公告ANNOUNCEMENTS
-
2026.07.09
宇森官网第一阶段上线:介绍 / 特色 / 背景 / 规则 / 图鉴 / 论坛 / 公告 七块,单页切换呈现,介绍页即概念宣传片。
+
2026.07.09
宇森官网第一阶段上线:介绍 / 特色 / 背景 / 规则 / 图鉴 / 论坛 / 公告 / 致玩家 八块,单页切换呈现,介绍页即概念宣传片。
2026.07.09
图鉴系统升级:种族 204 条、系别/性格/天赋/神器/传奇事件全面扩量,装备槽位对齐 头/手/胸/裤/鞋/戒指(双)/项链/宝物;全部缩略图改为程序化矢量插画,零 AI 生图。
2026.07.08
概念宣传片《垂直生长》完成,呈现五层世界自上而下生长的镜头语言(天空层改为云朵地基块,星空层改为陨石科技带)。
2026.07.01
园丁视角核心玩法原型启动,首版六边形地图与活 NPC 验证中。
2026.06.20
图鉴系统规划确定:种族 / 建筑 / 生物 / 神器 四大类目,美术持续补充中。
+ + +
diff --git a/website/demo.html b/website/demo.html index a90f84f..0bbcbe7 100644 --- a/website/demo.html +++ b/website/demo.html @@ -3,7 +3,6 @@ - 宇森 · 世界沙盘