存在

 切换到Typsite [new-ssg]

去年4月, 我基于 Vitepress 开发了 Librorum, 作为能享受整个NPM 生态且支持 Vue3SSG, 其功能是非常丰富的:

  • 文章归档(Timeline)
  • 分类, 标签, 词云, 全局搜索
  • 个性化阅读配置(感谢 AyakaNeko)
  • 支持 (markdown-it-mathjax3)
  • And more…
这听起来非常棒, 不是吗?


但当你在阅读我那充斥着 鬼画符 的Lambda Calculus页面与拉康精神分析文章, 并认为效果海星时, 在其背后却是这样的:

\begin{align*}
Y_v(M)(1)
&= D(1) \\
&= M\ (\lambda a.\, D(a))\ (1) \\
&= (\lambda f.\, \lambda n.\, \text{if } n = 0 \text{ then } 1 \text{ else } n \cdot f(n - 1))\ (\lambda a.\, D(a))\ (1) \\
&\Rightarrow 1 \cdot (\lambda a.\, D(a))(0) \\
&= 1 \cdot D(0) \\
&= 1 \cdot M\ (\lambda a.\, D(a))\ (0) \\
&= (\lambda f.\, \lambda n.\, \text{if } n = 0 \text{ then } 1 \text{ else } n \cdot f(n - 1))\ (\lambda a.\, D(a))\ (0) \\
&\Rightarrow 1 \cdot 1 \\
&= 1
\end{align*}
\begin{align*}
Y_v(M)(1)
&= D(1) \\
&= M\ (\lambda a.\, D(a))\ (1) \\
&= (\lambda f.\, \lambda n.\, \text{if } n = 0 \text{ then } 1 \text{ else } n \cdot f(n - 1))\ (\lambda a.\, D(a))\ (1) \\
&\Rightarrow 1 \cdot (\lambda a.\, D(a))(0) \\
&= 1 \cdot D(0) \\
&= 1 \cdot M\ (\lambda a.\, D(a))\ (0) \\
&= (\lambda f.\, \lambda n.\, \text{if } n = 0 \text{ then } 1 \text{ else } n \cdot f(n - 1))\ (\lambda a.\, D(a))\ (0) \\
&\Rightarrow 1 \cdot 1 \\
&= 1
\end{align*}

不得不说, 我的 编写体验十分糟糕, 以及当我想画一点拉康鬼画符时, 我的编写体验与作为正文的Markdown非常割裂的…

当然这也不是我脱更 [Partial Evaluation的坑光挖不填; 拉康精神分析只讲了最不重要的那部分…]借口 [ 哈哈, 我跑去读德古了]


一刻也没有为Markdown哀悼, 立刻来到战场的是: Typst


众所周知, Typst 既有 Markdown 的简洁, 也有 的力量(still growing), 但对我最重要的是: Typst 提供了一种一致性, 它是贯彻整个文章的书写体验的: 所见的一切都可交流.

换句话说,

它提供的是这么一种场域, 在其中无论是作为富文本的文字还是作为非文字的画图/公式, 都在 Content 之中保持着一致性, 例如, 我可以随地声明一段我将来会多次用到的片段, 并在之后甚至其他文章里随意调用.

  • Markdown + 的组合中, 世界是线性的, 但会被一段段本应被细分的公式&画图部分所分裂, 在这些裂口中, 世界被割裂成了几个无法互相交流的部分;
  • 而在 Typst 之中, 世界是树状(even 图状)的, 并且那些理应被更加细分的内容是确实被细分了的(公式&画图), 并且这些内容与其他内容仿佛本来就是一体的, 他们之间没有隔阂: 它们本就都在同一个世界中


当然, 你可能会说:
如果只用 呢?


如果你说的是它那关于书写体验上的一致性, 那 what can i say?

  • 允许你改写几乎任何层级的规则和格式, 你拥有堪称强迫症一般的排版上的绝对主权, 而代价却是复杂的语法与漫长的编译

    • 当然还有不是那么美好的错误处理系统, 我在 typsite 错误处理与恢复上也是有花了一番功夫…

总之, 贯彻着如此的宗旨: “你可以做任何事情,但你必须知道你在做什么。”

Typst 则试图在自由度 & 一致性 & 可用性 之间找到平衡点, 不能不说的是, 它确确实实地做出了很多策略性取舍, 但于此同时它获得的是 可维护性 & 稳定性, 以及高效的写作体验.

这就得吹一波我们 Typst 的实时预览了, 常规文章亚秒级预览就问你舒不舒服; 当然为了实现这一点, typsite也是从设计之初就走上了增量编译之路.

关于 Typsite 1
你可以通过 typsite c --port 8000 typsite c --port 8000 开启 watch mode, 并随着你对无论是文章还是配置的任何改动, typsite都会实时的同步并尽力做出最小量的编译.

对于我来说, Typst 所尝试寻找的这一平衡点足够平衡, 确实好用!

当然在读到这里时, 稍微混一点PL圈子的读者应该都能察觉到我这里提 Typst 是在影射些什么了…

