云烟记事录

少主小册


  • 首页

  • 归档

知识的形状

发表于 2018-08-28 | 分类于 浮生若梦

去年的某一天, 我与父亲在景阳的家里有过一次争吵,
景阳是一个非常漂亮的地方, 青山流水, 令人安详,
那一次的争吵却非常激烈, 令人映像深刻.

有趣的是我们争吵的并不是某个具体的问题, 反倒是一些思想上的碰撞. 争吵的最初, 是我们在讨论易经与算命的可信度.

父亲是算学大师, 而当时的我刚读完一本书叫<上帝掷骰子么>,
里面写了现代物理的一些历史,
对于里面物理学旧秩序的崩塌和新秩序的建立当时非常的震撼,
所以我就一直在追问父亲算学的源头理论在哪里,
比如欧几里得几何建立在五大公理, 在这个公理下, 理论是正确的,
之后第五个被推翻, 就出现了其它的几何学说.
那么算学的源头在哪里呢?
国学神奇的命运说法建立在什么基础假设之上呢?
最后引到易经上, 引到五行学说, 于是当时的我就草率的下了结论,
并且试图说服我的父亲, 算学只是一种近似的概率模型,
在最初的公理不成立的情况下, 总结出的一套预测算法,
也许是真实世界函数在某个条件下的泰勒展开.

我和父亲脾气都不好, 最初的争论开始慢慢跑题,
然后衍生到了更大的话题, 就是对待知识的看法:
我认为对一切的知识都应该持怀疑的态度,
所以论证的终点不应该是”古人云, 圣人云”,
即便是圣人所言, 也未必全对,
我认为知识无非是约定或者是解释,
对于约定性的知识, 是一个共识的体现,
而对于解释性的东西,
则需要不停的去挑战与解读, 必须要了解最初的假设.
而在这个过程中, 父亲认为我对知识没有敬畏,
对圣人没有足够的尊敬, 用成语形容, 就是自以为是, 狂妄无知.
我认为父亲迂腐不化, 对知识不求甚解.

这次争吵在母亲的介入下最后不了了之,
我和父亲谁都没有说服谁, 后来就慢慢淡化了.

今天早上上班, 天气很好, 但是我觉得有些困, 就没有看书选择了听书,
一路上昏昏欲睡, 直到听到一本书叫做<知识的边界>,
里面描述了互联网时代的知识承载和以往的不同,
其中提到了一个很有意思的词叫做知识的形状,
书中说互联网时代的知识的形状是网状的,
而纸质书时代的知识的形状是线性的.

受限于纸张和印刷的成本,
以往的时代知识或者说信息被传播开是会经过比较强的过滤的,
而互联网时代由于传播成本的低下, 信息开始被大量传播, 过滤失效,
你再也无法找到权威了, 因为无论你笃信哪个说法,
都不乏大量的对立说法的支持者,
而对立这里面也不缺乏传统意义上的权威.

于是我想起了那次和父亲的争吵,
突然明白了其实这只是两个时代的人在自己所处的环境中所积累的学习方法和理念的碰撞,
我并没有对知识的藐视, 只是这个时代所处,
一切的信息来源都要求我学会自己的过滤方法,
而我的过滤方法就是溯源, 于是我养成了自己的世界观和方法论,
我对一切的知识理论都要求溯源.
而父亲所处的年代杂乱的信息要少太多,
大量有效的知识累积直接接受显然是更高效的方法,
而且当时的溯源成本过高, 父亲也有自己的方法论与世界观,
当两个不同时代的产物聚合在一起, 自然就有了碰撞和摩擦.

更深一步, 我终于理解了为什么我一直在跟我的长辈们说不要轻信各种养生专家,
不要亲信朋友圈各种不靠谱的传言而他们还是孜孜不倦的看得很开心或者还要转发,
那是因为我的世界观决定了信息进来之后先是不可信的,
而他们的世界观则告诉他们信息先是可信的.

世界的变化真的很奇妙, 传播方式的改变最后改变了人们对信息的处理方式.

我期待着知识变成其它形状的那一天

画中人设计的关键点

发表于 2018-07-15 | 分类于 抛砖引玉

画中人设计的关键点在于规则驱动, 区别于之前的 rpg 人为设定任务,
新的设计方案需要规则驱动, 因此从玩家的角度来看 Hero 和其他 NPC 并无区别.
根据时钟, 画中人的世界应该隔一段时间就触发一次随机事件,
玩家和每个 NPC 都会为此事件作出选择从而改变下一次随机事件产生的条件.
随机事件是由先决条件和骰子来决定的.

同时由于玩家可以有目的地自己触发事件(比如交谈, 战斗, 做任务),
NPC 也应该随着时间间隔做出相应抉择, 不过是以事件的形式,
此处 NPC 的抉择应该是 AI 算法, 早期版本可以通过简单的决策树来实现.

若 NPC 与 HERO 处于同一张地图, 则 AI 的决策将滞后,
等 HERO 离开地图之后下一次决策会执行多次, 用来修改 NPC 的数值

游戏的事件结构应该设计如下:

触发条件 -> 触发主体 -> 抉择 -> 影响

其中触发条件是一系列游戏类的环境变量, 影响也是这样

