Skip to content

We want to help you make the best web games possible. That’s why we’ve been working on the following two projects and prototypes:


Poki Networking Library


The Poki Networking Library (Netlib) is a peer-to-peer library for web games that uses WebRTC datachannels to provide direct UDP connections between players. You can think of it like the Steam Networking Library, but for the web. Netlib aims to make using WebRTC in game development as simple as the WebSocket interface.

πŸ”— Check the project out on Github npm
Netlib


Project status

This library is still under heavy development and considered in alpha. The library API is likely to change without any warning or updates to the major version. Please make sure to get in touch if you want to launch your project with our Netlib.

One missing feature that’s on our roadmap is Lobby Listing and Discovery. Currently, you can only connect peers by having players externally share a lobby code.


Main advantages
Peer-to-Peer (P2P)

Clients connected to each other using this netlib will be connected directly without a central server in between (unless using the fallback TURN server). This has three main advantages:

  • No server costs, there is no server running the game.
  • No double implementation of the game. You don’t need to write your game logic twice (for the client and the server).
  • When players are living close by, the latency is often a lot lower than when connected via a server.
UDP

Most web games rely on WebSockets or HTTP for communication (which is always a TCP connection). For real time multiplayer games, however, the UDP protocol is preferred. The main reason is that when one packet is slow or dropped, UDP doesn’t pause new and already received packets - and this is great for things like position updates. The Poki netlib also supplies a reliable data channel useful for chat or NPC spawn events.


Set-up

First add @poki/netlib as a dependency to your project:

# either using yarn:
yarn add @poki/netlib
# or using npm:
npm i @poki/netlib

Then you can import and create a Network interface:

import { Network } from '@poki/netlib'
const network = new Network('<your-game-id-here>')
(any random UUID is a valid game-id, but if your game is hosted at Poki you should use Poki’s game-id)


Next up: Read the Basic Usage Guide and make sure to check out the example code.


STUN, TURN & SIGNALING Backend

The netlib is a peer-to-peer networking library, which means players are connected directly to each other and data sent between them is never sent to a server. With that said, there needs to be a signaling service to set these connections up. These backend and STUN/TURN servers are hosted by Poki for free, however, you have the freedom to host the backend yourself.



Arbitrary User Data Store (AUDS)


Ever run into the case where your game needs a simple backend to store levels or other user-generated content? Well, we have created AUDS, The Poki Arbitrary User Data Store just for that. It is a prototype that lets you store any data in our backend, and it will return a code for you to share with a player. You could use this server for user-generated content like levels, a leaderboard, or even a non-real-time multiplayer game!

πŸ”— Check out the project on Postman

Below is a collection of the basic endpoints for AUDS. (This API is just a prototype, subject to change β€” do not use in production yet)

GET    List userdata

https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests?q=type:arena-1v1

Supported parameters

  • ?q=key:value β€” Only supports simple matching for now, but this will change
  • ?sort=key or ?sort=-key β€” Allows you to sort the userdata entries by a “values” key
  • ?includedata β€” will also include the “data” in the listing
Example Request
curl --location 'https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests?q=type%3Aarena-1v1'
Example Response
{
    "total": 1,
    "items": [
        {
        "id": "ce702oq1gkcvlv1tmlgg",
        "meta": {
            "revision": 1,
            "created_at": "2022-12-05T14:34:11.677983Z",
            "expires_at": "2023-12-05T14:34:11.677983Z",
            "expires_in": 31536000
        },
        "values": {
            "levelname": "Test level",
            "note": "'values' can only be key/value pairs where values can only be string or number",
            "type": "arena-1v1"
        }
        }
    ]
}

q :type:arena-1v1

Content-Type:  application/json

Vary:  Origin

X-Content-Type-Options:  nosniff

Date:  Mon, 05 Dec 2022 14:35:03 GMT

Content-Length:  325

Via:  1.1 google

Alt-Svc:  h3=”:443”; ma=2592000,h3-29=”:443”; ma=2592000

200 OK



POST    Create userdata

https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests

The /tests part in the URL is a freeform key, use whatever type you are saving.

The POST will return an id to fetch and a secret to be able to update the data later. This secret is never returned again by this API.

