chenmo—— 可编程元叙事引擎 V2.2
Deploy, Register, Mix, Inspect, and Reason with Structured Fictional Universes
chenmo是一个面向高设定密度虚构世界(如硬科幻、生态宇宙、文明模拟、赛博朋克)的 Python 领域特定语言(DSL)库。它允许你用精确的类 Python 语句操控虚构宇宙的全生命周期:
- 部署(
d)与更新(u)设定包 - 注册(
l)本地创想,支持嵌套引用已有内核或镜像 - 混合(
x)多源设定,按权重杂交进化 - 提取内核(
c)、人物(p) - 创建镜像(
m)、转义(t) - 推演(
r)原生情节发展(仅限当前作品已声明实体) - 查看(
i)任意实体元信息
“设定即代码,宇宙可部署,推演可编程,创想可注册。”
PS: 这最初是一个虚构设定,但现在
chenmo原型已真实存在!你可通过
pip install chenmo安装基础版本,并在本地开发环境中以可编辑模式参与构建。
它仍处于概念验证阶段(仅l与i部分功能可用),但已足以作为元叙事引擎的最小可行载体——既可运行,也可写入小说。
📜 完整语句语法规范(全覆盖)
所有语句遵循统一结构:[操作头].[作品名].[下名](参数...)
路径补全规则
- 若省略
[下名],自动补全为novies(保留下名,代表主叙事本体)
例:d.neuromancer→d.neuromancer.novies novies语义:指代作品的小说/电影主干,几乎不可能被用作角色名,避免命名冲突。- 路径前缀语义:
- 以
temps.开头的路径(如temps.cyber_demo)为临时作品
→ 数据写入~/.chenmo/temps/works/,会话有效,需手动清理 - 其他路径为持久作品
→ 数据写入~/.chenmo/works/,自动注册到全局命名空间
- 以
💾 存储与命名空间(核心规范)
chenmo的所有数据持久化严格遵循以下文件系统布局:
~/.chenmo/ ├── works/ # 持久化作品(全局命名空间) │ └── <作品名>/ # ← 作品名 = 命名空间根(必须全局唯一) │ ├── manifest.json │ ├── novies/ # 主叙事内容 │ ├── cores/ # 内核:物理、生态、社会法则 │ ├── personas/ # 人物本体(p) │ └── tech/ # 科技、装置、载具 │ └── temps/ # 临时会话空间(完全隔离) └── works/ └── <作品名>/ # ← 临时作品名可重复,但限于 temps/ 域内 ├── manifest.json └── ...(同上)命名原则(【致命】级别)
命名冲突 = 宇宙污染 = 推演崩溃
- ✅必须使用源作品官方标识符
例:《阿凡达》中的星球意识应命名为eywa,禁止使用eva、ava、lilith等高冲突词(因与《EVA》《Ex Machina》等 IP 冲突) - ✅原创实体需具备上下文区分度
例:dr_leno、bio_net_core_7,避免helper、god、ai、neo等通用词 - ✅所有引用必须带作品前缀
例:i.avatar.eywa(...)正确;i.eywa(...)非法(未指定命名空间) - ❌禁止无作品名的裸操作
l.spider(...)将被拒绝或强制重定向至temps.anon
“路径即身份” —— 同名作品(但可以使用"_"特指某一个分支)在
works/中仅存一份,覆盖即血缘断裂。
🔧 操作详解(完整版)
1.d—— 部署(Deploy)
从源安装设定包到本地持久空间~/.chenmo/works/<toas>/
d.[源作品名].[源下名](from="源路径",# 可选,默认从官方仓库解析to="~/.chenmo/works/",# 固定基路径,用户不可改toas="本地命名"# 必须唯一,写入 works/<toas>/)- 作用:下载
.narr包,解压至~/.chenmo/works/<toas>/,注册到全局命名空间 - 包格式:
.narr= ZIP +manifest.json,内部结构必须含novies/,cores/,personas/,tech/ - 命名安全:若
toas已存在,系统报错Namespace collision: <toas> already exists,拒绝覆盖
示例:
d.blade_runner(toas="la_2049")# → 部署至 ~/.chenmo/works/la_2049/d.dune.spice_economy(from="git://dune-core",toas="arrakis_econ")# → 部署至 ~/.chenmo/works/arrakis_econ/2.u—— 更新(Update)
在已有持久作品上增量合并变更,目标路径必须存在于~/.chenmo/works/
模式 A:原地更新(无lo)
u.[本地作品名].[本地下名](from="源路径",# 必须to="~/.chenmo/works/[本地作品名]",# 固定,不可改merge="策略"# overlay | patch | strict | interactive)模式 B:分支合并(有lo)
u.[本地作品名].[本地下名](from="源路径",# 必须lo="~/.chenmo/works/[本地作品名]",# 必须:Local Originto="~/.chenmo/works/[新作品名]",# 必须toas="[新作品名]",# 可选,默认 = 新作品名merge="策略")- 语义:
merge="overlay"覆盖冲突字段;"strict"遇冲突即失败 - 命名安全:
toas若已存在,报错并中止
示例:
u.la_2049.novies(from="threebody/dark_forest",lo="~/.chenmo/works/la_2049",to="~/.chenmo/works/blade_runner_df",toas="br_df",merge="overlay")🔥 3.l—— 注册(Log / Register)
从零声明新作品、人物、设定或物品,适用于本地创作起点。
l.[作品名].[下名](log_works="作品描述",# 仅当下名=novies 时有效log_person=["人物描述",...],# 注册至 personas/log_settings=["设定描述",...],# 注册至 cores/ 或 novies/log_thing=["物品/科技描述",...]# 注册至 tech/)✅ 高级能力:嵌套引用结构化设定
支持内联引用同一作品内已有内核或镜像:
log_settings=i.[作品名].[下名](target='c')# 引用内核log_settings=i.[作品名].[下名](target='m')# 引用镜像(推荐用于命运映射)- 语义:注册时内联拷贝结构,非运行时查询
- 存储路径:
- 若
[作品名]以temps.开头 → 写入~/.chenmo/temps/works/<作品名>/ - 否则 → 写入
~/.chenmo/works/<作品名>/
- 若
- 命名安全:若持久作品名已存在,报错
Namespace exists
完整示例(安全命名):
# 创建新作品(持久)l.neural_frontier.novies(log_works="Neural Frontier",log_person=["Kai","Dr. Aris Thorne"])# → 写入 ~/.chenmo/works/neural_frontier/# 为 Kai 赋予“蜘蛛式”命运结构(身份撕裂)l.neural_frontier.kai(log_settings=i.neural_frontier.spider_archetype(target='m'))# → 写入 ~/.chenmo/works/neural_frontier/personas/kai.json# 临时实验:赛博格侦探(隔离)l.temps.cyber_noir.novies(log_person=["Detective Voss"],log_thing=["Neural Lace v3.1"])# → 写入 ~/.chenmo/temps/works/cyber_noir/🔥 4.x—— 混合(Mix)
按权重融合多源设定,生成新实体,必须先通过d/l声明所有源
x.mxd.in(sources=[("作品1","下名1"),("作品2","下名2")],# 所有源必须已存在weights=[0.6,0.4],target_type="c"|"p"|"t",# c=内核, p=人物, t=科技toas="新实体名")- 存储路径:结果写入
~/.chenmo/works/<toas>/(持久) - 命名安全:
toas必须唯一 - 注意:
x用于设定构建,不用于情节推演;r不可直接调用x结果,除非先l或d注册
示例:
x.mxd.in(sources=[("neuromancer","case"),("blade_runner","deckard")],weights=[0.7,0.3],target_type="p",toas="cyber_investigator")# → 生成 ~/.chenmo/works/cyber_investigator/personas/novies.json5.f—— 实例化(Fabricate)
动态生成作品实例(通常由d自动调用,用户极少直接使用)
f.[作品名].[下名](setting="描述字符串")- 作用:根据描述生成最小 viable 作品结构,写入
~/.chenmo/works/[作品名]/ - 命名安全:若作品名已存在,报错
示例:
f.solaris.novies(setting="Ocean planet with sentient plasma")# → 创建 ~/.chenmo/works/solaris/ 基础结构6.c—— 内核提取(Core)
定义或提取底层法则,写入cores/
c.[作品名].[下名](axioms=["公理1","公理2"],# 不可违反的基本法则constraints=["约束1","约束2"]# 可配置的边界条件)- 存储路径:
~/.chenmo/works/[作品名]/cores/[下名].json - 命名安全:同一作品内下名必须唯一
示例:
c.dune.spice_economy(axioms=["water_is_gold","spice_enables_navigation"],constraints=["no_atomic_weapons"])7.p—— 人物提取(Persona)
定义人物本体身份,写入personas/
p.[作品名].[下名](traits=["特质1","特质2"],constraints=["不可为行为1","不可为行为2"])- 存储路径:
~/.chenmo/works/[作品名]/personas/[下名].json - 语义:
p定义“他是谁”,是r推演的不可变基础
示例:
p.neuromancer.case(traits=["cyber_jockey","addicted_to_stimulants"],constraints=["no_corpo_loyalty"])8.m—— 镜像(Mirror)
创建命运变体,写入personas/作为子实体
m.[作品名].[下名](mp="源人物名",# 必须存在r="命运变更描述",# 如 "raised_by_fremen"as_sub="新镜像名"# 如 "paul_fremen")- 存储路径:
~/.chenmo/works/[作品名]/personas/[as_sub].json - 语义:
p说“他是谁”,m说“他可能成为谁”
示例:
m.dune.paul(mp="paul",r="raised_by_fremen_after_bene_gesserit_failure",as_sub="paul_fremen")9.t—— 转义(Transmute)
派生新作品,保留血缘,写入新持久路径
t.[源作品名].[源下名](toas="新作品名",rcd="血缘描述"# 如 "br_2049_official")- 作用:复制整个作品结构到
~/.chenmo/works/<toas>/,添加血缘元数据 - 命名安全:
toas必须唯一
示例:
t.blade_runner.novies(toas="la_2099",rcd="br_2049_official")✅ 10.r—— 推演(Run)←仅用于原生情节发展
r不引入新设定,不跨宇宙操作,仅在当前作品已注册实体上推导情节事件。
所有情节必须基于~/.chenmo/works/[作品名]/或temps/中已存在数据。
语法规则
r.[作品名].[下名](when=<条件表达式>,# 基于 i.[作品名]... 查询结果then="情节事件ID",# 预定义或内联事件名(非台词)outcome={...}# 可选:声明状态变更(用于后续 r 或 i))关键约束
- 所有
i(...)查询必须限定在同一作品名下 then应描述情节事件(如"eywa_grants_respiration"),非角色台词- 不可引用未通过
l/d/u声明的实体 - 不可跨作品引用(如
r.avatar.spider(when=i.neuromancer.ava...)非法)
✅ 正确示例(原生、无交叉、命名安全)
# 前提:avatar.spider 与 avatar.eywa 已通过 l 注册l.avatar.spider(log_person="Human orphan born on Pandora; lungs incompatible with Terran air")l.avatar.eywa(log_person="Pandoran planetary consciousness",log_settings=["responds_to_extinction_threat"])# 推演:Eywa 介入(使用官方名 eywa,非 eva)r.avatar.spider(when=(i.avatar.spider(target='p').o2_level<0.1andi.avatar.eywa(target='p').attentive==True),then="eywa_grants_pandoran_respiration",outcome={"spider.physiology":"+native_respiration","world_state":"hybrid_acknowledged"})此操作仅依赖
~/.chenmo/works/avatar/内已存在设定,无需x、u或外部引用。
11.i—— 查看(Inspect)
i.[作品名].[下名](target='c'|'p'|'m')- 作用:返回指定实体的结构化元数据
- 存储查询路径:
target='c'→ 读取~/.chenmo/.../cores/[下名].jsontarget='p'→ 读取~/.chenmo/.../personas/[下名].jsontarget='m'→ 读取镜像 persona(通常为 persona 子类)
- 在
l嵌套中,i... (target='m')用于引用命运结构 - 必须带作品名前缀,否则报错
Missing namespace
示例:
i.dune.paul(target='c')# 查看内核i.avatar.eywa(target='p')# 查看 Eywa 本体(使用官方名)📦 包与协议
- 包格式:
.narr= ZIP +manifest.json - 内部结构:
work.narr ├── manifest.json ├── novies/ ├── cores/ # 内核:物理、经济、生态法则 ├── personas/ # 人物本体 └── tech/ # 科技、装置、载具 - manifest.json 必须包含:
{"name":"作品名","version":"1.0","canonical_source":"可选官方源标识"}
🎯 设计原则(完整版)
p定义存在,m定义可能性r仅推演原生情节,不负责设定引入- 路径即身份,命名冲突【致命】
- 临时隔离:
temps.不污染works/命名空间 - 创作分层:
l(声明)→u/x(组合)→r(推演) - 所有引用必须带作品前缀,禁止裸标识符
- Eywa 必须拼写为
eywa,禁用eva等高冲突变体
🌠 适用场景
- 🧠赛博朋克角色构建:身份撕裂、神经植入、公司奴役(基于已注册
p/m) - 🌍生态反乌托邦:资源枯竭、气候难民、新社会契约(基于
c内核) - 🚀硬科幻文明模拟:星际政治、AI 伦理、费米悖论
- 🧬原生命运映射:如“蜘蛛式孤儿”在《阿凡达》宇宙中被
eywa救赎 - 🤖AI 叙事对齐测试:在强约束下生成一致剧情(
r严格遵守p/c)
📜 许可证
MIT License —— 自由用于个人与商业项目。
“以前,我们写宇宙。
现在,我们部署、注册、混合、查询、合并、并编程推演宇宙。”
用chenmo,让虚构世界运行于逻辑、约束与叙事动力学之中。
——作者:你
——存储于:~/.chenmo/works/chenmo_docs/novies