在文章的最后我想引用一段来自 lyzh : 作为意识形态的编程语言 的片段:

引用 2

曾经追求表达力和自由(如Lisp等)失败了。

状态、副作用、协作的复杂性要求我们戴上“规则”的镣铐跳舞:类型系统、限制副作用、规范依赖。

这是一种“自由的反转”:人受限而程序得以合作。

拥有绝对的自由就是拥有绝对的不自由

或者我们可以换句话说

自由的反面不是约束,而是混乱
 关于宗教 [religion]

海涅在《论德国宗教和哲学的历史》一书中说:

『为了提出一个关于这个世外上帝的概念, 东方和西方曾用尽了稚气的比喻. 然而自然神论者的幻想在时间和空间无限上却白白地用尽了气力. 在这个问题上完全暴露了他们的无能为力, 暴露了他们的世界观, 以及关于上帝本性的观念的不足凭恃. 所以即便这种观念被打倒, 那也不会使我们感到怎么悲伤. 可是, 当康德破坏了他们关于上帝存在的证明时, 他确实使他们大为伤感. 』

……

如上所述, 我不准备对康德驳斥那些证明的议论作任何通俗性的解脱. 我只想明确地告诉你们, 自然神论自此以后在思辨理性的范围内已经死灭了. 悲痛的讣告恐怕需要几个世纪之久才能被一般人所知悉——但我们早就穿了丧服.

De profundis(从深处)!


你们以为现在我们可以回家去了吗?绝不!现在还有一出戏有待上演. 在悲剧之后要来一出笑剧. 到这里为止康德扮演了一个铁面无私的哲学家, 他袭击了天国, 杀死了天国全部守备部队, 这个世界的最高主宰未经证明便倒在血泊中了, 现在再也无所谓大慈大悲了, 无所谓天父的恩典了, 无所谓今生受苦来世善报了, 灵魂不死已经到了弥留的瞬间——发出阵阵的喘息和呻吟——而老兰培〔兰培是康德的仆人〕作为一个悲伤的旁观者, 腋下挟着他的那把伞站在一旁, 满脸淌着不安的汗水和眼泪. 于是康德就怜悯起来, 并表示, 他不仅是一个伟大的哲学家, 而且也是一个善良的人, 于是, 他考虑了一番之后, 就一半善意、一半诙谐地说:

「老兰培一定要有一个上帝, 否则这个可怜的人就不能幸福——但人生在世界上应当享有幸福——实践的理性这样说——我倒没有关系——那么实践的理性也无妨保证上帝的存在. 」

于是, 康德就根据这些推论, 在理论的理性和实践的理性之间作了区分并且用实践的理性, 就像用一根魔杖一般使得那个被理论的理性杀死了的自然神论的尸体复活了. “康德使自然神论得以复活也许不仅是为了老兰培, 而且也是为了〔对付〕警察吧?或者他当真是出于确信才这样行事吗?难道他毁灭了上帝存在的一切证明正是为了向我们指明, 如果我们关于上帝的一无所知, 这会有多么大的不便吗?

……

(《论德国宗教和哲学的历史》, 商务印书馆1974年版, 第111—113页)

 关于Typsiteinline-svg [typ-svg]

花了 1 天时间,搞定了 typsite 的 link in inline-svg, 虽然最终效果还行,
但由于typst-svg 本身对HTML的适配依然有很大的进步空间 [直接把 TAG 和 LINK 跳过了可还行],我的实现手段也非常的草台,总之在这个站点用用得了,我不是很打算将这个功能推送到 typsite 的主分支上。

1 效果预览

可以来看看效果:

效果展示

test anchor goto: goto!!!
test external link goto: Source of typsite

1Contains content of an article, will be used to generate the HTML page.

this is where the <anchor> <anchor> is

 给所有留学生的一则反诈宣导 [fraud]

我在一周前遇到了冒充公检法的诈骗,幸亏及时识破,避免了财产损失 [though 浪费了我的时间],此后得知了近期我身边竟有10位左右的朋友遇到了类似的诈骗,遂决定写下这篇短文,给所有留学生一些反诈建议。

1 牢记
  • 在海外遇到任何电话,只要不是熟人都不要去接听(诈骗份子可以伪造拨出的电话号码)
  • 有非常专业的诈骗团伙,会通过国内已经泄漏完了的个人信息(姓名、身份证号、住址、电话号码等),甚至是从你被诈骗的朋友那要求"配合调查案件"来套取你的信息,来骗取你的信任,甚至已被抓获的一些团伙中有专门的"心理咨询师"来引导你一步步上钩,所以最好的办法就是不要开始,直接挂断电话
  • 无论是任何理由,永远不要进行任何对方要求的转账操作,无论是个人账户甚至是虚拟货币(这本来就非常可疑了)
  • 对方可能在你附近的线下有帮信人员,甚至会线下给你送"公检法"的证件,甚至可能会有专门的"律师"来给你做心理辅导,目的都是为了让你放松警惕,配合他们的诈骗
  • 遇到任何情况,第一时间联系家人/老师,寻求帮助

