Game
Joining a game
Section titled “Joining a game”Once Mason Service sends you your server details, the following is all that’s needed to make a simple connection to the server:
mason.on("partyJoinServer", (server: ApiServer) => { const game = new Game(server, { displayName: "Example Bot" });});There are some more options which you can tweak to fit your needs:
| NAME | TYPE | DESCRIPTION | DEFAULT |
|---|---|---|---|
| displayName | string | Bot’s in-game name | ”Player” |
| proxy | Agent | Connection proxy | undefined |
| schemas | boolean | Automatically parse JSON data and emit Schema events | true |
| rpcMapping | DumpedData | RPC mapping for the targetted platform & version* | built-in mapping** |
| udp | boolean | Communicate over UDP where possible | false |
| autoAckTick | boolean | Automatically acknowledge UDP ticks | true |
| ssl | boolean | Connect via WSS | true |
* Dumping RPC mappings is not easy and there is no public tool that can do it for you. In case you need any help, feel free to ask us in our Discord server.
** Built-in mapping version can be checked in zombslib source code (rpcs.json).
After initializing a connection, you must wait for the server to accept your join request and send you an EnterWorldResponse.
game.on("EnterWorldResponse", (response: EnterWorldResponse) => { if (response.allowed) { game.setPlatformRpc(/* your platform, same as in your RPC mapping */); game.startTcpStreamRpc(0, 0); }});The snippet above does two important things:
- First, it sends a
SetPlatformRpcto the server, which is required before anything else can be done. Not sure why they designed it that way but whatever. - Then,
StartTcpStreamRpcis sent which informs the server that you are ready to start receiving entity updates.
Controlling the bot
Section titled “Controlling the bot”Just like with Mason Service, zombslib handles all decoding/encoding for you and exposes a user-friendly API. Here’s a couple very simple examples:
Example 1
Section titled “Example 1”In this example, every tick (servers run at 64 tps) all the newly created entities, meaning ones which have just appeared in bot’s FOV, are printed to the console.
game.on("EntityUpdate", (u: EntityUpdate) => { console.log(u.createdEntities?.flatMap((uid) => game.getEntityByUid(uid)));});Example 2
Section titled “Example 2”Here, the bot repeats every chat message it sees (as long as it didn’t come from the bot itself).
game.on("ReceiveChatMessageRpc", (rpc: ReceiveChatMessageRpc) => { if (rpc.uid !== game.getMyUid()) { game.sendChatMessageRpc("Local", rpc.message); }});Methods
Section titled “Methods”Querying entities
Section titled “Querying entities”-
getEntityList():
Map<number, NetworkEntity>
Retrives all entities, maps them to their uids. -
getEntitiesByType(type: EntityType):
Map<number, NetworkEntity>
Retrives entities of given type, maps them to their uids. -
getEntityByUid(uid: number):
NetworkEntity?
Retrives entity with given uid if it exists. -
getPlayerByName(name: string):
NetworkEntity?
Retrives player entity with given uid if it exists. -
getSelf():
NetworkEntity?
Retrives controlled bot entity (“local player”) if it exists (it should). -
getSelfUid():
number
Retrives controlled bot’s uid.
Position translation
Section titled “Position translation”-
toWorldPos(pos: Vector2):
Vector2
Translates server position to world (Unity) position. -
toServerPos(pos: Vector2):
Vector2
Translates Unity position to server position.
-
getEnterWorldResponse():
EnterWorldResponse
Retrives lobby join response. -
shutdown():
void
Disconnects the bot. -
send(data: Uint8Array, udp: boolean):
void
Sends raw data to the server. Used internally.
All OutRpc’s got their own method and should be pretty straightforward to understand.
Notes:
- The few RPC’s with more than 3 fields are passed as entire objects instead of as separate function args.
InputRpccan be a partial.- Due to
SetSkinRpcbeing recognized as an “array rpc”, its corresponding method is defined assetSkinRpc(rpcs: SetSkinRpc[]).
Events
Section titled “Events”-
RPC’s
Event name:"ExampleRpc"
Parameters:(rpc: ExampleRpc, extra: RpcExtra)// interface RpcExtra {// tick?: number;// udpCookie?: number;// transport: "tcp" | "udp";// }game.on("KillFeedRpc", (rpc: KillFeedRpc, extra: RpcExtra) => ...); -
RPC’s (any)
Event name:"Rpc"
Parameters:(name: string, rpc: object, extra: RpcExtra)// This will trigger on any RPC. Let's say that you receive an AirDropRpc:// name => "AirDropRpc"// rpc => type AirDropRpcgame.on("Rpc", (name: string, rpc: object, extra: RpcExtra) => ...); -
Schemas
Event name:"SchemaExample"
Parameters:(data: ExampleRpc)or(data: SchemaExample[])(majority)game.on("SchemaGeneral", (data: SchemaGeneral) => ...);game.on("SchemaWeapons", (data: SchemaWeapon[]) => ...); -
Any packet
Event name:"RawData"
Parameters:(data: Uint8Array, transport: "tpc" | "udp", packetId: PacketId) -
Entity update
Event name:"EntityUpdate"
Parameters (TCP):(data: EntityUpdate, packetId: PacketId)
Parameters (UDP):(data: UdpTick, packetId: PacketId) -
Lobby join response
Event name:"EnterWorldResponse"
Parameters:(response: EnterWorldResponse) -
UDP connect response
Event name:"UdpConnectResponse"
Parameters:(response: UdpConnectResponse)
Entity types
Section titled “Entity types”EntityType enum:
| NAME | ID | NOTES |
|---|---|---|
| ZombieEntity | 0x0ed7fd27 | |
| SprayEntity | 0x1e1837cc | |
| PortalEntity | 0x2293598d | |
| PlayerEntity | 0x4254ae62 | Includes bots |
| CrystalEntity | 0x58eafdbd | Crystal Clash crystals |
| VehicleEntity | 0x5d0b456b | e.g. Hoverboard |
| PhysicsEntity | 0x8e187e23 | Likely unused |
| PlaneEntity | 0x8fe5d35b | |
| ItemEntity | 0xa7ecd754 | |
| ProjectileEntity | 0xb6cebbaa | |
| BuildingEntity | 0xdf853d95 | |
| PropEntity | 0xecaa7004 | e.g. Bush |
| GasEntity | 0xf15cdbb8 | The zone |
| NpcEntity | 0xf4de4be0 | No longer in use |
| UnknownEntity | 0xf5cf683e | No idea |
| PlayerBuildingEntity | 0xf63a37d6 | e.g. Snow Wall |