在画中人的世界中, 应该存在个体本身的变量和游戏中的环境变量, 具体数值还需要细想

画中人代码结构思路

发表于 2018-07-15 | 分类于 抛砖引玉

最近对画中人的玩法设计基本上有了总体思路, 细节还在完善, 主要工作量目前是三个:

* 数值的完善
* 数值填充工具的完善
* 部分新系统的添加(随机事件)

由于对于游戏玩法本身我并不想完全抄一个已有的游戏,
所以在可预见的未来画中人的规则会有需要更改的地方, 在现有的代码框架中,
修改的代价不小, 因为我们的规则逻辑分散在各个模块中, 每次修改都可能引入新的bug.
因此我决定重构.

根据现在的需求, 我需要有一个可以很方便操作各种内部数据的工具,
方便我来调整游戏性,同时我需要系统的规则是可插拔的, 最好规则的插拔的地方很统一.

所以新的系统架构应该从 oo 转换为数据流.

采用 proto 作为中间数据定义, 系统被分为 ui, data, logic 三层,
其中 ui 负责在每一帧读取 data 并展示(当然有脏数据的设计),
同时 ui 会发出 event, logic 层接收到 event, 遍历现有规则, 修改 data.
data 层由 proto 定义.

数值工具则是 proto 中 message 的可视化定义
存档工具则是 proto 的 二进制序列化和加密

以太坊, 不仅仅是数据

发表于 2018-06-24 | 分类于 抛砖引玉

上一篇我们介绍了比特币, 比特币事实上是以区块链作为分布式账本, 以共识为基础,
UTXO 为记录数据的一种区块链应用.

那么区块链的应用是否到此为止了呢? 当然不是, 否则我也不会写这篇文章了.

如果比特币在链上记录的, 不仅仅是可以被查询的数据, 而是一个可以被执行的程序呢?

想象一下我们最早举的那个本子的例子, 假设, 我们的本子一分为二, 还是区块链的概念,
所以每个人都有这个本子, 每个人的本子也能达成共识来同步更新, 我们约定:

1. 上半个本子记录一件做事情的方法: 事件名 -> 方法
2. 下半个本子记录某人要做什么事情, 并且会扣掉某人一部分钱
3. 拥有这个本子的人, 看到这件事情了, 就会去做, 做完之后通过我们之前说的共识的方法, 把结果写在本子上
4. 写上结果的人会得到一笔钱

在这样的约定下面, 我们发现可以做更多的事情了, 我们只要事先放一个方法在区块链上,
之后每次就可以使用这个方法来做某些事情, 总会有一个人帮我们做完想做的事情.
因为有钱赚嘛, 人家做事情也有动力.

这个就是以太坊.

事实上在比特币里面就提出了这个智能合约的概念, 但是比特币的内置脚本不是图灵完备的(这是什么意思请自行百度).
以太坊是第一个给出了图灵完备实现的区块链产品, 也真正意义上的实现智能合约.

和比特币一样, 以太坊目前的共识机制, 也是一种竞争机制, 所以比特币有的问题, 以太坊也会存在,
比如挖矿的资源浪费, 比如能被确认的交易量(写上本子的速度)始终上不去.

但是以太坊的出现, 的确给我们了一个新的思路, 那就是区块链到底能做什么?

我们本来以为区块链是一种数据组织方式, 现在看来远远不是这个意思了.

在现在的互联网架构中, 我们看到的组织方式是什么? 客户端服务器模式.

客户端提出请求, 服务器端给出响应.

而在区块链的架构下, 我们发现我们提出一个请求, 不知道谁会给我响应, 但是总会有人给我响应.

在互联网模式下, 每次使用服务的稳定性是由公司来保障的, 在区块链模式下, 是所有人来保障的.

在互联网模式下, 我们要为服务收费, 需要有一套额外的收费体系, 比如支付宝或者是微信, 或者是别的充值系统.

在区块链模式下, 我们每个人都是链上的会员, 想要做什么事情, 先存一笔钱在链上, 自动扣款.

如果当年的百度是在区块链上做起来的, 厂长大概不会经历那段殚精竭虑思索盈利模式的时光(笑).

于是从第一篇到现在, 我们看到了为什么之前很多币圈大佬会说区块链是下一代互联网,
因为从底层架构来说, 区块链虽然目前还有很多问题, 但是不能否认他有可能以另一种形式为用户来提供服务.

在我看来, 区块链从技术的角度事实上是一种加入了激励机制的分布式服务化的观念.

就像处在中世纪的我们无法理解跑得比马车慢的蒸汽机车以后会是怎样的革命,
在提出光的波粒二象性之前我们假设了以太, 区块链究竟是蒸汽机车还是以太目前我们无法得知,
让我们拭目以待吧.

PS: 下一篇文章可能先不写区块链, 不过区块链系列的下一篇应该会聊一聊区块链和金融的关系, 也就是大家最关心的炒币是什么

比特币-区块链的第一个应用

发表于 2018-06-19 | 分类于 抛砖引玉

接着上一篇来, 上一篇说到了区块链的数据组织方式, 我们来复习一下:

  1. 可以被追溯
  2. 不能被修改
  3. 被加密
  4. 但是这里面有一个问题.

