69 lines
3.0 KiB
Markdown
69 lines
3.0 KiB
Markdown
|
|
# rudder.build/server
|
||
|
|
|
||
|
|
The game server of Rudder for Go. It calls the functions of the modules of a project for a player
|
||
|
|
the game server names, and it updates the profile of a player, its ban and the environment of
|
||
|
|
the key. It uses the standard library only.
|
||
|
|
|
||
|
|
## Install
|
||
|
|
|
||
|
|
```sh
|
||
|
|
go get rudder.build/server@v1.0.0
|
||
|
|
```
|
||
|
|
|
||
|
|
The module path is resolved through the `go-import` meta tag of `rudder.build/server`; set
|
||
|
|
`GOPRIVATE=rudder.build` (or `GONOSUMDB`/`GONOSUMCHECK`) so the Go command fetches it from the
|
||
|
|
Rudder Gitea instead of the public proxy.
|
||
|
|
|
||
|
|
## Generate the client
|
||
|
|
|
||
|
|
In the Go module of the game server, where `rudder project use` chose the project:
|
||
|
|
|
||
|
|
```sh
|
||
|
|
rudder server generate --lang go --output ./rudderclient --package rudderclient \
|
||
|
|
[--game-address https://api.rudder.build] [--environment staging|prod]
|
||
|
|
```
|
||
|
|
|
||
|
|
The client follows the newest release of the environment, staging by default. It writes a
|
||
|
|
package with a `Client` and one subpackage per module (`stores`, `battlepass`), a method per
|
||
|
|
function, the functions marked `server` included, and the types of their arguments and results.
|
||
|
|
Every method names the player first. Generate it again when a release changes the functions or
|
||
|
|
their types.
|
||
|
|
|
||
|
|
## Use
|
||
|
|
|
||
|
|
```go
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
|
||
|
|
"game/rudderclient"
|
||
|
|
"rudder.build/server"
|
||
|
|
)
|
||
|
|
|
||
|
|
client := rudderclient.New(server.Options{ServerKey: serverKey})
|
||
|
|
|
||
|
|
environment, err := client.Server.Environment(ctx)
|
||
|
|
purchase, err := client.Stores.Buy(ctx, playerID, rudderclient.StoresBuyArguments{Offer: "pumpkin-pack"}, nil)
|
||
|
|
|
||
|
|
err = client.Server.SetPlayerProfile(ctx, playerID, server.Profile{Nickname: "Ada", Avatar: "https://example.com/ada.png"})
|
||
|
|
err = client.Server.BanPlayer(ctx, playerID, server.Ban{Until: time.Date(2026, 12, 1, 0, 0, 0, 0, time.UTC), Reason: "cheating"})
|
||
|
|
err = client.Server.UnbanPlayer(ctx, playerID)
|
||
|
|
```
|
||
|
|
|
||
|
|
The generated root `Client` holds `Server *server.Client` and a client per module; `New` takes
|
||
|
|
`server.Options` (`ServerKey`, `Address`, `Attempts`, `HTTPClient`).
|
||
|
|
|
||
|
|
- **Environment.** `client.Server.Environment(ctx)` answers `staging` or `prod`, the environment
|
||
|
|
of the server key. The header of the generated files names the environment they were generated
|
||
|
|
from, which can be another one.
|
||
|
|
- **Calls.** A query reads and a mutation changes data, for the player id the method names
|
||
|
|
first. A mutation sends an `Idempotency-Key`, generated for each call unless
|
||
|
|
`server.MutationOptions{IdempotencyKey: ...}` is passed. A banned player is refused to the game
|
||
|
|
client only.
|
||
|
|
- **Profile and ban.** `SetPlayerProfile` replaces the nickname and the avatar, `BanPlayer` bans
|
||
|
|
until the moment given, `UnbanPlayer` lifts it.
|
||
|
|
- **Errors.** A refused call answers `*server.Error` with `Code`, `Message` and `Status`; use
|
||
|
|
`errors.As` to read it.
|
||
|
|
- **Retries.** A request that got no answer or the answer `try_again` is sent again after the
|
||
|
|
`Retry-After` it gave or a short backoff, at most `Attempts` times (5), with the same
|
||
|
|
idempotency key. 429 is not retried. Pass `context.Context` to cancel.
|