Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major effort to re-organize, tidy-up, and fix the documentation! #62

Merged
merged 40 commits into from
Jun 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
b1efdb8
rename from Client-side SDK -> API to Client-side SDK -> Usage. merge…
endel May 14, 2021
7cc9dda
rename github links to 'view source-code'
endel May 14, 2021
85b820b
use same title for client and room
endel May 14, 2021
8954f19
rename 'state handling' to 'state synchronization'
endel May 14, 2021
99a14cc
add disclaimer
endel May 14, 2021
689a1b8
add delimiters to Room sections
endel May 14, 2021
d5d0ca7
cross-referencing room <-> client sections
endel May 14, 2021
2f31de5
note async/await support on lifecycle events
endel May 14, 2021
73289e2
add state sync excalidraw diagram
endel May 14, 2021
fb03f1b
minor fixes on state sync
endel May 17, 2021
513fa40
add state -> overview back. improving schema documentation.
endel May 18, 2021
3072bae
move setschema above collectionschema
endel May 18, 2021
138d2a0
formatting
endel May 18, 2021
2ae2bbe
add TODO
endel May 18, 2021
de811de
minor improvements. clarify schema-codegen usage
endel May 18, 2021
6219fdf
clarifying
endel May 18, 2021
975db5c
rename typescript headline
endel May 18, 2021
f9ca7a6
wording
endel May 18, 2021
b6289c9
use tip instead of warning for typescript heading
endel May 18, 2021
bdda4d2
clarifying schema/state at the top
endel May 18, 2021
25e1a5c
add link for schema
endel May 18, 2021
b317895
move type 'keyword' tip
endel May 18, 2021
1d28e19
schema complex types
endel May 18, 2021
f0aeee7
fix link to collection of items
endel May 18, 2021
65f3a11
command pattern - testability
endel May 18, 2021
ecb5329
improving server/room pages
endel May 18, 2021
e62a53c
improving server/room pages
endel May 18, 2021
6a8a6d0
wording
endel May 18, 2021
69fd39c
update room description
endel May 18, 2021
79f3ced
fix: server api -> server
endel May 18, 2021
7119d25
update setState() description
endel May 18, 2021
daddf4d
rename layer -> channel on room description
endel May 18, 2021
9a8fa1b
use 'npm start' rather than 'node server.js' for debugging
endel May 19, 2021
e6510c5
typos and grammar fixes
endel May 28, 2021
e75abd9
move server/client into server/room. add websocket close codes. colys…
endel Jun 1, 2021
0ebef12
clarify what a 'client' instance is
endel Jun 1, 2021
161e73b
update client clarification
endel Jun 1, 2021
30005e5
describe allowReconnection() return type. colyseus/colyseus#414
endel Jun 1, 2021
9135368
document closing codes colyseus/colyseus-unity3d#157
endel Jun 1, 2021
08fcff7
Merge branch 'master' into tidying-up-everything
endel Jun 1, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
15 changes: 15 additions & 0 deletions backup/state-handling/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# State Handling

The room handlers are **stateful** in Colyseus. Each room holds its own state. The mutations of the state are synchronized automatically to all connected clients.

## Serialization methods

- [Schema](/state/schema/) (default)
- [Fossil Delta](/state/fossil-delta/) (deprecated)

## When the state is synchronized

