什么是 MMO?
MMO(Massively Multiplayer Online,大型多人在线游戏)是一种非常多玩家在同一服务器上游玩的游戏。MMO游戏让玩家能够和其他玩家合作或者对抗,让游戏变得更加有趣。
为什么使用 Simple MMO?
在原版 Scratch 中制作 MMO 游戏是非常困难的,因为原版的云变量设计并不适合联机,你需要在原版云变量的限制上设计各种机制来实现联机。
同时,由于原版云变量为了方便使用,设计了“一人修改,所有在线用户同步”的功能,导致在大量玩家同时游玩同一作品时,大量耗费流量和服务器资源。
因此设计了 Simple MMO 拓展,既提供大量方便的积木实现联机匹配同步系统,同时优化了联机时的数据传输量,在保证高效联机的同时,节约玩家流量,降低服务器负担。
如何使用
快速入门
Simple MMO 提供了一些用于快速制作简单多人游戏的积木。你可以用最少的积木实现一个最简单的多人联机游戏。
加入或者创建一个房间,并且等待连接成功。
加入模式 | 描述 |
加入或创建 | 遇到服务器 ID 相同且未锁定、未满员的房间就会加入,否则会创建新的房间。建议在创建或者加入广播房间的时候使用。 |
创建 | 创建新的房间,无论是否已经有服务器 ID 相同的房间存在。建议在创建游戏室的时候使用。
如果用创建来创建广播房间,可能会导致相同服务器 ID 的广播房间出现,这会导致之后加入房间时发生混乱。 |
对于游戏大厅来说,加入或创建 和 创建 没有区别。 |
房间类型 | 描述 |
广播
broadcast | 最原始的房间,根据服务器 ID 区分。
虽然叫做广播房间,但它在支持广播的同时也支持玩家数据的同步。
不同的游戏室不应该共用同一个服务器 ID,这会导致加入的时候无法区分房间。 |
游戏室
match | 比广播房间更加完善的房间,支持限制房间人数和锁定房间功能。
不同的游戏室可以共用同一个服务器 ID,可以通过加入同一服务器 ID 的游戏大厅的方式获得相同服务器 ID 的所有游戏室房间的房间 ID,通过房间 ID 即可加入特定的房间。 |
游戏大厅
lobby | 特殊的房间,进入该房间后可以实时获取与该大厅同服务器 ID 的游戏室列表,以便选择游戏室。
在游戏大厅里无法获取同一大厅的玩家列表,查看其他玩家,或者接收广播。 |
额外数据:设定玩家的额外数据(不是房间的额外数据),额外数据可以用玩家相关积木获得。
这个积木会在连接成功之后运行后面的积木。连接失败了,后面的积木也会运行,可以用其他积木来判断房间是否连接成功。例如“我的 [ 会话 ID ]”积木为 NaN 时表示失败。
断开与当前房间的连接。
获取当前连接的相关信息。
选项 | 描述 |
会话 ID | 会话 ID,每个玩家的会话 ID 不同。
可以用来获取自己的相关属性,区分自己和其他玩家。
玩家每次连接到新的房间,会话 ID 会改变。
NaN 代表没有连接到任何房间 |
房间 ID | 房间 ID,每个房间的 ID 不同。
在游戏大厅里获取同一服务器 ID 的游戏室列表后,可以用房间 ID 来区分不同的房间,以便加入。
NaN 代表没有连接到任何房间 |
房间类型 | 连接到的房间类型。
broadcast 代表广播房间
match 代表游戏室
lobby 代表游戏大厅
NaN 代表没有连接到任何房间 |
设置自己的 X, Y, 缩放等数据,这样其他玩家可以获得这些数据。
属性名 | 描述 |
名字 | 名字,任意文本,通过设置积木设置,一般设为玩家的名字。默认是玩家的用户名。 |
X | X,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的X坐标。默认是 0。 |
Y | Y,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的Y坐标。默认是 0。 |
缩放 | 缩放,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的大小。默认是 0。 |
方向 | 方向,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的朝向。默认是 0。 |
额外数据 | 玩家的额外数据,任意文本,通过设置积木设置。任何东西都可以放这里。默认值通过加入房间的积木设定。 |
用一个积木同时设置X数据和Y数据。
获取房间里的玩家数量,如果没有连接房间,或者是连接到了游戏大厅,玩家数量将是0。
获取房间里玩家的详细信息,注意序号从 0 开始,第一个玩家的序号是 0,第二个玩家的序号是 1,依此类推。
属性名 | 描述 |
会话 ID
sessionId | 会话 ID,每个玩家每次连接的会话 ID 不同,可以用来区分不同的玩家。
在有玩家加入或者退出房间的时候,玩家的序号可能会改变,而会话 ID 不会变,因此应该用会话 ID 来区分玩家。
玩家每次连接到新的房间,会话 ID 会改变。 |
名字
name | 名字,任意文本,通过设置积木设置,一般设为玩家的名字。
默认是玩家的用户名。 |
X
x | X,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的 X 坐标。
默认是 0。 |
Y
y | Y,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的 Y 坐标。
默认是 0。 |
缩放
scale | 缩放,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的大小。
默认是 0。 |
方向
direction | 方向,最多保留两位小数的数字,通过设置积木设置,一般设为玩家的朝向。
默认是 0。 |
CCW UUID
uuid | 玩家的用户 ID,每个用户不同。也就是个人主页中的“共创世界 ID”。 |
在线?
connected | 玩家的在线状态。目前只能为 true。 |
额外数据
extra | 玩家的额外数据,任意文本,通过设置积木设置,任何东西都可以放这里。默认值通过加入房间的积木设定。 |
所有 JSON 数据 | 用 JSON 格式表示的所有玩家相关数据。相关的属性名称在表格中用斜体标出。下面是 JSON 示例。 |
{"name":"Alex","x":0,"y":0,"scale":100,"direction":0,"sessionId":"cTZEHuqKs","uuid":"123456789","extra":"Extra data","connected":true}
获取会话 ID 对应的玩家的详细信息。记得修改后面的[会话 ID]为你想要的属性。
和原版Scratch的克隆自己的积木相似,唯一的区别是这个克隆体会对应一位玩家的会话 ID。
克隆体所在的位置和大小等和本体相同,不会自动移动到对应玩家的位置,需要添加额外的积木让它运动到对应玩家的位置。
获取这个克隆体对应的会话 ID 所对应的玩家的数据。属性名参考上面的“属性名”表格。
在有新玩家进入房间的时候触发此积木。需要注意的是,自己进入房间的时候也会触发。
sessionId 新玩家的会话 ID
name 新玩家的名字(加入房间时,这个名字只能是默认的用户名)
data 新玩家的初始额外数据(在加入房间的积木里设置)
在有玩家离开房间的时候触发此积木,自己退出房间的时候不会触发。
sessionId 离开房间的玩家的会话 ID
name 玩家离开时的名字(中途有可能通过设置积木设定了别的名字)
data 玩家离开时的额外数据
判断当前克隆体所对应的会话 ID 是不是对应的 ID。等价于
额外数据:设定房间的额外数据(不是玩家的额外数据),额外数据可以是任何文本(不一定要是 JSON)。
注意:所有的玩家都能读取和修改房间的额外数据。从游戏大厅可以读取游戏室的额外数据。
获得房间的额外数据。
广播消息
给房间里的其他玩家发出广播。
syscmd:
,因为这是扩展保留的内部广播名称。房间里的其他玩家发送广播时触发。自己不会收到自己发出的广播。
sender 代表其他玩家的会话 ID
senderUID 代表其他玩家的共创世界 ID
name 代表其他玩家设定的名字(默认是用户名)
type 代表发送的消息的类型
content 代表消息的内容。
游戏大厅与游戏室
创建游戏室
创建游戏室的积木,功能和最开始的创建房间积木相似,不过只能创建游戏室,而且能够设定游戏室的最大人数。
不要给每一个房间分配不同的服务器 ID,同种类的游戏室服务器 ID 应该相同,这样才能通过相同的服务器 ID 查询到所有创建的游戏室。游戏室之间通过房间 ID 区分。
加入模式 | 描述 |
加入或创建 | 遇到服务器 ID 相同且未锁定、未满员的游戏室就会自动加入,否则会创建新的房间。非常适合用来做“玩家自动匹配”机制。 |
创建 | 创建新的游戏室,无论是否已经有服务器 ID 相同且可以加入的房间。可以在玩家主动创建新的游戏室的时候使用。 |
禁止新的玩家加入游戏室。一般在游戏已经开始的时候使用。
加入游戏大厅,搜索游戏室
使用创建或加入房间的积木加入到和游戏室服务器 ID 相同的游戏大厅后,即可搜索游戏室。
获取和大厅服务器 ID 相同的游戏室的数量。
获取大厅服务器中的房间信息。编号从 0 开始。
属性 | 描述 |
房间 ID
roomId | 这个房间的房间 ID |
房间类型
name | 只可能是 match,代表游戏室 |
玩家数
clients | 游戏室中玩家的数量 |
最大玩家数
maxClients | 游戏室最多能接收的玩家数,或者 null 代表不限制玩家数量。 |
创建于
createdAt | 房间创建的时间。使用 ISO 8601 时间表达
例子:2022-06-18T10:06:25.143Z |
元数据
metadata | 用 JSON 格式表示的房间数据,可以同时获取房间锁定状态、额外数据和房间的真实 ID(作品 ID 和 房间 ID 用 “-” 连接起来的结果)。
因为有更方便的方法获取这些数据,目前没有使用的必要。 |
额外数据
metadata
extra | 获得房间的额外数据。
如果没有设置,返回 undefined。在 JSON 数据中将会省略 |
锁了?
metadata
locked | 房间是否锁定,true 代表锁定,false 代表没锁。 |
所有 JSON 数据 | 以上全部内容的 JSON 格式表达。相关的属性名称在表格中用斜体标出。下面是 JSON 示例。 |
{"clients":1,"createdAt":"2022-06-18T10:06:25.143Z","maxClients":10,"metadata":{"locked":false,"gid":"63e066d11ba8060c1769b63f-serverId","extra":"Room data"},"name":"match","processId":"0b3kFmIru","roomId":"jFU7S--W0"}
将指定列表的内容整个替换为所有游戏室的指定属性。属性和上一个积木相同。顺序保持一致。
关于额外数据里的 undefined:这个值非常特殊,在列表里看不到,但是能正常使用。
获取所有游戏室的 JSON 数据,是每个游戏室的“所有 JSON 数据”按顺序连接的数组。
修改选项,可以只获取已锁定或者未锁定的游戏室。
[{"clients":1,"createdAt":"2023-04-05T15:22:48.302Z","maxClients":null,"metadata":{"locked":false,"gid":"63e066d11ba8060c1769b63f-serverId"},"name":"match","processId":"0b3kFmIru","roomId":"jFU7S--W0"},...]
在有相同服务器 ID 的游戏室被创建或者删除时触发。
选项 | 描述 |
发生任何变化 | 创建或者删除都触发 |
有新游戏室被创建 | 创建时触发 |
有游戏室被移出 | 删除时触发 |
rooms 格式:将改动的房间的消息连接在一起成为一个数组。
房间 JSON 的格式见下方“得到大厅中第( )个游戏室的 [ ]”积木。
[{"clients":1,"createdAt":"2023-04-05T15:22:48.302Z","maxClients":null,"metadata":{"locked":false,"gid":"63e066d11ba8060c1769b63f-serverId"},"name":"match","processId":"0b3kFmIru","roomId":"jFU7S--W0"},...]
连接到游戏大厅里的游戏室。
额外数据 代表玩家的额外数据。
房间号 代表区分不同房间用的房间 ID。
服务器 ID 代表房间使用的服务器 ID。
异常处理
在与房间的连接异常断开时触发。
异常断开只包括网络故障(断网,网络波动,或者服务器异常断开),如果是因为服务器 ID 或房间 ID 错误,或者受到“一号多登”限制掉线,或者作品主动断开了连接(包括点击停止/重新启动按钮),不会触发。
任何时候都可以使用“我的 [ 房间类型 ]”积木的返回值判断连接状态。
其它积木
获取当前与 Simple MMO 服务器的连接的延迟,大概每 5 秒更新一次。
这个积木用来设置游戏室的属性,所有玩家都能设置,默认是允许。
设置为禁止后,同一个账号将不能同时(打开多个窗口)加入这个游戏室,加入这个游戏室将会导致这个游戏室内共创世界 ID 相同的其他玩家断开连接(异常断开积木不会因此触发)
这类积木和之前提到的积木很像,但是它们不会等待房间连接成功或者失败后再运行后面的积木,而是直接运行后面的积木。
在自己进入任意房间后,这个积木会被触发。一般和上面的三个积木配合使用。
无论使用什么积木加入房间,只要加入房间成功,这个积木都会被触发。目前没有加入房间失败触发的积木。
获取房间里的玩家列表。
格式 | 描述 |
默认 | 使用逗号和分号分隔的玩家列表。
会话 ID共创世界 ID,玩家名字; |
JSON | 使用 JSON 格式的玩家列表,将所有玩家的所有 JSON 数据连成一个数组
玩家所有 JSON 数据格式,请参考快速入门一节 |
默认格式示例
vEOvyf0zm,123456789,John;0CjdCxTmT,234567890,Bob;xuvhtkhP8,123345678901456789,Robert;
JSON 格式示例
[{"name":"John","x":0,"y":0,"scale":100,"direction":90,"sessionId":"vEOvyf0zm","uuid":"123456789","extra":"data","connected":true},{"name":"Bob","x":0,"y":0,"scale":100,"direction":90,"sessionId":"0CjdCxTmT","uuid":"234567890","extra":"data","connected":true},{"name":"Robert","x":0,"y":0,"scale":100,"direction":90,"sessionId":"xuvhtkhP8","uuid":"345678901","extra":"data","connected":true}]
获取相关玩家的属性。属性见上方“第( )个玩家的 [ ]”积木。
(其中离开的玩家的属性只能通过这里的第二个积木获得,因为他已经离开房间了)
目前改变状态的积木存在问题,无法正常触发,正在修复中……
判断运行此积木的角色是否是克隆体,包括原版“克隆”积木还是 Simple MMO 的“数据源克隆”积木产生的克隆体。
查看克隆体是否是根据自己的会话 ID 克隆的。
较难使用的积木
在房间的状态变化(玩家加入或者退出,或者房间额外数据变化)时,触发此积木。
状态变化时该积木可能会多次触发(2 到 4 次)
选项 | 描述 |
任何 | 玩家加入或者退出或者房间额外数据变化都触发 |
在线人数 | 玩家加入或者退出时触发 |
额外数据 | 房间额外数据变化时触发 |
sessionId 当前会话 ID
roomState 当前房间状态,JSON 格式。
属性 | 描述 |
onlineCount | 在线人数 |
extra | 额外数据。未设置前无此属性 |
players | “当前在线的玩家列表”,JSON 格式 |
{"onlineCount":2,"players":{"vEOvyf0zm":{"name":"Kathi","x":-103.64,"y":54.63,"scale":100,"direction":-165,"sessionId":"vEOvyf0zm","uuid":"198924309","extra":"data","connected":true},"at56c7bqK":{"name":"Bob","x":0,"y":0,"scale":0,"direction":0,"sessionId":"at56c7bqK","uuid":"198924309","extra":"data","connected":true}}}
changes 描述房间状态的修改。这是一个 Colyseus 内部数据,不建议直接使用。
在玩家的状态改变的时候触发此积木。
目前这个积木存在一些问题,无法正常触发,正在修复。
sessionId 当前会话 ID
name 玩家设定的名字
data 玩家的额外数据
其它问题
参考文章
如何选择合适的云变量替代方案?
用 Simple MMO 制作联机游戏的教程!
Simple MMO 英文版教程
更多细节
- Simple MMO 使用开源联机游戏库 Colyseus 实现方便的联机匹配、玩家状态管理以及数据同步等功能。(Colyseus 基于 MIT 协议)
- Simple MMO 的所有修改都是实时向在同一房间内的其他玩家同步的,而读取不消耗网络流量,和云变量的机制很像。因此你可以任意地读取其他角色的状态而不用担心增大服务器负担,同时,不要随意传输大量数据。
- 点击停止/重新启动按钮会自动断开连接。
- 所有玩家退出房间后,房间将会自动删除。
- 自己的坐标数据以及玩家数据更新是有限速的,每 0.05 秒最多更新 1 次。如果你想让其他玩家的位置更加流畅,需要自己设计让角色平滑移动的积木。
- 虽然Simple MMO的内部广播名只是以
syscmd:
开头,但是你发出的广播名里的任何位置都不能包含syscmd:
,无论是中间有syscmd:而已
还是末尾有syscmd:
都不行。
兼容性引导
不同社区的云变量机制区别很大,如果你想要使用 Simple MMO 扩展,将你的作品适配到其他社区将会是一件很困难的事。
如果你有将作品发到其他社区的打算,应该在创作作品的时候就做好准备。
一个比较简单的适应不同社区的方法是把所有需要社区专有扩展的积木放在同一个角色中,然后通过列表和广播传送参数来调用。这样,在需要适配其他社区的时候,可以在不影响其他角色的情况下删除这个角色,实现作品多社区适配。
例如一个平面射击游戏,有单人游玩和联机游玩功能。那么可以在不同的社区制作不同的“联机”角色并且导出,在上传到不同社区时,使用删除角色和导入角色的方法适配。如果遇到不支持联机的社区,还可以去掉该角色,禁用联机功能。
备注
此插件由以下肝酱贡献:
文档由 -6 校对
-6 Scratch 创作者✉️ 1195132772@qq.com | 飞书链接 | QQ: 1195132772
讨论
<iframe
width="100%"
height="800px"
scrolling="no"
src="https://www.ccw.site/embed?id=dev-extensions-simplemmo&type=comment"
title="Gandi Simple MMO 插件评论区"
frameBorder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
allowFullScreen
scrolling="0"
></iframe>