{
    "data": {
        "tiles": [1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0],
        "note": "data in userdata is freeform, can be anything."
    },
    "values": {
        "levelname": "Test level",
        "type": "arena-1v1",
        "note": "'values' can only be key/value pairs where values can only be string or number"
    }
}
Example Request
curl --location 'https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests' \
--data '{
    "data": {
        "tiles": [1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0],
        "note": "data in userdata is freeform, can be anything."
    },
    "values": {
        "levelname": "Test level",
        "type": "arena-1v1",
        "note": "'\''values'\'' can only be key/value pairs where values can only be string or number"
    }
}'
Example Response
{
    "id": "ce702oq1gkcvlv1tmlgg",
    "secret": "Qn8iO6bQVlGyVPkJhoi4oHwufb6GWgpgyedP5cO3fB39rzwTJZwg7N2n7GbLU3aG",
    "meta": {
        "revision": 1,
        "created_at": "2022-12-05T14:34:11.67798351Z",
        "expires_at": "2023-12-05T14:34:11.67798351Z",
        "expires_in": 31536000
    },
    "values": {
        "levelname": "Test level",
        "note": "'values' can only be key/value pairs where values can only be string or number",
        "type": "arena-1v1"
    }
}

Content-Type:  application/json

Vary:  Origin

X-Content-Type-Options:  nosniff

Date:  Mon, 05 Dec 2022 14:34:11 GMT

Content-Length:  383

Via:  1.1 google

Alt-Svc:  h3=”:443”; ma=2592000,h3-29=”:443”; ma=2592000

201 CREATED



GET    Fetch userdata by ID

Example Request
curl --location 'https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests/ce702oq1gkcvlv1tmlgg'
Example Response
{
    "id": "ce702oq1gkcvlv1tmlgg",
    "meta": {
        "revision": 1,
        "created_at": "2022-12-05T14:34:11.677983Z",
        "expires_at": "2023-12-05T14:37:02.733083Z",
        "expires_in": 31536000
    },
    "values": {
        "levelname": "Test level",
        "note": "'values' can only be key/value pairs where values can only be string or number",
        "type": "arena-1v1"
    },
    "data": {
        "note": "data in userdata is freeform, can be anything.",
        "tiles": [
            1,
            0,
            0,
            0,
            1,
            1,
            1,
            1,
            1,
            0,
            0,
            1,
            0,
            0,
            1,
            0
        ]
    }
}

Content-Type:  application/json

Vary:  Origin

X-Content-Type-Options:  nosniff

Date:  Mon, 05 Dec 2022 14:37:02 GMT

Content-Length:  410

Via:  1.1 google

Alt-Svc:  h3=”:443”; ma=2592000,h3-29=”:443”; ma=2592000

200 OK



POST    Update userdata with secret

https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests/ce702oq1gkcvlv1tmlgg
{
    "secret": "Qn8iO6bQVlGyVPkJhoi4oHwufb6GWgpgyedP5cO3fB39rzwTJZwg7N2n7GbLU3aG",
    "data": {
        "tiles": [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1]
    },
    "values": {
        "levelname": "Test level (edited)",
        "type": "arena-1v1"
    }
}
Example Request
curl --location 'https://auds.poki.io/v0/use-your-poki-game-id/userdata/tests/ce702oq1gkcvlv1tmlgg' \
--data '{
    "secret": "Qn8iO6bQVlGyVPkJhoi4oHwufb6GWgpgyedP5cO3fB39rzwTJZwg7N2n7GbLU3aG",
    "data": {
        "tiles": [1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1]
    },
    "values": {
        "levelname": "Test level (edited)",
        "type": "arena-1v1"
    }
}'
Example Response
{
    "id": "ce702oq1gkcvlv1tmlgg",
    "meta": {
        "revision": 2,
        "created_at": "2022-12-05T14:34:11.677983Z",
        "updated_at": "2022-12-05T14:41:58.223397772Z",
        "expires_at": "2023-12-05T14:41:58.223397772Z",
        "expires_in": 31536000
    },
    "values": {
        "levelname": "Test level (edited)",
        "type": "arena-1v1"
    }
}

Content-Type:  application/json

Vary:  Origin

X-Content-Type-Options:  nosniff

Date:  Mon, 05 Dec 2022 14:41:58 GMT

Content-Length:  273

Via:  1.1 google

Alt-Svc:  h3=”:443”; ma=2592000,h3-29=”:443”; ma=2592000

201 CREATED


Main Contributors