SLG是重生态边界和导量策略的游戏,游戏到了中后期,为了维护玩家的新鲜感,扩大社交范围,提升留存和付费。会伴随各种各样的跨服玩法。其中以KvK(Kingdom vs Kingdom)持续时间最长(一个月左右),最为复杂(玩家可以在KvK中参与城建、活动、联盟等各种玩法,与原服的体验很接近)。本文以KvK为出发点,聊聊关于SLG跨服模型的一些实践和思考。

在此之前,有必要对游戏中常见的跨服、合服、迁服几个概念进行区分:

  • 跨服: 生态的摩擦和碰撞
  • 合服: 生态的融合和重组
  • 迁服: 生态的流动和微调

KvK跨服战场活动的简单示意图如下:

对玩家而言,体验最好的KvK玩法应该是轻量的,即玩家可随时自愿加入和退出,KvK战场活动持续期间,原服和KvK服都可以有玩家在玩。并且玩家切换战场的成本应该最小化,如联盟关系、活动进度、邮件、聊天等数据都应该尽可能保留。

以下聊聊我们在实际项目中,对KvK跨服的三种理解(领域模型)和实现,并简单以Model1,Model2,Model3区分。

阅读全文 »

起意是想梳理下分布式系统的一些基本概念和理论,做一张知识脉络图,后来发现内容太多,图片不适合,因此整理成了文字版本。不过整体框架结构仍然类似思维导图,用作知识联结与发散。

定义

什么是分布式系统?

系统中有若干独立自治的计算实体,每个实体有自己的内存状态,实体之间通过传递消息相互通信。整个系统对用户提供一致、统一的服务。

为什么要使用分布式系统?

使用分布式而不是单机的原因有很多,总的来说大概分为三类:

  • 解决业务问题: 如复杂度瓶颈、系统对接、成本考量等
  • 解决扩展性问题: 如计算瓶颈、存储瓶颈、延迟优化等
  • 解决可用性问题: 通过冗余提升可用性

指标

分布式系统关注哪些指标?或者说我们通过哪些指标来衡量一个分布式系统?

可伸缩性

定义: 系统通过添加资源来应对不断增长(或变更)的工作量的能力。

伸缩的维度有很多,包括规模伸缩、地理伸缩、功能伸缩、异构伸缩等。

理想情况下,期望系统处理能力随资源投入线性增长。而实际上,还要权衡通信成本和延迟、可用性、数据一致性等诸多方面。

可用性

定义: 系统处于正常工作状态的时间比例。

这里有两个个相关概念:

  • MTBF(Mean Time Between Failure):平均无故障时间,MTBF越长表示可靠性越高
  • MTTR(Mean Time To Repair):平均修复时间,MTTR越短表示易恢复性越好

可用性 = 正常运行时间/(正常运行时间+故障时间) = MTBF/(MTBF+MTTR)。

阅读全文 »

本文为《领域驱动设计-软件核心复杂性应对之道》中关于柔性设计和重构相关内容学习笔记,之前总结的软件设计更多偏向于技术实现层面,而柔性设计更强调领域模型,属于非结构化建模。前者教你修房子(设计之术),后者教你设计建筑(设计之道)。虽曰”道可道,非常道”。但反复学习品味相关内容,结合之前的重构实践,相互印证,确实诸多共鸣,受益匪浅,逐整理之。

从Erlang过渡到Golang以来,一直陆续会有同学问: “Golang能不能做代码热更呢?”,”游戏服务器不能热更会不会经常停服?”之类的问题,我的一贯看法是,抛开成本和风险谈收益的意义是不大的,所以在回答以上问题之前,先聊聊主流的Golang热更方案,它们都是基于Go Plugin机制的,这里讨论其中的两种,这里我将其称为plugin package swap方案和plugin function patch方案。

plugin package swap

该方案的思路是,将业务package编译为plugin,动态加载和替换,再通过plugin.Lookup来动态查找和使用函数。这也是最主流的Go Plugin应用方案,不过该方案有以下缺点:

  1. 受 Go Plugin 本身的限制,如第三方依赖需要一致、不能引用插件package、插件内数据类型共享、插件无法释放、调试相对困难、跨平台问题等
  2. 对业务代码侵入式较强,包括 plugin main package限制、Lookup调用方式、发布流程等

Go Plugin从2016年发布以来一直不温不火,Go官方对Plugin的维护升级更谈不上上心(两者互为因果),对于大部分开发者而言,面临Plugin的诸多限制,还是要花一些时间踩坑的。因此,有一套弱侵入性的热更方案,减少对已有框架代码的影响,减轻对开发者的理解负担(比如不要为热更单独写业务代码),并且提供快速切换静态编译和热更版本的支持,在我看来对线上服务是比较重要的。有一些开源库能解决部分问题,如hotswap能解决 main package 限制(通过正则临时替换)、不同版本plugin数据类型问题、Plugin生命周期管理问题等,并且也提供了动态链接(走plugin Lookup)和静态链接(对外暴露相同的接口,不过底层不走plugin Lookup,而是package函数调用)两种集成方式,一定程度降低了热更的侵入性。

阅读全文 »

这段时间学习Unity,顺便系统性地了解了下C#和Unity异步编程的各种机制和实现细节。本文是这些学习资料和个人理解的汇总。会先介绍下C# yield,Task,async/await,同步上下文等机制。然后聊聊其在Unity上的一些变体和应用。

阅读全文 »