Bot/Guide

This guide will lead you through creating a bot in Smiley Face Game.

If you're familiar with APIs, consider reading the official API documentation.

## Prerequisites

* Some knowledge of JavaScript
* A code editor *(preferably Visual Studio Code)*
* Node.js *(LTS or Current, doesn't matter)*
* A package manager *(preferably npm or pnpm)*

## Installation

Create a new folder anywhere on your PC, as this will be where you store the bot's code. Copy the folder's address, then navigate to it with cmd or whatever terminal you use (`cd [address]`).

Inside the bot's folder, run `npm init -y`. This will create a package.json file, which is essential to installing the API. To install the API, run `npm i @smiley-face-game/api`.

With pnpm, the process is similar. `pmpm init`, then `pnpn i @smiley-face-game/api`.

## Programming the bot

### Setup

Open the bot's folder in your code editor. Then, create a new file called `index.mjs`. Having .mjs instead of .js allows using modules, ultimately being able to use the SFG API. The bot won't work if you simply use .js. Also, in the package.json file, change the `"main"` property from `"index.js"` to `"index.mjs"`.

Copy and paste the following into your index.mjs file:

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

async function main() {
 useDev();
 /// this is where you'll code the bot
}

main().catch(console.error);

```

Let's go over what this piece of code does:

First, it imports some functions from the Smiley Face Game API. We'll go over what they mean in a bit.

Then, a `main()` function is defined. This will be where we code our bot. Before that, however, the function is ran, an use of hoisting (using functions before they are defined). The `catch(console.error)` after that enables logging errors into the console if the bot runs into an error. In the `main()` function now, the `useDev()` function tells the bot to use the dev version of the game, as the normal version can't be played on yet.

### Authentication

Next, you have to choose how to log the bot in: through a guest account, or through an existing account. Logging the bot in through your account allows the bot to automatically gain edit, but you have to be extra careful to censor the password when pasting the bot's code somewhere for help. Depending on the method you use, you will have to write different code below `useDev()` for logging in:

* Logging in with a guest account:
```
const client = await auth({ username: 'botty' });

```
* Logging in with an existing account:
```
const client = await auth({ email: 'botty@yahoo.co.jp', password: '12345678' });

```

### Joining a world

Now that the bot can log into Smiley Face Game, it has to join a world to actually do anything. You have a choice to either make the bot create a new dynamic world and join it, or join an existing saved world:

* Creating a dynamic world:
```
const world = await client.connect({
 type: 'create',
 name: 'World Name',
 width: 15,
 height: 35,
});

```
* Joining an existing world:
```
const world = await client.connect({
 type: 'join',
 id: 'id visible in url bar',
 });

```

Once all that is done, run the script. If you use Visual Studio Code, at the top click **Run** -> **Start Debugging** -> **Node.js**. You can also start the bot opening the bot's folder in your terminal, then running `node .` . Check wherever you think the bot will appear. If it appears, great! If it doesn't appear, check the console for any errors and try to fix them. If you're having trouble fixing them, you can ask for help in the #programming channel in the Discord server.

### Responding to commands

First, we have to make a for await loop. This waits for an interaction in the world then runs some code. However, the piece of code would actually run whenever the world is interacted with in any way, for example placing a block. We have to make it so it only runs when a command is run.

```
for await (const message of connection) {
 if (message.packetId === 'SERVER\_CHAT') {
 // activated when a message is sent
 }
}

```
This doesn't do anything yet though. To do anything we need to place some code in place of the comment. We also need another if statement to check if a player's message contains the command.

```
for await (const message of connection) {
 if (message.packetId === 'SERVER\_CHAT') {
 if (message.message === '!hello') {
 connection.chat('hi!!!');
 }
 }
}

```
Restart the bot, and send `!hello`. If everything goes right, the bot should send "hi!!!" in the chat.

To add more commands, just copy the if statement above inside the `if (message.packetId === 'SERVER_CHAT')` snippet and customize the command and the message. We'll make another command now, a counter of how many times it has been called.

In the `main()` function, at the start, define a variable: `let called = 0;`. This will be the variable to keep track of how many times the command was called. Add the if statement (the command) in the `if (message.packetId === 'SERVER_CHAT')` part. You are free to rename it to what you want, but in this tutorial we'll rename it to `!counter`.

Inside the command, we increment the `called` variable by `called++;`. Afterwards, we can send a message in the chat to notify the player how many times the command was called: `connection.chat(`This command has been used ${called} times.`);`

Now, call the command a few times, and see the counter increase. The full command will be:

```
if (message.message === '!counter') {
 called++;
 connection.chat(`This command has been used ${called} times.`);
}

```