公检法永远不会因你犯罪而主动联系身在海外的你,而是会先联系你在国内的家人,再让家人联系你。

 Minestom Journey [index]
 基础设施 [basic]

TODO

 Past Skillw [bukkit]
1 朝花夕拾 - Bukkit

我之前已经基于 Bukkit 开发过许多 Minecraft 服务器插件,它们主要都是为了 RPG 服务器而设计的,主要追求模块化和自由度。

见:Skillw

现在回看当初设计这些插件时的理念:

  • 模块化:每个功能(而非插件)都应该是一个独立的模块,可以与其他模块组合使用

    • 一致性:每个模块都应该有一个核心功能,并且这个核心功能应该是一致的且是抽象的(并非具体功能,而是实现此类功能的框架)
    • 可扩展性:应该提供统一的接口,让用户可以通过编程/脚本的方式来实现对模块的功能扩展
  • 自由度:插件的设计应该尽可能地通用,让用户可以根据自己的需求来进行配置和使用

    • 配置化:插件的功能应该尽可能地通过配置文件来实现,而不是通过代码写死
    • 脚本化:插件应该提供脚本化的能力,让用户可以通过脚本来实现对插件的功能扩展

所以首先要有一个脚本模块,提供预编译脚本与运行脚本的功能;

然后对于每个模块,尽量对其核心功能进行抽象(泛化, generalization),并且对其的使用(拓展)提供统一的两套接口:

  • 原生接口 (Java/Kotlin… 面向开发者)
  • 配置/脚本接口 (Javascript, Asahi… 面向插件用户),应该基于原生接口去实现

这两套接口必须是等价的,即通过脚本接口实现的功能必须可以通过原生接口实现,反之亦然,这样可以降低心智负担。

我认为 Skillw 全家桶 在 Bukkit 平台上很大程度上实现了上述的设计理念,而目前我想在 Minestom 上再实现一套类似的功能,鉴于 Minestom 与 Bukkit 在架构上的差异,这套理念需要进行一些调整。

2 Encore! - Minestom

事实上,我懒得再在 Minestom 上重新搭建一套 配置-脚本 的基础设施了,所以我打算只提供原生接口

对于某个功能,先实现一套抽象的核心框架模块,然后再基于这个框架模块实现具体的功能模块

例如,对于物品系统中的物品生成:

  • Bukkit - ItemSystem

    • 原生接口:BaseItemBuilder.ktItemBuilderManager.kt
    • 配置/脚本接口: ItemBuilder.kt

      • 配置示例: example.yml
        是的,这个物品的配置文件过分复杂,你需要在yaml中无语法提示地写 JavaScript, Asahi, 并在字符串中无检查地调用变量名
        这是我原理念里最大的弊病,我感觉用户先学习 Javascript/Asahi,再熟悉"配置-脚本"的框架,甚至不如直接学习 Java/Kotlin 来得更快更容易…

        • 当然,无论如何,用户们在学习过程中总会培养起来一种品性,这有助于他们在未来的编程学习中受益。

        这也是我不想再在 Minestom 上重新搭建一套 "配置-脚本" 基础设施的原因,我不想重蹈覆辙
        配置文件系统可以热重载固然是一个优势,也许我未来会开发一套仅用作调试的模块热重载系统

  • Minestom - Item 模块

    • 原生接口:仅提供基本的 ItemBuilder 接口 与 ItemBuilderManager 接口

      • 具体的物品功能模块由开发者通过实现ItemBuilder接口,自行实现具体逻辑
        你可以拥有完整的语法提示&检查,相比于配置文件,无论是自由度还是安全性都更高
3 新的根基

我需要再建一些基础设施,这是必然的,我们留到 基础设施 讨论。

 Skillw Project on Minestom [index]
 前言 [intro]

最近迷上了小时候玩过的 Cube WorldMinestom

Minestom 有着优异的性能,较 Bukkit 系列相比,它有着原生多线程的支持,且 API 设计的也非常现代化,适合用来开发较为复杂的且遵循一致性(Consistency) Minecraft 服务器。

Minestom 贯彻了抽象化的设计理念,提供了最小化的功能集,允许开发者根据自己的需求来进行扩展,相比于臃肿不堪的 Bukkit 来说,这更加轻量级和高效,也允许我们应用更加先进且符合人体工学的范式。

对于 Bukkit 到 Minestom,我的编程理念所进行的转变,我已经放到了 Past Skillw 中进行讨论。

而 Cube World 则是我童年时光的美好回忆,虽然它的游戏内容可以说非常简单并不复杂,但它的核心玩法和机制非常有趣。

于是我决定用 Minestom 来重现 Cube World 的玩法和机制,打造一个名为 Skillw 的 Minecraft 服务器。

我会在此系列文章中记录我的计划与开发过程。

 总览 [overview]
1 物品
2 技能
3 实体
4 世界