我上文举了一个纸上写诗的例子, 假如我们给这个本子起个名字叫 <学诗记事>,

如果有且仅有你一个人你一个人能看到这个<学诗记事>, 那么这种数据组织方式就没有任何意义. 因为你完全可以做一个新的本子, 然后就非说它叫 <学诗记事>, 反正也没有人反对.

只有当你的<学诗记事>被很多人看多, 而且大家都记得, 你修改之后别人不认, 当有两个以上的人不认的时候, 你的修改的东西就不能叫 <学诗记事> 了.

所以上面说了一大堆, 其实就是两个点:

分布式
共识

分布式的意思呢就是这个事情你不能一个人玩, 得有人陪你玩, 你不能自high.
共识的意思呢是既然大家陪你玩, 那大家就都要有说话的权利, 不能你一个人说了算, 只有大家都承认了, 才是真的.

那么现在的情况是什么呢? 区块链在这个机制下, 变成什么样子了呢?

  1. 所有人都有了一个副本
  2. 大家都认可这个副本
  3. 副本永远一样
  4. 如果要修改(增加)这个副本, 那要所有人都同意.

于是, 我们区块链的第一个应用比特币就天然的产生了.

什么是比特币呢?

比特币是基于区块链的一种加密货币.

按照我们上面区块链该有的样子, 我们把 <学诗记事> 变成账本, 就成了比特币天然的原型了,

为什么这么说呢? 让我们来分阶段看一下货币的发展:

  1. 以物易物 — 不方便, 不好定价, 身份可以隐匿

  2. 实物货币 — 可以定价了, 不方便, 身份可以隐匿, 需要大家都认可

  3. 纸币货币 — 可以定价, 方便, 可能掉, 要信赖发币的机构, 身份可以隐匿, 有可能通货膨胀

  4. 电子货币 — 可以定价, 方便, 不会掉, 身份基本不可能隐匿了, 要信赖发币的机构, 有可能通货膨胀

可以看到这四个阶段, 我们每次都在解决问题的同时引入了新的问题.

我们越来越方便, 但是安全性越来依赖于中心化机构.

我们需要有一个绝对信赖的人(组织), 来背书. 比如银行, 比如支付宝. 比如微信.

绝对信赖这件事情是很难的, 08年的时候, 出现了一个化名叫中本聪的人说, 我们可以有一种机制, 让中心化机构不存在, 参与者自己天然就能保障信任. 这就是比特币的由来.

那么我们来看中心化机构在货币体系里面担任了什么角色呢?

记账, 大家个人有多少钱, 在电子货币阶段, 是在中心化机构里面有个账本, 记录了你的余额, 交易则修余额.

发行, 市场上流通的钱币总共有多少, 是由中心化机构来做的

所以比特币既然想要去掉这个中心化的机构, 那么他就必须解决这两个问题.

首先解决记账的问题, 按照我们之前的说法, 区块链里面的数据变成账本, 每个人都存有副本, 只要能达成记账的共识, 那我们就做到了记账.

在我们日常的生活当中, 一般交易系统是基于账户的设计.

这是什么意思呢?

就是说你的账号 + 余额, 就是被存下来最终的数据.

你要查你的账户, 只要能验明你的身份, 就能查到你的余额.

那么基于账户的设计在区块链这边有什么问题呢?

让我们回忆一下我们之前的说法, 区块链里面的数据是不让改的, 否则链就坏掉了.

也就是说想象一下我们每个人都愿意用比特币,

手上都有一个神奇的纸质账本, 这个账本只能增加不能修改, 他会不停地试图和边上的账本同步, 保持一致.

如果是账户设计, 那这个账本上原有账户的值不能修改, 那就只能加一条新的数据, 也就是账号 + 余额, 我们查看的时候以最新的为准.

那么在这种设计下, 我们看看会有什么现状呢?

  1. 原来的大部分数据都没有用, 因为以最新的为准

  2. 我也不知道这个人的钱是怎么来的, 除非有第三方来检验交易, 那第三方又涉及到信任问题.

所以, 中本聪提出了UTXO的解决方案, 这里我不再进行计算机学上的证明与推导, 感兴趣的朋友请自行查阅, 有很专业的文章在解释, 我只说直观的说法.

UTXO的解决方案简单点说, 就是我们记录交易, 不记录余额, 每一笔, 记录的都是张三给了李四多少钱. 你想要余额, 没问题, 算. 当然为了快速运算, 区块链的程序里面会用数据库和缓存来解决速度的问题, 这里主要探究基本原理和最终数据, 毕竟为了加快的东西都不是最后数据的依据.

所以现在我们的比特币就变成了这个样子:

  1. 他是一个区块链, 每个人参与的人都要拥有一个相同的账本

  2. 账本上记录的是每个人的交易信息, 也就是说每个人的交易记录事实上是公开的.

那么在使用比特币发起一笔交易是怎样的呢?

这里面我们会遇到一个巨大的坑, 就是日常生活中我们的账号是怎么玩转的.

在电子支付时代, 和纸币交易不一样, 我们需要确定一个人的身份才能进行交易.

那大家相信平时也用的多, 就是账号密码嘛.

那岂不是区块链里面还要存储我们所有人的账号密码? 那不是很不安全?

