从编程的角度来看,Minecraft 是怎么样设计的

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从编程的角度来看,Minecraft 是怎么样设计的相关的知识,希望对你有一定的参考价值。

1.整体架构
对于modder来说,写Mc mod的的时候,我总是想着Java怎么就不提供个直接能覆盖掉MC原类的关键字呢?Mc源代码在部分层面的逻辑非常混乱,后面慢慢吐,不急。Mc的混乱不在于不同程序员间的代码风格迥异(当然也是因素之一),更在于Mc与他的“历史遗留问题”。打个比方说,一个孩子在搭积木,他开始用了方形的结构磕磕绊绊的搭了好几层,后来,他发现三角形结构更加稳定。然而他那时偷了点懒,在方形的基础上构造一层层稳固的三角形。积木越搭越高,却也越来摇摇欲坠。当孩子望着这些积木打算着手修改时,却发现问题早就树大根深了。Mc就是这样,Notch早期很明显的以小项目为基础考虑而构建的代码、逻辑结构很大程度上或多或少祸害了如今的Mc。不是说Notch开始不对,是说Mc在还来得及的时候没有痛下决心重写项目。后来的程序中,当然不乏漂亮的逻辑,但是这都有一个蹩脚的点为根基。从根本上讲,Mc“根本”不行。由于当初小项目开发的前瞻性不足,如今留给mod开发者抑或是Mojang的开发空间十分狭隘。得亏有了ASM得以使开发者在源码上凿开空间。
2.Truck
你你你……我我我……唉:-(!
Mc效率差的原因之一。这样吧,这部分我先静一静,有机会说说哈。
3.绘制
有答案已经提了,直接给数据什么的……不提效率,反问Mojang团队自己看不看得懂自己在写什么!
4.逻辑
为什么一个方块有4种得到掉落物的方法,还附赠一个掉落物品的方法?为什么纵使每种物品方块几乎都有class,指定他们的硬度等参数还要在init里?这么说吧,我植物这方面做的比较多,如果你的植物不属于换了材质的小麦,基本就是要继承Block再造轮子了。没办法,原版植物谁用谁知道。
5.GUI
又要造一波轮子。个人想法:mc的GUI本身的鼠标部分写的太次了!完全没有继承价值,属于重载了super都不带一句那种。自带的GuiButton就是个摆设。
6.硬编码
Mojang喜欢硬编码跟见了亲人一样。比如物品Id、方块Id、子物品、RenderType……分配一个,用registry很难吗?
/==================
专门来一篇Minecraft的介绍。先声明,这里只是普通的Moder。
1.Minecraft的地图生成算法
Minecraft的地形算法是基于Perlin Noise的2-pass过程。关于Perlin Noise的,可以看看git上我写的版本(链接:https://github.com/kaaass/JavaPerlin 直到目前尚未完成)。第一次:基本生成,确定biome,建立基础地形。第二次:特性生成,从layout开始(河流等等),然后是洞穴、树、村庄什么的。由于存在先后多次生成,就会偶尔遇到村庄位于峡谷上等等奇葩景观。
2.Minecraft的Block
方块具有很多特性,这里只讲一点。先是metadata,诸如植物(单指Corp)不同的生长状态都是不同的metadata决定的。TileEntity,entity是实体,诸如玩家、怪物都属于entity。metadata的存储数据量对部分方块,比如箱子。所以引入了TileEntity的形式。暂时就说辣么多。
3.物品
物品具有和block相似的机制。存储状态使用damage值决定。没错很多时候物品就是用名字上叫“耐久”的值存储状态的。然后是subitem的机制,就是子物品。比如染料(dye),染料很多,然而其实物品id是一样的。
参考技术A 以下是PC的设计首先启动器,现在的有正版启动器和忘却的旋律。(设置皮肤,插件,设置等等等等)然后主程序,好像mc没有游戏引擎吧,我不清楚,先构造好GUI,设计物品子类,父类,给他们一定的代码代替,然后是随机地图,像这个就复杂了,你可以看看mojang早期作品,地图生成从代码角度就复杂了,你还要设置seed,游戏的话其实这些搞好了,就是拼接问题了。我以前用vb做了个2D的mc我可以把源码给你看看 参考技术B 日照香炉生紫烟,遥看瀑布挂前川。 参考技术C Java从入门到入土

什么是shell

  从程序员的角度来看, Shell本身是一种用C语言编写的程序,从用户的角度来看,Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。在Linux GUI日益完善的今天,在系统管理等领域,Shell编程仍然起着不可忽视的作用。深入地了解和熟练地掌握Shell编程,是每一个Linux用户的必修 功课之一。  
    Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、K Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等等。不同的Shell语言的语法有所不同,所以不能交换使用。每种Shell都有其特色之处,基本上,掌握其中任何一种 就足够了。在本文中,我们关注的重点是Bash,也就是Bourne Again Shell,由于易用和免费,Bash在日常工作中被广泛使用;同时,Bash也是大多数Linux系统默认的Shell。在一般情况下,人们并不区分 Bourne Shell和Bourne Again Shell,所以,在下面的文字中,我们可以看到#!/bin/sh,它同样也可以改为#!/bin/bash。  
 
      
 
shell是一种具备特殊功能的程序,它是介于使用者和 Unix/Linux 操作系统之核心程序(kernel)间的一个接口。为什么我们说 shell 是一种介于系统核心程序与使用者间的中介者呢?读过操作系统概论的读者们都知道操作系统是一个系统资源的管理者与分配者,当您有需求时,您得向系统提出;从操作系统的角度来看,它也必须防止使用者因为错误的操作而造成系统的伤害?众所周知,对计算机下命令得透过命令(command)或是程序(program);程序有编译器(compiler)将程序转为二进制代码,可是命令呢?其实shell 也是一支程序,它由输入设备读取命令,再将其转为计算机可以了解的机械码,然后执行它。

        各种操作系统都有它自己的 shell,以 Dos 为例,它的 shell 就是 command.com 檔。如同 DOS 下有 NDOS,4DOS,DRDOS 等不同的命令解译程序可以取代标准的 command.com ,UNIX 下除了 Bourne shell(/bin/sh) 外还有 C shell(/bin/csh)、Korn shell(/bin/ksh)、Bourne again shell(/bin/bash)、Tenex C shell(tcsh) … 等其它的 shell。UNIX/Linux 将 shell 独立于核心程序之外,使得它就如同一般的应用程序,可以在不影响操作系统本身的情况下进行修改、更新版本或是添加新的功能。

Shell 的激活

        在系统起动的时候,核心程序会被加载内存,负责管理系统的工作,直到系统关闭为止。它建立并控制着处理程序,管理内存、档案系统、通讯等等。而其它的程序,包括 shell 程序,都存放在磁盘中。核心程序将它们加载内存,执行它们,并且在它们中止后清理系统。Shell 是一个公用程序,它在您签入时起动。藉由解译使用者输入的命令(由命令列或命令档),Shell 提供使用者和核心程序产生交谈的功能。

当您签入(login)时,一个交谈式的shell 会跟着起动,并提示您输入命令。在您键入一个命令后,接着就是 shell 的工作了,它会进行:

1. 语法分析命令列。

2. 处理万用字符(wildcards)、转向(redirection)、管线(pipes)与工作控制(job control)。

3. 搜寻并执行命令。

        当您刚开始学UNIX/Linux系统时,您大部份的时间会花在于提示符号(prompt)下执行命令。

        如果您经常会输入一组相同形式的命令,您可能会想要自动执行那些工作。如此,您可以将一些命令放入一个档案(称为命令档,script),然后执行该档。一个shell 命令档很像是 DOS 下的批次檔(如 Autoexec.bat):它把一连串的 UNIX 命令存入一个档案,然后执行该档。较成熟的命令档还支持若干现代程序语言的控制结构,譬如说能做条件判断、循环、档案测试、传送参数等。要写着写命令档,不仅要学习程序设计的结构和技巧,而且对 UNIX/Linux 公用程序及如何运作需有深入的了解。有些公用程序的功能非常强大(例如 grep、sed 和awk),它们常被用于命令档来操控命令输出和档案。在您对那些工具和程序设计结构变得熟悉之后,您就可以开始写命令档。当由命令档执行命令时,此刻,您就已经把 shell 当做程序语言使用了。

细说 Shell 的生平

        第一个有重要意义的,标准的 UNIX shell 是V7(AT&T的第七版)UNIX,在1979 年底被提出,且以它的创造者 Stephen Bourne 来命名。Bourne shell 是以 Algol 这种语言为基础来设计,主要被用来做自动化系统管理工作。虽然 Bourne shell 以简单和速度而受欢迎,但它缺少许多交谈性使用的特色,例如历程、别名和工作控制。

Shell基本工作原理方案

        Linux系统提供给用户的最重要的系统程序是Shell命令语言解释程序。它不属于内核部分,而是在核心之外,以用户态方式运行。其基本功能是解释并执行用户打入的各种命令,实现用户与Linux核心的接口。系统初启后,核心为每个终端用户建立一个进程去执行Shell解释程序。它的执行过程基本上按如下步骤:

(1)读取用户由键盘输入的命令行。

(2)分析命令,以命令名作为文件名,并将其它参数改造为系统调用execve( )内部处理所要求的形式。

(3)终端进程调用fork( )建立一个子进程。

(4)终端进程本身用系统调用wait4( )来等待子进程完成(如果是后台命令,则不等待)。当子进程运行时调用execve( ),子进程根据文件名(即命令名)到目录中查找有关文件(这是命令解释程序构成的文件),将它调入内存,执行这个程序(解释这条命令)。

(5)如果命令末尾有&号(后台命令符号),则终端进程不用系统调用wait4( )等待,立即发提示符,让用户输入下一个命令,转⑴。如果命令末尾没有&号,则终端进程要一直等待,当子进程(即运行命令的进程)完成处理后终止,向父进程(终端进程)报告,此时终端进程醒来,在做必要的判别等工作后,终端进程发提示符,让用户输入新的命令,重复上述处理过程。

 

以上是关于从编程的角度来看,Minecraft 是怎么样设计的的主要内容,如果未能解决你的问题,请参考以下文章

STL源码剖析——iterators与trait编程#1 尝试设计一个迭代器

DPDKring从DPDK的ring来看x86无锁队列的实现

从IDEA角度来看懂UML图

从另一个角度看Reactor

从编码人员的角度来看文件权限

从任何角度来看 ++i 和 i+=1 有啥区别