@smiley-face-game/api
TypeScript icon, indicating that this package has built-in type declarations

0.3.0 • Public • Published

@smiley-face-game/api

The API package for @smiley-face-game. This package is used by the client itself, and is made a public NPM package so bot creators can utilize this package.

Contents

Installation

With a Package Manager

Using NPM

npm i @smiley-face-game/api

Using Yarn

yarn add @smiley-face-game/api

Using PNPM

pnpm add @smiley-face-game/api

With HTML

RECOMMENDED: Using SkyPack to serve ES Modules

<!-- For modern browsers, recommended. -->
<script type="module">
  import * as sfg from "https://cdn.skypack.dev/@smiley-face-game/api";
  console.log(sfg);
</script>

Using UNPKG to serve JS

<!-- Imports an `sfg` global -->
<script src="https://unpkg.com/@smiley-face-game/api"></script>
<script>
  console.log(sfg);
</script>

Examples

Usage in Different Environments

Node (ES Modules) [RECOMMENDED]

// index.mjs
import { useDev } from "@smiley-face-game/api";
useDev();

Node (CommonJS Modules)

// index.cjs
const { useDev } = require("@smiley-face-game/api");
useDev();

HTML ES Modules

<!-- index.html -->
<script type="module">
  import { useDev } from "https://cdn.skypack.dev/@smiley-face-game/api";
  useDev();
</script>

HTML Global

<!-- index.html -->
<script src="https://unpkg.com/@smiley-face-game/api"></script>
<script>
  sfg.useDev();
</script>

Authentication

import { auth, useDev } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  // tells SFG to use the development servers (dev-smiley-face-game.sirjosh3917.com)
  useDev();

  // authenticates as a guest, with the username "wee"
  const guest = await auth({ username: "wee" });

  // logs in using an email and password
  const user = await auth({
    email: "alice@alicenbob.com",
    password: "1234",
  });
}

Connecting to a World

import { auth, useDev } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  useDev();
  const client = await auth({ username: "aaa" });

  // generates a *new* dynamic world.
  const newDynamic = await client.connect({
    type: "create",
    name: "Connection Example",
    width: 25,
    height: 25,
  });

  // connects to an *existing* dynamic world.
  const existingDynamic = await client.connect({
    type: "create",
    id: newDynamic.init.worldId,
  });

  // connects to a *saved* world - these are owned by someone
  const saved = await client.connect({
    type: "join",
    id: "00000000-0000-0000-0000-000000000000",
  });
}

Chatting

import { auth, useDev } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  useDev();
  const client = await auth({ username: "chatbot" });

  const connection = await client.connect({
    type: "create",
    name: "Chat Example",
    width: 10,
    height: 10,
  });

  for await (const message of connection) {
    // if we received a chat message
    if (message.packetId === "SERVER_CHAT") {
      if (message.message === "!hello") {
        // we'll send something back
        connection.chat("hi!!!");
      }
    }
  }
}

Placing Blocks

import { auth, useDev } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  useDev();
  const client = await auth({ username: "blockbot" });

  const connection = await client.connect({
    type: "create",
    name: "Blocks Example",
    width: 10,
    height: 10,
  });

  // use `tileJson` to get the numeric id of `basic-red`.
  // for the names of tiles, it's best to consult `tiles.json`
  // you can find a `name` -> `image` mapping at:
  //   `packages/client/src/assets/tiles`
  const redId = connection.tileJson.id("basic-red");

  // fill the world with it
  for (let y = 0; y < connection.init.size.height; y++) {
    for (let x = 0; x < connection.init.size.width; x++) {
      connection.place(redId, { x: x, y: y });
    }
  }
}

Placing Signs

import { auth, useDev } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  useDev();
  const client = await auth({ username: "blockbot" });

  const connection = await client.connect({
    type: "create",
    name: "Signs Example",
    width: 10,
    height: 10,
  });

  const signId = connection.tileJson.id("sign");

  // place a sign, using the third argument for additional data
  // fun fact: you can place a sign without any additional data at all! if you
  // don't specify any data, you'll get a blank sign
  connection.place(
    signId,
    { x: 1, y: 1 },
    {
      kind: "sign",
      text: "hello world!",
    }
  );
}

Handling Players and Blocks

import { auth, useDev, Game, TileLayer } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  useDev();
  const client = await auth({ username: "blockbot" });

  const connection = await client.connect({
    type: "create",
    name: "Players and Blocks Example",
    width: 10,
    height: 10,
  });

  // create a new "game" instance. the game instance is the **exact same code**
  // that the actual game itself uses. that's right - your bot can be just as
  // sophisticated as a player!
  //
  // in our case, we'll use the `game` to handle blocks for us.
  const game = new Game(connection.tileJson, connection.init);

  for await (const message of connection) {
    // the first line of code in the loop should be this. this will tell the
    // game about messages received and handle them accordingly.
    //
    // for our purposes, we only care about the fact that it will handle blocks
    // (and players).
    game.handleEvent(message);

    // if the player says "tell me"
    if (message.packetId === "SERVER_CHAT" && message.message === "tell me") {
      // we use `game.players` to get access to the players.
      const sender = game.players.get(message.playerId);

      // get the ID of the block at 0, 0 (upper left corner of world)
      const blockId = game.blocks.blockAt(0, 0, TileLayer.Foreground);

      // the blockId is a numeric number that won't make sense to a human.
      // let's change it to the name of the texture, using `tileJson`!
      const blockName = connection.tileJson.texture(blockId);

      // tell them what block is at 0, 0
      connection.chat(`hey ${sender.name}: there is a ${blockName} at 0, 0!`);
    }
  }
}

Simulating Physics

import { auth, useDev, Game } from "@smiley-face-game/api";

main().catch(console.error);
async function main() {
  useDev();
  const client = await auth({ username: "blockbot" });

  const connection = await client.connect({
    type: "create",
    name: "Physics Example",
    width: 10,
    height: 10,
  });

  const game = new Game(connection.tileJson, connection.init);

  // the `game.update()` function takes the total number of elapsed milliseconds
  // let's start recording right now as the start of physics simulation
  const start = Date.now();

  // now, we call `game.update` every `game.physics.optimalTickRate` milliseconds,
  // passing in the total number of milliseconds since `start`.
  //
  // this will run the physics system, so we can get accurate values for x and y.
  // physics in your bot - isn't that great?
  setInterval(() => game.update(Date.now() - start), game.physics.optimalTickRate);

  for await (const message of connection) {
    game.handleEvent(message);

    if (message.packetId === "SERVER_CHAT" && message.message === "where am i") {
      const player = game.players.get(message.playerId);

      const { x, y } = player.position;
      connection.chat(`you are at ${x}, ${y}!`);
    }
  }
}

Package Sidebar

Install

npm i @smiley-face-game/api

Weekly Downloads

3

Version

0.3.0

License

MIT

Unpacked Size

601 kB

Total Files

179

Last publish

Collaborators

  • sirjosh3917