当然不是啦, 这里面就要说到区块链另一个很有意义的设计了, 就是密码学的消息加密设计, 非对称加密. 还是一样, 详细原理请自行查阅技术文档…. 我这里简单描述.

你可以这么想像: 区块链里面能拿到你的账号的一把钥匙, 也就是说你的账号的消息, 他就会试图用这把钥匙打开, 打得开, 他就认.

那你这边有啥呢? 你有做锁的方法, 这个钥匙和做锁的方法在你生成账号生成好, 然后你把做锁的手艺拿走了, 每次发消息, 就用这个手艺做一把锁, 锁住, 所以别人不知道你做锁的手艺, 就没法操作你的账号. 当然你要是忘记了做锁的手艺, 那就等于你这个账户没人能操作了, 你的钱也就没了.

在这个设计下, 我们的交易就变得简单了, 我们只要发一条消息给所有人,

说 我大白给二狗子发了100个比特币, 之前的来源是三胖给我的, 交易号是多少, 如果所有人的账本上都出现了这个消息, 那么我们就交易成功了.(真实情况不会这么苛刻, 但是你可以这么理解)

你看, 我们不需要第三方来检验钱是怎么来的, 因为我们每个人都可以一直翻书看直到最源头.

我们也能算出一个人的账号里面还有多少钱, 因为我们拿过来所有的交易数据加减就好了.

到目前为止, 除了怎么写进这个账本, 我们已经解决了大部分交易和记账的问题.

那么接下来, 就是发币和写进去的问题了.

我们在解决共识的问题. 换句话说, 我们写了一笔交易, 想要所有人都认, 怎么办呢?

在中本聪的设计里面, 他选择相信力量强大的.

也就是说, 对于这个账本啊, 所有人都可以写, 但是最后所有人的账本应该一样, 所以只能听一个人的, 那听谁的呢? 听那个最能写的, 所有人都在竞争写, 听最先写出来的.

那这里就有一个问题啊, 就是记账这件事情太简单了, 谁不会写啊, 我可能写的速度还不如我告诉别人我写完的速度快呢! 所以中本聪说, 那大家写的时候就变态一点吧, 我给你们加难度,

你随便写的不算, 得用系统随机给你的一个命题来作文一篇先. 系统觉得你这篇文章不错, 你接来下写的数据才算.(这里的真实算法不是这样啊… 这是一个形象的比喻)

那能率先写出文章的人, 必然能力最强啊, 那他就是可信的.

好, 到目前为止, 我们解决了记账的问题, 听能力大的人, 大家都听他的.

这时候能力大的人, 我们简称大先生吧, 大先生说话了: 我去你的吧, 我花这么大代价为你们做牛做马, 有啥好处啊? 你还故意加大难度?

所以中本聪说, 别急, 你要是能成功写一页账本呢? 我就允许你写一笔交易是系统给你发点钱, 你看你还有得赚.

这就是比特币给出的发币的方法, 记录一个区块链的人可以获得系统产生的比特币, 除此之外没有其它途径了.

当然比特币为了避免无限发币, 设计了一个思路是记账所得的系统比特币会越来越少, 到最后就没有了, 这时候比特币的总数就固定了, 当然这时候如果还想要人记账, 就只能通过手续费的手段来刺激了.

上面我们说的记账, 就是大家听得很多的挖矿.

到目前为止, 我们基本上把比特币一些概念上的设计都说完了.

我们来看看比特币的优缺点吧,

先说缺点, 在我看来, 有以下几点:

  1. 区块链的定义可以看到, 要大家陪你玩, 参与人越多就越可信, 价值就越稳定
  2. 因为它去中心化了, 和纸币时代一样, 存在了掉钱的可能性, 而在目前阶段, 一个中心化机构的倒闭的概率远远小于你自己忘记信息的概率, 所以事实上对于每个人来说是风险增加了
  3. 比特币本身设计的共识算法, 为了证明能力大小(写文章), 要耗费大量的计算力, 这是一种极大的浪费.
  4. 如果将来有一个机构, 能够拥有这个世界上51%的能力(算力), 那他就是神, 随意修改所有的账号交易, 此时比特币生态就会崩塌, 这也是著名的51%攻击.
  5. 比特币是分布式的, 也就是要求所有参与者都拥有全数据(实现上会有差别, 但概念是这样), 而且数据不会删除, 所以数据会越来越多, 形象点说就是每个人手上的账本会越来越厚, 而且大部分都跟自己没关系

再说优点, 在我看来, 有以下两点:

  1. 它真的去中心化了, 人类历史上第一次真的靠所有人投票完成了信任, 而且是利益相关
  2. 它不会通货膨胀

今天粗劣的介绍了比特币, 不知道大家有没有什么不理解或者认为我说错的地方呢? 请大家指出.

对了, 插一句题外话, 现在比特币是暗网的唯一交易货币, 有朋友说还有少量XMR不过我没找到.

比特币介绍到这里, 它仅仅是区块链的第一个应用, 在我们昨天的数据组织方式里面, 它把数据当做了账本. 如果我们更进一步, 区块链技术是不是会有新的惊喜呢?

敬请期待下一篇<以太坊, 不仅仅是数据>.

谢谢大家阅读

区块链初探

