那么终于,哀歌吧!这知道是何物或者不知道的,如梦似幻的,只顾以无知的无形流散了。节气之变换,日月的旋转,无非是生成风景,将何物替代。而低头之后,难道要称之为江南?跳跃尚未站定,好似又要跳跃。从花心至花心,颤动,是悬置的期待。所衔山石生青苔?夜深沉,是非不问,万古一人。要见那不曾见过的,而此见已是见过了。有情者,唯独月影荣耀之。

毕竟有条爱河,喜将人以泪水淹没,从而重新来过。便利口舌,好似无中生有。大是大非,却非此不可?花开花谢,尽是狂喜之物事。奔流至今,洗净有形之贫瘠。悲风中的春草,囿于无言的困境,只得随着潮声闪烁。新生的云雾里,却是长命的造像藏匿。趁那日头尚不在高天,挟持光影的捕快,还有几分确信。天蓝日远,花重情深。松弛一切怨痛,长刀短,短歌长。

在故纸堆中偶然寻得了早年未竟的实验计划,代号 Story,惊觉其已然属于 Sympoesie 的精神。当时此计划已有一个 demo 公开,以 Django Web APP 的形式部署在 Red Hat 公司的 OpenShift 平台上。然而,自 2015 年以来,本站赛博架构几经变易,OpenShift 的云端服务也多次升级,当时的部署究竟没有保留下来。如今我虽仍存有当时的代码,却也难以在当前的环境下重现了。但想法很重要,故在此记录一下原理,以备日后有空重建。

得益于 Django 的工程模式,实现原理并不复杂。在数据 (model) 方面,如果以 Fragment 为基本单位,将其视为数据库中的一条记录,那么同时也应在记录中保存其上一条 Fragment 的 ID,以此形成连贯性。由此,创作者将有三种方式贡献其 Fragment:

  1. 创建一个全新的故事,即不存在上一条 Fragment 的 Fragment。1
  2. 在当前的故事末尾继续编写下一条 Fragment。
  3. 指定从某一条 Fragment 开始,重新编写其后的故事。既存的 Fragment 并不会被覆盖,而是作为另一种可能的故事线继续存在,同样接受续写的提交。

于是,一个故事连同其所有的可能性,将形成一个多叉的大型树状结构。2

难点其实在于数据的展示 (view)。按顺序将 Fragment 逐一展示并提供分支导航固然是不够的,必须有一套特殊的推荐算法来评估故事树中特定故事线的价值,选择最合适的 Fragment 及其所在的故事线优先展示给读者。同时也要便于读者在不同的可能性之间跳转。由于算法能力的缺失,我当时仅实现了三种推荐方式:最新作品百条、最热作品百条(以点赞数计)以及最具潜力作品(最新作品中点赞达到一定数量的)。虽然简陋,姑且能用。

可以看出,这个 demo 的功能是基本完整的。造成此计划不了了之的重要原因之一,正如许多其他的项目,无非是没人来 syn-。可见 Sympoesie 本身是一个具有极高门槛的活动,人类历史上任何一次实现都可称之为奇迹。


  1. 原则上这是可能的,但当时为求逻辑简便,实际上预先设定了唯一的一条全新 Fragment,因此只存在唯一的一个故事树。
  2. 当然,这种结构也存在着缺点。例如无法事后单独修改位于中部的某一 Fragment,因其可能会影响此后的其他分支。固然可以将之后的分支故事树另行复制,或者将每个记录的追溯做成双向的,但如此一来复杂度就上升太多,既不美观又不便利,总之我是不情愿的。

哦我跳跃着
日光雨下
林木开出道来

黄金的风知晓
千山万里的冷却
无穷迷路世界

火车不曾减速
飞越故事外

你从不赞美汽水的多余
只因夏日水汽一层
许诺空中的亭台

崇祯三百九十六年
六月七日的上午
冻结的澄清海

旅人旧背包
纷失终焉ニ在リテ

电光精微
波形浓郁
疑怒一层飞出去
气化长风
削字如泥
迷魂万卷仍破击

为颂长生曲
今持血肉身
人间多逸散
共感作星辰

余音打上天巡海
遍落真珠
忆得南柯入世来