18/11/2009
明天上午考高级编程,这个号称所有函数都是值,所有值都是对象的纯函数,纯面向对象语言Scala,竟然是洛桑联邦理工的教授在最近几年开发完成的。在某期校报的一篇文章中这样介绍Scala语言:“Twitter使用Scala作为后台部分的开发语言,开发人员反映使用Scala编程轻松而让人愉快”,文章中还称:“Scala将为Web2.0提供强大的推进力”。而这位教授在笑呵呵地给我们上了快十个星期的课之后,终于在明天要露出狰狞的面目,对我们进行期中考核。
我最近越来越觉得蜡笔小新是一部人民群众喜闻乐见的优秀动画作品。看似是用各种桥段拼凑起来的无厘头搞笑剧,其实却在忠实地反映着现实生活的方方面面:有时是对幸福生活的赞美,有时又是对世间冷暖的讽刺。
最后推荐一套叫做《技术史》(A history of technology)的书,总共七卷,可以在verycd上找到扫描版的pdf。原书由牛津大学出版,九几年的时候我国几所大学的教授合作完成了中译本。这套书介绍了从原始人时代开始到作者编写此书的时代为止,人类掌握的技术是如何不断进步。书中的技术涉及生产生活建造等各个方面,介绍相当全面详细,读起来很有趣。
嗯,《ツキアカリノミチシルベ》很好听。
07/11/2009
先就《还没有决定名字的网络游戏》的开发现状发一点牢骚。
第一次会议七人参加,第二次会议二人参加,第三次会议三人参加。没来参加会议的人到底是什么原因,怒气值不够放不出必杀了么?
像这样同学朋友通过网络聚集起来一起做一件事不可能有什么强制性的制约措施来让每个人都开足马力全力以赴,大家都是在靠热度做事。热度这东西很好,可以让人在干活儿的同时获得生理上的快感,唯一的问题是热度不持久,而且这个问题不是你每天灌两三瓶蓝色小药水就能解决的。
我不想说热度用完了就要用责任心来继续做下去什么的,这么说了就好像在说大家做事没有责任心一样。大家每个人都不容易,都有自己的事要忙。我只是觉得要找到一个稳定的团队,能够始终保持某种程度的效率把一件事做完实在是太难。
谢为然说你再去写篇日志找点程序员吧,随着会议讨论的深入,大家都发现有不少问题需要在程序上进行试验和尝试,而我现在还在测试网络连接方面的东西(比如用户验证)。于是我说,是啊,再来点程序员就好了,就要烤箱用200度预热15分钟之后再用180度烤30分钟加上奶酪胡椒粉的那种好了。
但是我真的不知道这篇日志该怎么写。
我很想把要求写得很详细,比如像这样:
一 共通要求:
1 C#语言
2 知道如何利用msdn网站或VC#附带的帮助文档查找函数及类定义
二 分类要求:
1 网络编程:socket编程经验 (主要任务是编写关于网络连接方面的代码,尝试实现各种游戏需要的功能)
2 游戏系统:对算法与数据结构掌握较好 (主要任务是编写游戏的主要逻辑代码,使用合适的算法与数据结构)
3 图形编程:2D图形API编程经验 (主要任务是尝试使用slimDX编写2D图形引擎)
但是根据以往的经验,这样的日志后面只会发现诸如“牛B”,“看不懂”一类的回复,所以日志不能这样写。
那么如果按照上次召募游戏策划那样的风格去写会怎样呢?
什么大家“一起燃烧青春热血”,“一起做有趣的事”,或者“只要有兴趣就行了”。结果就是大家刚来的时候热度满点,战斗力比超级赛亚人还要高几千万,一个星期以后热度耗尽,战斗力就算用上显微镜还要滴点苏丹红染染色才能找得到。
好吧,这其实还是一篇召募文。只不过就像命题作文题目明明是“一件难忘的事”,整片文章却在讨论什么样的事才能算是难忘的事,老师没有觉得你在无理取闹给你0分而是判你走题给你50分已经算相当客气。如果没有这样的觉悟的话,还是老老实实写点小明在公共汽车上给老人让座云云。
31/10/2009
今天把多人聊天的demo完成了,运行服务器端的程序之后,用户就可以使用客户端程序连接服务器,并和其他连接到服务器的客户端进行通信。
服务器接收客户端发来的消息,对其进行一些处理后再发送给其他客户端;客户端接受用户键盘输入的消息,将它发送给服务器,再从服务器接收来自其他客户端的消息,并把它显示在屏幕上。
到这里,关于网络连接、通信这些基础技术的尝试已经完成。接下来要做的是针对如何实现某些特殊的功能,进行进一步尝试。
下一个demo,我想重点考虑如何实现让多个玩家在同一个场景中互动。demo可以做成一个“玩家们在迷宫中探险”这样的小游戏。
对于多线程,我仍然有不少地方不明白。这次的问题是CPU的占用率。
我在服务器端的主线程中使用了一个while循环,在每一次循环中程序遍历所有与服务器相连的客户端,从这些客户端接收消息,再将服务器处理过的消息发送给客户端。消息的接收和发送都是以多线程的方式异步完成的。然后我运行这个服务器端程序,CPU占用率直接升到50%。
接着我换了一种代码的写法。我把刚才的整个while循环剪切粘贴到一个叫Update的函数中,然后新建一个线程,让这个线程去执行Update函数。而在主线程中,我还是写了一个while循环,但在这个while循环里,我放的是类似这样的代码:
String str = Console.ReadLine();
if (str.Equals("quit"))
{
break;
}
ReadLine是一个同步函数,他在读取到用户输入之前会阻塞当前线程。程序用这个函数读取用户输入后判断这个输入是否是字符串quit,如果是则退出循环,中止程序。然后我再次运行程序,奇怪的是,这一次CPU占用率完全没有明显的提升,和平时一样在5%以下波动。
第二种代码的写法和第一种相比,不但没有减少程序的工作量,甚至还增加了一点东西,但是CPU占用率反而变低了。这到底是何解?
我不记得是下学期还是明年,我们会有Concurrency这门课(我也不知道这个词该怎么翻译,大概就是“并行”之类的意思),也许到时候我能对多线程有更好的了解。
29/10/2009
又不是开心农场。
我在想如果把这一个多GB的图形资源丢掉,那么美工的成本就可以省出来用在系统设计上(不过好像3D模型一个也要好几个MB,所以估计也省不出多少成本来)。但是好的系统和好的画面哪个更能吸引玩家这个问题不容易得出结论。
程序方面这一个星期以来进展不大,又是在多线程的问题上遇到了困难。
异步函数本身不难理解,就是用线程池里面的一个空闲线程去做一件事情。但是这个异步函数还可以拥有一个回调函数,这就让人产生不少疑惑的地方。
网上找到的关于回调函数的说明大概有这么几点:
1 它和异步函数使用同一个线程,并在异步函数执行完毕后被调用;
2 它从异步函数那里接收一个实现了IAsyncResult接口的对象作为参数,这个对象有AsyncState和IsCompleted属性。AsyncState属性用来获取一开始传递给异步函数的那个Object对象,相当于起到给回调函数传递任意类型参数的作用。IsCompleted属性表示异步函数是否完成,由于回调函数必然在异步函数执行完毕后调用,所以在回调函数中这个属性肯定为true,这个属性的作用是当不使用回调函数时,可以在主线程里利用它判断异步函数是否执行完毕(不使用回调函数时,这个IAsyncResult对象可以通过异步函数的返回值得到)。
比如像这样(iar是一个IAsyncResult对象):
iar = xx.BeginXXX();
while (! iar.IsCompleted)
{
//更新UI并响应用户操作
}
现在仍然不太理解的是和开始异步的BeginXXX相对应的EndXXX的作用。msdn上查到的解释是等待异步调用的完成。
如果把这个函数放到主线程调用,那么它会在异步调用完成前阻塞主线程。问题是把这个函数放到回调函数里到底是什么意思?
如果说NetworkStream的EndRead函数还能返回读取到的byte数的话,像TcpClient的EndConnect这样什么都不返回的函数是怎么回事?
这次的demo估计还要过一段时间,我打算等完成多人聊天功能之后再让大家测试(之前试着写的一个demo线程之间的关系被我弄得乱七八糟,一运行就CPU占用率百分之百直接挂掉)。
另外就是希望这周的会议能在建筑的问题上取得进展吧。
20/10/2009
Civilization advances by extending the number of important operations which we can perform without thinking about them.
这是存在于一本二十世纪初数学教材中的一句话(我不是说我闲到有空去找一个世纪前的书来看啦,只是在其他书里面看到有人引用),把它抄下来在设计游戏的时候说不定能成为灵感的来源。
建筑判定的问题感觉相当难办,要判断人在不在建筑里,就要先判断这是不是一个建筑,麻烦得很,麻烦得很。
但是又想到,当初之所以会产生需要判断人在不在建筑里的问题,是因为我们打算给建筑增加一个隔断声音传播的特性。所以如果反过来想一想的话,假如我们不给建筑以隔音的特性,那么我们就不用再判断人在不在建筑里了。而一旦不需要判断人在不在建筑里的话,那些墙、柱子什么的是否构成一个建筑也不用判断了,因为只要设定墙的作用是阻断两个格子之间的通路,门的作用是存在打开和关闭两个状态等等如此的基本性质之后,建筑这个概念就可以忽略了。但这样随之而来的问题是,屋顶也变得没有用了。
嗯,再考虑看看。