发表于 2018-06-18 | 分类于 抛砖引玉

大家好, 因为工作的原因, 最近在研究区块链,
理解需要交流才能透彻, 于是计划写这么一个系列, 来和大家交流交流我对区块链的理解.

那么什么是区块链呢?
按照维基百科上的定义, 是一系列使用密码学保护的持续增长的被链接起来的区块, 区块指的是一个信息列表.

这个定义读起来有点复杂, 我来翻译一下:

如果你有一页纸, 上面记录了一条条的数据(你写的诗啊, 你记的账啊), 这个就是区块链里面的区块.

你用了一种方法把这些记录写成了密文, 只有你读得懂, (比如爸爸叫阿玛, 哥哥叫欧巴) 这叫密码学保护

把好多页纸首尾用胶水粘起来, 这是链.

在区块链的技术中, 每一个区块都要求保留上一个区块的信息, 换句话说, 每一页纸都会写上上一页纸的简介, 这样每一页纸以及连接顺序都是不可修改的. 这里给个例子:

  • 纸一: 上一页纸: 无 记录: 上穷碧落下黄泉, 两处茫茫皆不见
  • 纸二: 上一页纸: 纸1, 长恨歌, 无 记录: 如今俱是异乡人, 相见更无因
  • 纸三: 上一页纸: 纸2, 韦庄, 纸1, 长恨歌 记录: 十年生死两茫茫
  • …..

这里面任一一张纸的改动, 都会导致后面的纸记录跟不上, 那么就可以认为这个链坏掉了.

当然在真正的实现里面, 利用hash算法, 把上一页纸的信息变成了一个固定长度的字符串, 不会像例子里面这样记录.

好的, 到目前为止, 我们可以看到区块链事实上就是一个数据的组织方式, 特点是三个:

  1. 可以被追溯

  2. 不能被修改

  3. 被加密

那么区块链有什么用呢? 区块链真的仅仅就是这样的数据组织方式吗?

让我们在下一篇文章里面来探讨.

预测一下这个系列的下两篇文章应该是:

<比特币, 区块链的第一个种应用>

<以太坊, 不仅仅是数据>

写得不好, 请大家多多指教, PS: 写这篇文章的还有一个目的是希望我的不是学金融或者IT的朋友能够看懂区块链, 所以如果写的哪里不够通俗易懂, 还请大家指出~~

我的游戏梦

发表于 2018-05-04 | 分类于 浮生若梦

最近生活事业经受诸多变故, 三年的创业团队散伙, 职业生涯大倒退,
既然认清现实, 就突然想找个地方来说说我的游戏梦.

创业三年, 每逢试图融资, 总会有人问你为什么要做这款游戏?
你的玩家群体有多大?
你的商业模式是什么?
从最早的毫无意识, 到最终的小心经营与酝酿.

既然现在不再试图融资, 我终于可以大声的说出来了:

我为什么要做这款游戏?
因为我爱我自己国家的文化啊!
因为眼见得这么多牛逼的人, 牛逼的团队, 被现实压得不得不没有情怀, 我不甘心啊!

我的玩家群体有多大?
我们能做多好, 玩家群体就有多大!

商业模式是什么?
商业模式是我们做一点有趣的东西, 大家付一些心甘情愿的钱, 我不想要赌博, 不想要仇恨与攀比!

好了我知道这是梦, 这是我的梦, 可惜的是让几个兄弟陪我为这个梦买了单.

做梦完毕.

我始终坚信, 有一天, 游戏会成为真正的艺术品,
它能承载除了廉价娱乐以外的价值,
无论是历史还是教育, 只是也许真的需要更多破碎的梦想来奠基.

画中人转为了兼职制作, 可是它也是我的梦,
无论如何, 也会更新下去, 直到它成为一个成品, 哪怕很慢, 哪怕很难, 也不会间断….

云烟记事录序

发表于 2014-09-04 | 分类于 浮生若梦

很早之前就想写这么一个系列了,虽是个粗人,却对些舞文弄墨的事 有些向往的。总觉人生百岁,听闻甚多,电影小说,也无非是他人的杂事,
作者殚精竭虑,试图写出些与众不同,
跌宕起伏,写下的也不过是身边之人,所见所闻而已,
茕茕孑立,亦或是神采飞扬,都只是自己心境的某个快照。
局限于此,却也是我的真诚。

人生不过数十载,历经之事却不能算少,
最近听闻了经历了很多事,想说的时候却不知道从何说起,
化为文字却是更好地宣泄或是回忆,于是就有了接下来的这个系列。

这个系列大概是要叫《云烟记事录》,所记之事,皆非真实,是以叫做云烟。

取云烟缭绕,非真非幻之意为其一。
世事纷杂,过眼云烟之意为其二。

与君共勉。

RQuery-分布式 R

发表于 2014-08-27 | 分类于 抛砖引玉

工作需要,组里设计了一个叫 RQuery 的分布式 R 环境。

我们都知道 R 是一门强大的数据处理语言(或者叫做数据处理工具更合适),
R 有一些很强大的特性,比如 R 中可以很方便的插入 sql,
执行 sql 查询之后得到 data.frame,
然后利用 R 本身强大的库函数去做各种各样的运算。