- When the user successfully joins the room, he receives the full state from the server.
- At every [patchRate](/server/room/#patchrate-number), binary patches of the state are sent to every client (default is `50ms`)
- [`onStateChange`](/client/room/#onstatechange) is called in the client-side after every patch received from the server.
- Each serialization method has it's own particular way to handle incoming state patches.
108 changes: 0 additions & 108 deletions docs/best-practices/command-pattern.md

This file was deleted.

138 changes: 132 additions & 6 deletions docs/best-practices/overview.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,138 @@
# Best practices with Colyseus
# Best practices & recommendations

!!! Warning "Important"
This section needs improvement and more examples! Each paragraph needs it's own page with thorough examples and better explanation.
!!! Note "Work-in-progress"
This documentation page is not complete

- Keep your room classes as small as possible, without game logic.
This section provides general recommendations and best practices to keep your codebase healthy and readable for your team. They are all optional, but if followed are going to improve code readability and cleanliness.

- Keep your room classes as small as possible, delegating game-specific functionality to other composable structures.
- Keep your synchronizeable data structures as small as possible
- Ideally, each class extending `Schema` should only have field definitions.
- Custom getters and setters methods can be implemented, as long as you don't have game logic in them.
- Your game logic should be handled by other structures, such as:
- See how to use the [Command Pattern](/best-practices/command-pattern/).
- An Entity-Component System. We currently lack an ECS package that works well with Colyseus, some work [has started trying to combine ECSY with @colyseus/schema](http://github.com/endel/ecs).
- The [Command Pattern](#the-command-pattern).
- An [Entity-Component System](#entity-component-system-ecs).

## Unit Testing

> TODO: we need to provide a `@colyseus/testing` package to allow easily mocking the `Room` class and triggering its lifecycle events, as well as creating dummy clients.

## Design Patterns

### The Command Pattern

**Why?**

- Models ([`@colyseus/schema`](https://github.com/colyseus/schema)) should contain mostly data, without heavy game logic.
- Rooms should have as little code as possible, and forward actions to other structures

**The command pattern has several advantages, such as:**

- It decouples the classes that invoke the operation from the object that knows how to execute the operation.
- It allows you to create a sequence of commands by providing a queue system.
- Implementing extensions to add a new command is easy and can be done without changing the existing code.
- Have strict control over how and when commands are invoked.
- Improves code readability and the possibility of unit testing.

#### Usage

Installation

```
npm install --save @colyseus/command
```

Initialize the `dispatcher` in your room implementation:

```typescript fct_label="TypeScript"
import { Room } from "colyseus";
import { Dispatcher } from "@colyseus/command";

import { OnJoinCommand } from "./OnJoinCommand";

class MyRoom extends Room<YourState> {
dispatcher = new Dispatcher(this);

onCreate() {
this.setState(new YourState());
}

onJoin(client, options) {
this.dispatcher.dispatch(new OnJoinCommand(), {
sessionId: client.sessionId
});
}

onDispose() {
this.dispatcher.stop();
}
}
```

```typescript fct_label="JavaScript"
const colyseus = require("colyseus");
const command = require("@colyseus/command");

const OnJoinCommand = require("./OnJoinCommand");

class MyRoom extends colyseus.Room {

onCreate() {
this.dispatcher = new command.Dispatcher(this);
this.setState(new YourState());
}

onJoin(client, options) {
this.dispatcher.dispatch(new OnJoinCommand(), {
sessionId: client.sessionId
});
}

onDispose() {
this.dispatcher.stop();
}
}
```

How a command implementation looks like:

```typescript fct_label="TypeScript"
// OnJoinCommand.ts
import { Command } from "@colyseus/command";

export class OnJoinCommand extends Command<YourState, {
sessionId: string
}> {

execute({ sessionId }) {
this.state.players[sessionId] = new Player();
}

}
```

```typescript fct_label="JavaScript"
// OnJoinCommand.js
const command = require("@colyseus/command");

exports.OnJoinCommand = class OnJoinCommand extends command.Command {

execute({ sessionId }) {
this.state.players[sessionId] = new Player();
}

}
```

#### See more

- See [command definitions](https://github.com/colyseus/command/blob/master/test/scenarios/CardGameScenario.ts)
- See [usage](https://github.com/colyseus/command/blob/master/test/Test.ts)
- See [implementation](https://github.com/colyseus/command/blob/master/src/index.ts)

### Entity-Component System (ECS)

We currently do not have an official ECS (Entity-Component System), although we've seen members of the community implement their own solutions.

!!! Warning "Very experimental"
Some work [has started trying to combine ECSY with @colyseus/schema](http://github.com/endel/ecs).
Loading