神OP,外加连续三话都保持同样的高水准,不可谓不是本季动画的神作之一。我本来只是因为看了之前的禁书目录,所以打算看看试试,结果这一部的质量竟然比禁书目录要高出许多(难道是我的错觉吗 =3=)。追看确认。
另外求此图的高分辨率版。
上周末玩了一下信长之野望天道,用1546年的织田家,先灭了松平(因为之前不小心把德川家康的老子砍了,结果德川跑去今川家了)、筒井,接着又在1552年灭掉今川(这下终于收到德川,但是今川义元被武田挖走了……),织田家已经拥有六座城,三十万兵力。然后我就让电脑自动打,电脑一路高歌猛进,打了三十年统一全倭岛(在电脑进攻最后一座敌方城池的时候重新控制织田家,最后仍然算你完成了统一,可以看到结局动画并获得统一奖励)。
17/10/2009
第一次开会难免手忙脚乱,出各种状况,但总体来说今天的会议还算比较有成果。
下面是会议的内容提要:(如果需要完整的会议发言记录,请联系郭跃尘)
一 一个格子有多大 => 一个玩家占一格 => 玩家移动时重复输入指令很麻烦 => 玩家可以普通移动或在区域间传送 => 玩家可以事先设定好移动路线
二 说话声音可以传多远 => 大喊,普通,小声分别对应三种声音传播距离
三 可以隔离外界声音判定的会议室 => 没有特殊建筑,建筑的用途由玩家自行决定 => 建筑的大小由玩家自行决定 => 将建筑抽象成墙,柱子,顶,和门 => 如何判断玩家位于建筑内部还是外部 => 如何判断地图上的墙,柱子,顶,和门是否构成一个建筑
四 物品私有还是公有 => 由玩家自行决定部落的所有制=> 玩家只能使用被玩家带在身上的物品,玩家可以捡起任何不在其他玩家身上的物品 => 建筑物是否也有所有权 => 任何人都可以进入门没有上锁的建筑 => 部落可以指定对于偷窃行为的处罚措施 => 游戏中没有系统级别的私有财产设定,玩家只能尝试采用各种行动来保护自己的私有财产
五 如何防止游戏外交流 => 没有地名,部落名,和玩家名 => 玩家之间如何互相识别 => 玩家脸部特征,身材,衣着,装饰品
之前的一篇日志里提到了“命令行模式下如何能够在玩家输入信息的同时显示新接收到的消息”这样一个问题。这个问题现在已经解决,具体方法是这样:
在主线程中使用Console.ReadLine以阻塞的方式接收用户输入,在从线程中接收网络中的消息,然后配合Console.MoveBufferArea函数进行消息的显示。
解决这一问题后,就可以在命令行模式下实现一些简单的图形化。比如用各种符号来表示不同的物体,从而显示玩家周围的情况。
关于内网主机做服务器的问题,今天从高手处问到的结论是,目前没有什么比较简便的软件实现方式。要实现的话,都要对接入公网的那台机器做改动,也就是说首先就需要一个做改动的权限。
那么等到以后demo完成,进行测试的时候,我尽量每天开机,但是开机时间不能保证,一般是在GMT+1的下午和晚上,国内的话应该已经半夜了。
12/10/2009
没办法,本来这些东西都准备作为保留节目,在《关于大型多人在线火箭推动式榴弹程序现状之分析及新可能性之探讨》中呈现给大家的,但现在为了这一篇召募贴的需要,就让我提前拉开幕布吧(坚定的眼神望向远方)!!
我想要做一个网络游戏,所以在这里发一篇共同制作人召募贴。我会先说明召募的条件,然后再介绍一下这个我想要做的网游,最后讲一讲加入共同制作的人需要做的工作。
那么以下就是召募条件。
1 你不需要会编程。真的真的,哪怕从没听说过编程二字都没有问题。
2 你不需要是那种什么游戏都能立刻理解系统,轻松掌握诀窍的骨灰玩家。你可能会问,那我要不要写一篇500字的关于游戏产业现状或者对某个游戏的关卡设计进行分析的小论文?答案当然是不用。
那么说了这么多不用不需要,唯一一点必须满足的条件是什么呢?那就是:
3 在看完了下面对于这个游戏的介绍后,你要觉得“嗯,好像还挺有意思的”或者“哎呀,这样的游戏我真想早点试试看哪”。
如果以上三点都没有什么问题的话,那么欢迎和我联系。
下面就来说说这个游戏的大致情况。
我之所以想做这么一个游戏,主要是觉得现在的网游已经陷入了一种单调的套路中,大家都在做同样的东西。
网络游戏玩的到底是什么?我的看法是,网络游戏提供给玩家一个向别人炫耀的平台,玩家在这个平台上向其他人炫耀自己的等级,自己的装备,然后就是什么声望,荣誉之类的东西。玩家在网络游戏中做着和单机游戏同样的事情——用时间换取自己角色的能力提升,唯一的不同就是现在你可以让其他人都知道自己的角色能力提升了,或者获得好装备了。
以上几点,难道就应该是网络游戏的定义吗?我觉得这里面还是有可以改一改的地方的。
首先就是让网络游戏拥有和单机游戏截然不同的玩法,玩家要做的不再是打怪练级或者刷各种东西,和其他玩家一起去完成某件事情才是能体现网络特性的玩法。其次是改一改可以炫耀的东西,不管是等级、装备或者声望,这些都是可以通过时间换取的,等级只要杀怪做任务就行,装备只要刷副本杀Boss就行,这样一来各位玩家炫耀的其实只是自己的耐心和毅力而已。如果我们让玩家的角色会真正死亡,然后把可以炫耀的东西改成角色在游戏中的经历怎么样?角色脸上有一道很长的刀疤,那么这位角色大概是经历过恶战的勇士;角色的胸口挂着一段罕见的骨质饰物,估计这位角色应该是位打倒过各种奇虫异兽的出色猎手。
也就是说玩家不再用游戏时间来炫耀自己的耐心,而是和其他玩家一起,用角色仅有一次的生命,去体验游戏中的各种事情。这就是我想要在将要制作的游戏中体现的要素。
而游戏的具体内容大概是这个样子。
游戏发生在远古时代,原始人类组成了一个个部落艰苦地生活着。玩家需要扮演某一个部落中的某一个原始人,和自己的族人一起战胜由其他玩家组成的部落,最终在这场生存的竞争中存活下来。
游戏中没有任何由系统制定的社会管理系统,玩家在部落中担任何种分工,部落中的资源要怎么分配,以及部落成员采用何种管理制度,这些都要由玩家之间自行讨论决定。
游戏中也没有任何npc角色。玩家的任何行动都将改变这个世界。玩家可以探索世界,发现新的资源,发现其他部落。玩家可以制作工具武器,发现新的科技。玩家可以在世界的任何一个地点建造房屋,围墙,或是为自己的族人们提供一个安全的避风港,或是为采集距离较远的资源建立一个中转站,或是为了进攻其他部落建立一个临时营地。每一个角色在世界中都是微不足道的一份子,同时又在为改变这个世界默默地贡献着力量。
目前需要做的工作主要是游戏系统的设计。这个游戏目前还只是一个如同草稿纸上的涂鸦一般的初步构思,我有了一些想法,但是具体要怎么把这些想法实现出来,还需要大家的热情和力量。
游戏中要有哪些猛兽,有哪些可利用的资源,又有什么科技可以研究,有什么建筑可以建造,这些都需要进行设计。还有就是怎么样提供一种机制,让玩家可以自行产生属于自己部落的社会管理系统,比如说要怎么样让玩家从公有制发展到私有制,或者玩家愿意始终保持公有制的形式。需要设计的东西还有很多,这里只是举几个例子。
那么差不多就是这样。
二零零九年十月十二日
《还没有决定名字的网络游戏》制作委员会
11/10/2009
今天终于下定决心开始写代码了,可以说这是五月病症状有所缓解的好兆头么?
考虑到十一月初有期中考,虽然不是决定性的一击,但也影响到期末的bonus,所以这次的《石头剪刀布OL》还是慢慢来。
今天主要尝试了建立简单的TCP连接,并在两台主机之间发送信息。写完demo找几位同学测试了一下,发现凡是内网用户都不能作为TCP连接的服务器端,但是他们可以作为客户端去连接一个拥有外网ip的用户(我在宿舍用无线上网居然还能分到一个外网ip,全世界总共2^32个ip地址就被我占掉一个,在这一点上不得不承认瑞士很牛叉)。
(在写这篇日志的时候突然想到,如果两个内网用户和同一个外网用户分别建立连接之后,外网用户可以把内网用户建立连接时使用的外网ip地址和端口号分别发回给内网用户,然后这两个内网用户是不是就可以使用这个ip地址和端口号来直接建立连接了呢?在计算机网络的书里面写了,NAT其实是利用端口号来进行ip地址的扩展的,主机的内网地址和管理内网的服务器的外网地址以及这个服务器的一个端口号有一一对应的关系,那么有了这个端口号是不是就可以实现连接呢?)
接下来的一段时间仍然是进行未掌握技术的尝试,大概有以下这么两点:
1 实现多客户端对单一服务器的连接
*服务器如何检测客户端是否已经断开连接(网上的结论是用C#的话没有直接的函数能够实现这项功能,解决的方法是服务器端定时向客户端发送确认信息,如果收到客户端回应就表示客户端仍然连接,否则表示连接已经断开)
*各个客户端之间如何通信(也就是说服务器端需要提供一种标记客户端的机制,等于是给每个客户端一个名字。这一套标记要能让连接到服务器的每一个客户端知道,而且还要根据客户端的连接情况时刻保持更新)
2 实现命令行环境下的多线程消息收发机制
如何在用户输入信息的同时显示新接收到的消息(把程序图形化就不会有这方面的问题了,但是和C#搭配的图形API我只会用XNA,而用XNA的话就要先安装一大堆微软的补丁才能运行程序)
完成以上尝试之后,就要对代码进行整理,重写,并封装,做成一个可以重用的如dll之类的东西。
再往后才是设计游戏,写游戏本身的代码。这部分工作其实是有可能和上面的那些尝试工作一起进行的,比如你是个双头巨人,然后某个法师好心给你用了个奇迹术让你不再弱智,同时你全身挂满各种+1、+2直到+5智力的斗篷或是戒指项链护身符。但是在现实世界里,这些都不可能发生,唯一可能的只有去绑架一个会写程序的游戏策划来,然后再骑马滴XX灌XX地调教他,让他死心塌地地从了你,从此两人就一直幸福地生活下去,不对,是从此他就帮你毫无怨言地做策划,写试玩demo。
明天要看数学了,还有vhdl的作业(要做一个ALU和一个内存),还有Scala的编程项目,还有……
不能再列举下去了,一项一项列举出来只会发现时间完全不够用,一件接一件地去做才是把事情全部做完的正确方法。
07/10/2009
难怪有时候wifi会在已经连接网络的状态下提示“无线网络已连接”。
又到秋风送爽的时节,作为祖国的花朵,新世纪的阳光好少年,此时此刻我沐浴在祖国六十年生日的和谐光辉下,浑身power max。
关于这一季动画的扫雷请看这里,这位同学的口味和我惊人地相似,可以说我基本差不多完全同意他的看法。天体战士桑雷德出第二季了,华盟字幕组迟迟没有动静,于是我最终选了元火字幕组,因为据说这些人是北大动漫社的。
嗯,顺便说一句,我的专家级扫雷最好成绩是一百七十九秒。
计算机网络讲完了应用层的种种协议,下周应该就要开始socket编程了。到时候欢迎没有被NAT遮挡,拥有外网ip地址并且使用windows操作系统的同学来帮助我测试demo,先做一个《石头剪子布Online》好了。
学校的上机作业都要求用Java来写,但是考虑到Java程序难以实现“双击运行”,在测试的时候可能会遇到一点困难。所以游戏方面的demo打算全部用C#来写,这样的话基本上只要是windows系统,运行应该都没有问题。
06/10/2009
a short-sized sock, typically worn by Internet specialists.
这是今天计算机网络课堂小测验中一道问什么是Socket的问题的A选项。
开学第四个星期了,这学期本来每人只要选一门课就够了,结果我多选了两三门,一个星期的课时就从早上到晚上排得满满当当。
高达蛋蛋补完了,感想是不愧于新世纪高达之名的作品。第一部给人的感觉有点莫名其妙,但实际上故事从第二部才真正开始。不过既然这样为什么不把第一部的内容再精简一点,用两三集一口气解决掉不是可以让整部片子更紧凑一些吗?
这学期买了四本书了,好贵。
一本是计算机网络,这门课我期待已久,所以老师说了参考书名之后,没有犹豫一下课就去书店把书买到手,现在每天坐地铁都抱在手里看。第二本是计算机结构,据说做CPU是在第二学期,心想不能轻视,于是又买了。第三本是高级编程课的参考书,我本来以为这门课是要开始讲C或者C++,结果讲的是一门叫Scala的语言,之后好像还要学Lisp。第四本是线路信号,感觉这门课应该在去年上信息学之前上,很多原来模模糊糊的概念到上这门课的时候才发现原来是这么一回事。
最后就是如题的预告,大概一两个星期后完成。