然而强大的 R 有一个限制,那就是它事实上是单机的程序,
当你有一堆巨大无比的数据集,比如好几百T甚至上P的时候,
单机的 R 就无法用来做数据分析了,
业界事实上有很多分布式的系统来做数据分析比如 Storm,Pig。
然而对于一个传统的数据分析人员来说,
在思考数据本身的同时还要去理解分布式的算法是一件很麻烦的事,
而且这些系统也没有直接支持 R,matlab 这样高级的适合于数据分析人员使用的工具。
在这样的背景下,RQuery 产生了。

RQuery 在设计上尽可能的屏蔽了分布式相关的东西,使得 api 和 R 原生的 api 相近。
举个例子:

read_table.Rview raw
1
2
3
4
5
data <- read.table("Sample.txt")

new_data <- lapply(data, function(x) x + 1)

summary(new_data)

上面的代码是在 R 中去 read 一个本地的 text 文件,并且进行了一系列操作,

read_dtable.Rview raw
1
2
3
4
5
6
7
data <- dtable("Sample")

new_data <- lapply(data, function(x) x + 1)

new_data_local <- take(new_data, 1000)

summary(new_data_local)

这里面,Sample 是事先在 meta 中建好一张表,
对应的是存在分布式文件系统上的一堆文件。

可以看到上下的 R 代码写起来差距很小。这样就给传统的数据分析人员极大的便利。
再举一个 kmeans 的例子:

kmeans_r.Rview raw
1
2
3
4
5
6
7
8
9
data <- read.table("Sample.txt")

new_data <- lapply(data, function(x) x + 1)

kc <- kmeans(new_data, 3L)

kc$cluster

kc$centers
kmeans_dr.Rview raw
1
2
3
4
5
6
7
8
9
data <- load.table("Sample")

new_data <- lapply(data, function(x) x + 1)

kc <- rquery.kmeans(new_data, 3L)

collect(kc$cluster)

kc$centers

可以看到用法基本一致。

RQuery 抽象出了一个数据结构叫做 dtable,并且提供了如下 API:

1
2
3
4
5
6
select(dt, expr)  # 类似于 sql 中的 select
where(dt, expr) # 类似于 sql 中的 where
count(dt) # dt 中的行数
take(dt, 10) # 取 dt 中的前10行
collect(dt) # 将 dt 中的数据拿到本地
takeSample(dt) # 从 dt 中采样并拿到本地

然后我们目前提供了四个 api,供用户在 dtable 上做分布式的算法操作,
之后会给出更多地算法 api:

1
2
3
4
dtable(name)  # 创建一个 dtable
rquery(sql) # 执行一条 sql 语句
rquery.collect(sql) # 执行一条 sql 语句
rquery.kmeans(dt, k) # 执行 kmeans 算法

当然,目前来说 RQuery 还很不成熟,缺失了诸多的 api,
虽然可以方便的在分布式和本地切换,但是 dtable 还有很多操作不能直接进行,
需要一步转换,后续会支持更多地 R 本地的 api,提供机器学习十大经典算法,
让在分布式上执行 R 运算和在本地一样便捷!

雪球快跑--设计与思考

发表于 2014-08-24 | 分类于 抛砖引玉

好久好久没有写文章了,就像我之前说的,我实在是太懒了。

前不久写了个游戏,叫雪球快跑,andorid,ios都已经上架,搜就能搜到。
毕竟是第一次写真正上架了的游戏,还是有很多感触的,会一一写成文章记录下来。
这一篇,就从设计开始吧。

从大学开始,提到设计,想到的就是OO,那么究竟什么是OO呢?
面向对象这个词语实在是用得太多了,关联的东西也很多,无非第一下想到的就是继承,
多态什么的一堆词语。对于面向对象,我的理解其本质是数据和行为的聚合,
其它都是这个衍生出来的。因此,我去思考设计,其实无非就是如何去组织数据和行为,
数据和行为聚合在一起的,是面向对象,分离的则不是。当然在实际实现中,
这个的界限是很难区分清楚的,设计本来就是一个糊涂事…
很难去给出一个清晰的定义或者准则,所以,如果我继续这么玩概念虚下去,
那这篇文章也就没有存在的理由了,下面,
我会从《雪球快跑》这个游戏的具体设计开始说起,
这个设计未必好,但是是我自己的一种思路。

首先介绍一下雪球快跑这个游戏吧,(ps:有兴趣的可以去玩玩,能不能玩到100分)。

雪球快跑是一个冒险跑酷类的游戏,玩家通过点击屏幕操控重力,
雪球会根据重力来上下掉落,在地面上面的长时间滚动会导致雪球增大,
玩家需要控制重力来让雪球躲过黑洞,闪电,陨石等障碍物。
游戏本身很简单了,元素也不多,操作也简单,那么,我们如何去划分它会比较合理呢?

天下所有的设计者都其实是在寻求一个设计来说服自己,让自己安心。
大部分之前精心设计考虑了大量情况的扩展都没有用,最后被重构了,
可是在设计的时候还是会纠结来纠结去,期待给出一个完美的答案,
不幸的是我就是这样的性格,于是在设计雪球快跑的时候,考虑了各种扩展的问题,
当然到最后也没有精力去具体实现,设计过程的本身,也是一种乐趣。

这个游戏的设计和实现都是基于 cocos2dx 这个游戏框架的,对于 cocos2dx 这个框架,
我就不在这篇文章里面详细介绍了,简单地说一些概念,
Sprite 可以认为是绘制在屏幕上的实体,Layer 来承载 Sprite,Scene 来组织 Layer。
后面的设计会经常提及这几个玩意,因此,如果完全不知道我在说什么的,
建议先去了解一下 cocos2dx 这个框架。事实上这几个抽象是游戏设计的一种通用抽象,
聚集了无数前人的智慧。

正式切入主题吧。
这个游戏看上去简单,可是第一次设计的时候,会发现其实挺复杂的。
比如说,当雪球碰到各种障碍物之后的表现,就有好多种,
又比如雪球虽然看上去在动,但是当雪球到了某个位置之后实际上就不动了,
也就是说事实上这时候是背景在动,又比如障碍物是随机生成的,
那么障碍物出现的策略是什么,如何保证雪球一定能过?
重力反转之后,雪球需要有坠落效果,遇到上下的地面都要停止坠落。
雪球方向反转之后滚动的方向也需要变化,等等。
这么多复杂的特性,会让人有种无从下手的感觉。

游戏和我工作从事的后端服务器类的程序有一点很大的区别,在于游戏是有屏幕显示的,
复杂的显示效果和后端逻辑结合起来,会扰乱人的思维。
因此,我们不妨将整个游戏分为两个部分,一部分为展示,一部分为逻辑处理。
定义一个中间的结构,展示的时候仅仅是读取这个中间结构的值去绘图展示,
逻辑处理仅仅是改变这个中间结构的值,这样就将展示和逻辑处理分离开了。
可能这么说有点抽象,我举个例子吧,比如我们有一个逻辑是,球遇到黑洞会被吸进去。
那么按照不分开的写法,代码(伪代码)应该是:

if ball.contact_with(black_hole) then ball.die and screen.show_ball_sucked()

而按照分离的写法则应该是:

if ball.contact_with(black_hold) then ball.die and ball.status = sucked

然后再绘图的代码位置:

if ball.status == sucked then screen.show_ball_sucked()

似乎看上去代码变多了, 但是第二种写法的好处在于,我们把逻辑分离了,
当思考球撞到黑洞的时候,我们想的是求被黑洞吸进去了,
那至于吸进去的时候有没有旋转,有没有变小,我不管。
然后在写绘图的时候,则是,如果球现在的状态是被吸进去,那么我们就吸进去吧。
我才不管他为啥被吸进去。

有了上面的这个认知,接下来的设计会轻松很多。
这是一个跑酷类的游戏,这类游戏有一个特点,除非游戏结束,
否则游戏是一直自己往前推进的,而不是玩家来控制进度。
类比一下,其实这类游戏和电影没啥两样,剧情在不停的往前发展,
玩家最多就是一个厉害一点的观众,时不时能稍微影响下剧情。

于是,我们就可以建立这样一个模型,首先有个游戏的主体,自己在不停的演进,
比如球在自己滚啊,受重力的影响啊,镜头在不停的跟踪球啊,
球在看是不是和障碍物撞了啊,等等。接着是交互系统,
也就是说玩家可以通过点击屏幕去改变球的参数,但是这个改变实际上是延迟的,
也就是说,玩家的点击仅仅就是改变了一个值而已,真正起作用,
还是游戏自我演化的时候起作用。
然后就是我们上面提到过的那个显示模块,会不停的读取主体的数据去刷新屏幕。

这样我们游戏的大体模型就出来了,我们来具体看看主体部分应该怎么设计。
首先,会有一个 World 这样一个类,它扮演着总体容器的这样一个角色。
所有的游戏中的实体,可见或者不可见的,我们都可以抽象出一个父类叫 Entity。
比如 Ball,BlackHole,Meteor,LightingBall ,Ground,
Background 都是 Entity 的特化,这样所有的 Entity 的生命周期都由 World 去掌控了。
这样我们只要去分别实现各个类,发现这个游戏就完了。。。真的是这样么?

。。。当然不是了。。。不然我还写个啥?这时候球还只能够一个劲地往前滚,
一会儿就滚出屏幕了,而且那些障碍物的分布是怎样呢?换句话说,地图是怎么出来的呢?
于是,我们势必要抽象一个 camera 来跟踪球的位置,让球始终在左边 1/3 的地方。
记得之前我反复强调的显示和逻辑分离么?这里就是最好的应用场景了,
想象一下你的逻辑里面不是球在往前滚而是背景在回退吧,
各种变速碰撞上下,是不是整个人都不好了?还好我们将这两部分逻辑抽开了,
球还是往前滚吧,camera 跟着滚就是了。

好吧,还剩一个麻烦事,地图怎么玩呢?抽象一个 Loader 对象来做这件事吧,
现在是随机地图,于是用一个随机序列就可以了,若是之后要使用手动写地图,
那换个 loader 就好了,当然,
这里面用到了一些算法来保证障碍物出现的合理性,这篇文章谈设计,不说那些。

好,到这里为止,雏形出来了,可是马上就能发现,World 这个类,做的事情太多了吧:
又要去管理 Entity 的生命周期,又要去驱动 camera 跟踪球,
又要去看球和障碍物们是不是碰撞了,还要调用 Loader 去拿接下来的地图。
这哪吃得消啊,抽出一个 logic 的类来做点事情吧,
World 老老实实管理生命周期就行了,甚至都不需要去理解 Entity 是什么,
至于后面的玩法改变,比如加了个球什么的,替换 logic 吧。

到此为止,雪球快跑的初步架构是已经出来了,扩展性还是不错的,
很容易添加和删除东西。但是,如果就这么写着,各个模块并行,
你依然会发现逻辑不好描述,比如说重力改变了,而你的球正往前滚得欢呢,
你怎么去影响他呢?

这里又说到游戏里面另外一个通用的设计了,所有的游戏都是一个巨大无比的循环,
根据屏幕刷新的帧数或者是其他参数来决定游戏循环计算的速度,也就是说,
你看上去一直在进行的游戏,其实从本质上只是一个一直在进行的迭代计算而已,
而你考虑的逻辑,只是每一次迭代中的算法,这么看,是不是很多复杂的情况都简单了?
比如你的重力改变了,没问题啊根本,应为我每次迭代重力都是一个参数,
你要么影响这次,要么影响下次,反正我也只是计算而已。

好,到这里,游戏本身的设计就完了,当然有很多细节会需要关注,
但是这些不是我这篇文章要关注的重点了。

这边文章的重点,真正开始了:

我们来回顾一下先前的游戏的设计,看看和我们已知的一些其他知识,
有什么相同的地方呢?

大循环,这个抽象,有没有让你想起什么来呢? 。。。。。。
是的,这可不就是一个服务器么。。。只不过服务器是一个请求过来,
对整个请求的处理作为一个循环,而游戏是你自定的参数或者是屏幕的帧数;
既然如此,那服务器设计用到的东西,完全可以照搬到游戏中嘛,
内存池的管理什么的都能用上了。那么我们更进一步,在服务器中,
拿 nginx 来说,一条 request 一般是一条数据,一堆的模块挂载上去之后各种处理。
那我们进化一下如何?在函数式编程中,有一种东西叫做 closure,
这玩意各种定义一大堆,简单的说,就是一段包含了运行环境的可执行代码。
想象一下,你的 nginx 接收的每个 request 是自执行的,
nginx 做的只是给它分配一个线程,是不是发现逻辑清晰好多?
这么做在服务器上未必合适,因为服务器要求的是一个稳定的持续可维护可测试的逻辑。
但是在游戏里面这么做,逻辑不要太简单了。
这就是我之前一直没有提的 event 机制了。
循环里面事实上触发了一堆的 event 去自己执行。
event 机制在 cocos2dx 中已经实现了,用得非常轻松。

好,和服务器的对比完了,我们继续来看这个大循环的抽象,怎么感觉有点眼熟呢?
。。。。。。想想当年你在大学或者是找工作的时候,绞尽脑汁的去想算法。
思路是什么,是不是演化一次迭代?是不是找数列的通项公式?。。。
好吧,万物是相同的。

好了,说够了大循环了,我们来看看别的。我上面举出那个例子,
雪球被黑洞吸收的时候的那个例子里面,显示和逻辑是怎么分开的?
逻辑改变了雪球的状态,显示根据状态去显示了。我偷偷藏了一点没说:
后来 logic 发现雪球挂了。。。于是判定游戏结束。
这里面有一个关键点是啥?
没错,就是状态机。状态机,只要 998,程序代码,你值得拥有。
状态机这个玩意的应用太多了,字符串匹配算法,
编译机制的词法推导语法推导,这不都是状态机么?
是的,游戏就是一个特殊的编译器。。。
我这么说是不是太不像话了?可是你仔细想想,他们其实没有本质区别的,
人如果能从处理字符串中得到乐趣,那编译工作又有啥不是一个游戏的呢?

啰啰嗦嗦说了一堆,并不是试图去教什么东西,我只是一个小小求学者,
一直在试图用很多理由来说服自己这个设计不是那么差,于是就有了上面的文字。

最后打个广告:

雪球快跑, 孤独的小雪球跑啊跑,完全停不下来啊, 你和朋友谁跑得最远呢? 谁能跑到100分?

附一张300分的截图。。。 不要看我,肯定不是我玩的。。。

ios传送门:

  • appsore :

    https://itunes.apple.com/cn/app/xue-qiu-kuai-pao/id906007297?l=en&mt=8

android传送门:

  • 小米商城 :

    http://app.mi.com/detail/70714

  • 豌豆荚 :

    http://www.wandoujia.com/apps/klnd.flip_gravity

  • 91助手 :

    http://apk.91.com/Soft/Detail.aspx?Platform=Android&f_id=40848946

  • 360手机助手:

    http://zhushou.360.cn/detail/index/soft_id/1939872?recrefer=SE_D_%E9%9B%AA%E7%90%83%E5%BF%AB%E8%B7%91

  • 应用宝 :

    http://android.myapp.com/myapp/detail.htm?apkName=klnd.flip_gravity

12

听松馆少主

这是一本小册子,从今天开始记录我小小的人生。

12 日志
2 分类
6 标签
© 2018 听松馆少主
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4