# Developing for Dark Forest!

Dark Forest developer resources

With Ethereum gaming, the closed source server model has been replaced by a few open source Ethereum contracts. This means you can hack literally every other part of the experience to your liking.

Dark forest [publishes npm packages](https://www.npmjs.com/search?q=%40darkforest_eth) for its contract addresses, types, and utilities functions and releases an [official subgraph](https://github.com/darkforest-eth/developer-guides/tree/38f849f540ac29b11be0eb1da486d943db164fab/subgraph.md) to ease your development workflow.

## Plugins Developers

Anyone can get started scripting with the Dark Forest Console. Just look out for the command that is printed from your mouse actions. You can copy and repaste that command to run it again any time, or modify it slightly to try something new. Mostly you'll just be replaying a command so dont worry too much about breaking anything, give it a shot. The [df object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameManager.default.md) and the [ui object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameUIManager.default.md) are the main api surfaces for plugins developers so you'll want to familiarize yourself.

Our community plugins developers have written mini maps, automation plugins, remote miners and much much more. Check the [Dark Forest Community Plugins Showcase](https://plugins.zkga.me/) for inspiration and to copy existing plugins and make them your own. Please join the community by submitting your plugins back there as well.

## Client developers

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

## Contract Developers

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.

## Circuits developers

Dark Forest's innovative gameplay comes in no small part from its [ZK circuits](https://github.com/darkforest-eth/circuits) design utilizing [iden3's circomlib](https://github.com/iden3/circomlib)

## Unaudited Community Resources

**WARNING** Nothing in the Dark Forest ecosystem has any guarantee of being audited. Smart contracts could be malicious or be found to be insecure. Further, all plugins and pasted code in the Dark Forest console have access to your private key and ability to sign transactions (without a cpnfirmation popup). This means they could now or in the future take all your funds, planets, artifacts etc from your burner wallet. You should rotate burner wallets often, not keep more funds or nfts than you're willing to lose, and be careful using any plugins that you haven't written yourself or by someone you trust completely. Further, some plugins dynamically load dependencies under the hood meaning a 'safe' plugin could become unsafe in the future! All use is at your own risk.

Theres a whole wild world of amazing community creations. They're mostly being tracked at the [awesome darkforest repo](https://github.com/snowtigersoft/awesome-darkforest)


# What is an RPC endpoint?

As a decentralized game, Dark Forest stores all public game data on a *blockchain*. Currently, Dark Forest v0.6 is run on the [xDAI blockchain](https://www.xdaichain.com/)--an EVM compatible sidechain.

To connect to and retrieve data from a blockchain, you'll need to connect to a *node* on the blockchain network. A *node* is a participant in the network that stores and serves the latest blockchain state. Users who wish to download blockchain data can either run a node themselves, or connect to a publicly-provided node via the node's *RPC endpoint*. An RPC (remote procedure call) endpoint is like a node's address: it's a URL which requests for blockchain data can be sent to.

The Ethereum [JSON-RPC spec](https://eth.wiki/json-rpc/API) defines the methods which you can use to retrieve data from a node. As a player or 3rd-party developer, you likely won't need to make RPC calls directly with this API--these calls are typically abstracted by web3 libraries like [ethers.js](https://docs.ethers.io/v5/).

By default, the Dark Forest webclient will connect to <https://rpc-df.xdaichain.com/>, a public endpoint provided by the xDAI team. xDAI maintains a fleet of nodes which respond to requests made to this endpoint. There are other public endpoints you can connect to as well; if you'd like a dedicated node to serve your requests, you can also run your own xDAI node and connect to the endpoint it exposes.


# Changing your RPC endpoint

You can change the RPC endpoint that the Dark Forest client connects to in the settings pane of the game.

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F107c00a0669bc080fb981b497a1275c649aa265b.png?generation=1622752883654441\&alt=media)

* In addition to the game default xDAI-provided <https://rpc-df.xdaichain.com> endpoint, xDAI also provides a number of other [public endpoints](https://www.xdaichain.com/for-developers/developer-resources).
* You can also run your own node locally [or on the cloud](/rename/connecting-to-the-blockchain/running-your-own-xdai-node)
* Cloud providers like [Quicknode](https://www.quicknode.com/) will run a node for you with a few clicks for a monthly fee.
* Last but not least, [Pocket Network](https://www.blog.pokt.network/darkforest/) has gifted the Dark Forest community an xDAI RPC load-balanced endpoint node at <https://poa-xdai.gateway.pokt.network/v1/lb/60b13899d3279c22da2a444d>


# Running your own xDAI node

## Why run your own xDai Node?

* No queue of other people's transactions
* No downtime. Thousands of other players are attempting to use the same free rpc endpoint as you otherwise!
* Faster access. The memory and cpu speed of the free rpc is not published. By running your own node you can use a beefier box.&#x20;

The clients that have known xDai support include [OpenEthereum](https://www.xdaichain.com/for-developers/install-xdai-client/parity) (formerly Parity) and [Nethermind](https://www.xdaichain.com/for-developers/install-xdai-client/nethermind).

## Why Nethermind

from xDai [docs](https://www.xdaichain.com/for-developers/install-xdai-client/nethermind)

> A majority of xDai validators are now running the Nethermind client. The latest version includes support for MEV via flashbots and increased default xDAI TxPool size from 1024 transactions to 2048.

## Why Digital Ocean for hosting

from Nethermind [docs](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/hardware-requirements)

> Generally the faster IO operations the better. For this reason Digital Ocean and UpCloud are so far the best cloud providers we have tested when running Nethermind nodes.

## 1. Setting up a Digital Ocean Instance

1. Buy a droplet (cloud computer). I recommend a machine with *at least* the following specs ($40/month):
   * `Ubuntu 20.4 / 8 GB / 4 CPUs 160 GB SSD Disk 5 TB transfer`
   * If this too slow, I synced a node in \~6 hours with the $80/month option

     > If your sync is very slow (extended beyond two days) then very likely your setup cannot catch up with the chain progress.
   * ![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F30b189753da9979dbf0f70ab75f79fa7751675d9.png?generation=1633130009834050\&alt=media)
2. Remotely [connect](https://docs.digitalocean.com/products/droplets/how-to/connect-with-ssh/) to the Droplet using ssh. Probably something like `ssh root@157.245.5.42`
3. You should see the following on success:
4. ![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb2d526c1f6f841bd61fd2c2c5f501449ecdbd912.png?generation=1633130005677758\&alt=media)

## 2. Install Nethermind and dependencies

*Note: these commands are verbatim from* [*here*](https://docs.nethermind.io/nethermind/ethereum-client/running-nethermind/running-the-client)

1. `wget [NETHERMIND_URL]` - use the most recent linux amd64 release from [downloads](https://downloads.nethermind.io/))  Probably something like `wget https://nethdev.blob.core.windows.net/builds/nethermind-linux-amd64-1.11.3-fe90423.zip`
2. `sudo apt-get update && sudo apt-get install libsnappy-dev libc6-dev libc6 unzip -y` - Linux dependencies
3. `unzip NETHERMIND_URL -d nethermind` - unzip to nethermind folder

At this point, I diverged from the basic installation. This is because there are some specific configuration settings that are nice for running a node (and playing Dark Forest).

## 3. Configure Nethermind for Dark Forest

So in the `nethermind` folder you will see `Nethermind.Launcher` and `Nethermind.Runner`.

* ![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fd1b91eeee4753c33072893acf1988a94b4861947.png?generation=1633130006577923\&alt=media)

From [ethhub](https://docs.ethhub.io/using-ethereum/ethereum-clients/nethermind/)

> Nethermind.Launcher is an interactive prompt that allows you to choose the network which then calls Nethermind.Runner with the appropriate config file. This is the quickest way to get up and running. Nethermind.Runner is the actual client binary similar to the geth binary and supports both cli options or a JSON configuration file. `Nethermind.Runner --config <path_to_config>`

I added some custom configurations, so I choose to use the `Nethermind.Runner` binary with my custom config file.

1. `cd nethermind`
   * We want to sync an xDai node, so here are the options for xDai (xdai\_dfdao is my custom config):&#x20;
   * ![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F063e3db236ad4364d1756b5edff05768c2691ead.png?generation=1633130010610154\&alt=media)
   * I choose to copy `xdai_pruned_mev.cfg` because:
     1. I want the experiment with [mev](https://www.xdaichain.com/for-developers/developer-resources/mev-and-flashbots) on xDai
     2. I want to save size by pruning, at the cost of historical queries: &#x20;

        > pruning is the process of removing some of the intermediary state nodes - it saves some disk space but makes most of the historical state queries fail.
2. `cp configs/CONFIG_FILE configs/YOUR_CONFIGNAME`
   * for me, this was `cp configs/xdai_pruned_mev.cfg configs/xdai_dfdao.cfg`

Edit your config file with something like `nano configs/xdai_dfdao.cfg` and change the following fields to allow access to your node from the internet: 1. Your JSON RPC should look like this:

```
 "JsonRpc": {
   "Enabled": true,
   "Timeout": 20000,
   "Host": "IP ADDRESS",
   "Port": 8545,
   "WebSocketsPort": 8546,
   "EthModuleConcurrentInstances": 6
 }
```

1. Under Network add a new field.

   ```
   "Network": {
   ...
    "ActivePeersMaxCount": 256,
   ```

   > if you have a good connection and a reasonable machine then setting --Network.MaxActiveSyncPeers to 256 (see NetworkConfig secion in configuration) should give much better fast sync times (we use 256 peers to get 5 hours syncs)
   >
   > * Note that even though `ActivePeersMaxCount` is [deprecated](https://docs.nethermind.io/nethermind/ethereum-client/configuration/network), this setting worked for me (and `MaxActiveSyncPeers`) didn't.
2. Exit and save the file

## 4. Run Nethermind in background

So now we're ready to go.

However, if you run `./Nethermind.Runner --config <path-to-config-file>` and logout, your process will stop.

To avoid this, you can use [nohup](https://www.geeksforgeeks.org/nohup-command-in-linux-with-examples/) and the `&` operator to run your process in the background.

1. `nohup ./Nethermind.Runner --config <path-to-config-file> &`
2. optional: If you want to enable Health [Checks](https://docs.nethermind.io/nethermind/ethereum-client/monitoring-node-health), run the following:
   * `nohup ./Nethermind.Runner --config <path-to-config-file> --HealthChecks.Enabled true &`

This command will create a new file `nohup.out` (name can be configured with `nohup ... > output.txt`) in the `nethermind` directory, with logs that you can inspect.

You can find the process id in order to stop the now backgrounded syncing process with `ps`:

```
root@ubuntu-s-4vcpu-8gb-nyc3-01:~/nethermind# ps
    PID TTY          TIME CMD
   8083 pts/0    00:00:00 bash
  13059 pts/0    00:07:10 Nethermind.Runn
  13441 pts/0    00:00:00 ps
```

And kill it with `ps PID` like `kill 13059` You can also check out the Digital Ocean Droplet Activity Dashboard, which should show a large increase in activity while syncing occurs.

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fffdd406f8c28bb3b5e05362f15843369ded7a65e.png?generation=1633130009636312\&alt=media)

1. Go to `http://DIGITAL_OCEAN_IP:8545` and you should see the following:
   * ![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F8a1daf12f504d42d01a88f27e4407f2e086c5680.png?generation=1633130007508261\&alt=media)

## 5. Inspect logs and check node's health

Logs are in two places: `nohup.out` (or whatever you name your output file) and `nethermind/logs/xdai.logs.txt`.

I inspected both sets of logs with the `cat filename` command and once the file got too big `tail -n 10 filename` to view the newest entries.

Nethermind provides an excellent [explanation](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/getting-started#explaining-nethermind-logs) of what the logs are telling you about the speed of your fast sync.

I suggest following along and learning about the logs.

Finally, once your node is synced or near synced, you can confirm your node is in good shape:

`http://DIGITAL_OCEAN_IP:8545/health`

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F7b859e6b9d4ce67f44e5a07660342a8fe0b01649.png?generation=1633130004756417\&alt=media)

**Thanks for reading!**

This guide was originally submitted by [cha0sg0d11](https://twitter.com/cha0sg0d11).


# What is a plugin?

Dark Forest allows players to customize the default webclient via the *plugins* system. Plugins are snippets of code that players can write to generate alternate views of game data, automate common gameplay flows, or even reskin the game. Essentially, Dark Forest allows players can interact programmatically with the webclient in any way they'd like.

We encourage players to share plugins with the larger community. A community-maintained plugins showcase can be found [here](https://plugins.zkga.me/), with the underlying source code available in [this repository](https://github.com/darkforest-eth/plugins). Follow the instructions in the plugins showcase [README](https://github.com/darkforest-eth/plugins#adding-your-plugin) to submit your plugin to the repository.

It's worth noting that plugins are evaluated in the context of your game and can access all of your private information (including your burner wallet private key!). Additionally, plugins can dynamically load data, which can be switched out from under you. **Use these plugins at your own risk.**

Therefore, it can be dangerous to use any plugins that you haven't written/reviewed yourself or by someone you trust completely. You or someone you trust should control the entire pipeline (such as imported dependencies) and should review plugins before you use them.


# Writing your first plugin

This article is a stub. Maybe you can help write it!


# Porting v0.5 plugins to v0.6

For most v0.5 plugins, upgrading is as simple as following these two steps:

* First, replace `plugin.register(new Plugin());` (usually the last line of the v0.5 plugin) with `export default Plugin;`.
* If the plugin is tracked in the [plugins repository](https://github.com/darkforest-eth/plugins), replace `0.5.0` in the `version` field with `0.6.0`, and the `date` to the current date.

Here's an [example](https://github.com/darkforest-eth/plugins/pull/63/files) port (doesn't update the `date` field).

In a few cases, you might have to alter a few more lines. Here is a (possibly incomplete) list of additional modifications you may have to make:

* If the plugin is importing utils dynamically with `import('https://plugins.zkga.me/utils/utils.js')`, you should replace any instances of `canUpgrade` with `canPlanetUpgrade`. [example](https://github.com/darkforest-eth/plugins/pull/70/files)
* `entityStore.planetCanUpgrade` is now a static method; any instance of `df.entityStore.planetCanUpgrade(planet)` should be replaced with `df.entityStore.constructor.planetCanUpgrade(planet)`.

If you want to inspect the differences between the v0.5 and v0.6 clients, you can find the last v0.5 client source code [here](https://github.com/darkforest-eth/client/tree/e13caedd3497fbd3822056694d445ddcb25dca88). Documentation on the v0.6 `df` and `ui` objects can be found [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gamemanager.default.md) and [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gameuimanager.default.md), and the source code can be found in the [Dark Forest open-source client](https://github.com/darkforest-eth/client).


# What is mining?

Dark Forest's key mechanic is its cryptographic *fog of war*. When you first join the game, you have no information on where other players are located.

Players must compute hashes in order to uncover points of interest in the universe, such as the locations of planets and other players. These hashes are saved to your browser's local storage, and are considered secret data.

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb0b7540e0bf498ac077c46361d5c6f1a5311e6c4.png?generation=1622752884381350\&alt=media)

By default, the Dark Forest default web client uses a single-threaded Javascript miner to explore the universe, but there are a number of things that you can do to increase your hashrate.

You can set your webclient to use additional cores next to the play pause mining button. The performance of your miner will plateau if you try to set the number of cores to be greater than your computer's actual number of cores.

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fda4989a9b860a4c4b6bcb81fdcb2c6c2fcf1f6da.png?generation=1625245334593799\&alt=media)

Community-maintained headless miner implementations, such as [mimc-fast](https://github.com/projectsophon/darkforest-rs/tree/main/mimc-fast) (and a [complimentary client plugin](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-explore/plugin.js)), are available online.

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fc8f0aab403eea4a869363813767f2791170e1183.png?generation=1622752885238239\&alt=media)


# Sharing map data

As your miner uncovers regions of the universe, your webclient will save information associated with these uncovererd regions to your browser's local storage.

Dark Forest saves data to IndexedDB. You can copy a JSON representation of your full map data to your clipboard through the settings pane. You can also use the settings pane to import a map from your clipboard (or by copying map data into the text box shown below.)

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Feb47020eeb9d1d04cc4169c98f7cb91c938a8585.png?generation=1622752883869456\&alt=media)

A community plugin also exists that allows you to [export snippets of your map](https://github.com/darkforest-eth/plugins/blob/master/content/utilities/map-export/plugin.js).

## Map JSON Structure


# Running a headless miner

This article is a stub. Maybe you can help write it!


# Connecting to a remote (headless) miner

Connecting to a remote explorer should be as simple as putting your miners url in the built in Remote Miner plugin. However if that remote explorer isnt running on your localhost machine, your browser security will reject the connection. The explorer guide gives 2 options to fix this browser limitation.

1\) you can put an ssl cert on your remote server (difficult, costly) 2) disable insecure content for the zkga.me domain (not good security practice in crypto where we really need good security practices).

But those aren't the only solutions!. Instead we can make a remote server look like a local server with a few command lines.

## Port forward with ssh

SSH is a way to access remote machines and allows port forwarding. To set this up there are a few simple steps:

### 1. Installing ssh

SSH is already installed on GNU/Linux. For Windows install your favorite application.

### 2. Editing `~/.ssh/config`

This step is done so that you can ssh into machines without typing commandflags each time. Replace the 192 ip and user with your server.

Here is an example entry:

```bash
    Host miner
        Hostname 192.168.178.132
        User user
        Port 22
        Localforward 8001 localhost:8000
```

> If you have multiple miner copy/paste the entry and then increment the first port number by one

### Connecting

Use `ssh miner` to connect to the remote server and forward the port. Notice how `miner` stands for the ip address in the `~/.ssh/config`.

Once you drop into the shell start `mimc-fast` or whatever remote miner client you're using.

### Plugin use

The Plugin is called Remote Explorer and is in the official client, but does need one change from the default. Instead the default url `http://0.0.0.0:8000/mine` well use `http://localhost:8001/mine`

### Using key based authentication

If you're sick of typing your password to your server, we can fix that too. On your local machine client generate a key with `ssh-keygen`

Then copy it over to your miner with `ssh-copy-id miner` and type your user password for the last time ever.


# Running a custom client

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

Also with the local client running you can develop plugins in your usual text editor. The webpack loader will watch the embedded\_plugins directory for changes and reload your plugin automatically.


# Developing plugins locally

This article is a stub. Maybe you can help write it!


# 3rd-party contract development

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.


# Dark Forest subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

## Forking the subgraph

The [graph schema and mappings](https://github.com/darkforest-eth/eth/tree/master/subgraph) are open sourced and offered as a starting point. Feel free to PR bug fixes and or new features but remember you dont have to rely on our existing graph implementation or hosted url. You can and should publish your instance of thegraph on the hosted site or better yet on your own infrastructure which will be FAR faster to sync. The legacy hosted solution can take days to sync weeks of chain data making patching within the round a difficult task. Syncing a subgraph requires an archive node. xDai offers a free endpoint which thegraph uses which, again, is very slow for being free and open. It would be far better to sync your own xdai archive node.

## Previous Dark Forest subgraphs

* [v5](https://thegraph.com/legacy-explorer/subgraph/jacobrosenthal/dark-forest-v05)
* [v6 R1](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-1)
* [V6 R2](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-2)
* [V6 R3](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-3)


# How to query a subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

You might want to familiarize yourself with the [df wikis more technical explanation](https://dfwiki.net/wiki/Technical_Explanations) of how the game works in order to understand lazy state and what is actually stored in the blockchain.

Like the contract, the subgraph doesn’t know any map data and can’t tell you anything about (x, y) coordinates. Also, like the contract, the subgraph only knows about planets have been interacted with at least once. However UNLIKE the contract, the subgraph DOES apply voyage arrivals as they occur, and therefore has all the most recent ownership data!

## How to query

The query language is called graphql and can take some getting used to. Thegraph explorer has a nice right column that allows you to investigate the schema to see what columns and fields are available.

A little guide of a small query getting upgraded to a big one using different commands/properties. This query will show you all the planet ids (well the first 100 by default) that the contract knows about.

```bash
{
  planets {
    id
  }
}
```

Query that shows planets that are foundries (RUINS=Foundries) ordered by their id

```bash
{
  planets(where:{planetType:RUINS}) {
    id
  }
}
```

Query that shows planets that are foundries with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level and the owners id of each foundry

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner and coords (Coords only will be shown if the planet has been broadcasted by someone)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows the first 10 planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:10) {
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

Query that shows the planets in the range 101-201 that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:100, skip:100){
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

## Troubleshooting

### lower case

All ids like are lower case like 0x0f45aba574aceba2e0717ca86e910211b34f9db9. Sadly blockscout and metamask can occasionally mix case in ids like 0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9!

So for example this might return data:

```bash
{
  players(where: {id: "0x0f45aba574aceba2e0717ca86e910211b34f9db9"}) {
      id
  }
}
```

But this won't:

```bash
{
  players(where: {id: "0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9"}) {
      id
  }
}
```

Theres online [case converters](https://search.brave.com/search?q=tolowercase+online\&source=web) that can help if you find yourself in this predicimant

### Leading 0x and padding

User ids (which are actually ethereum wallet addresses) are always shown with a leading 0x and are zero paddded to 42 characters (0x0f45aba574aceba2e0717ca86e910211b34f9db9) . However planet locationId (00000000004896511cb246d2e6dfcde2dccc1b3855fcf69b53e046b09a929953) do NOT use a 0x in front and are 0 padded to 64 characters.


# Running a remote SNARKer

Dark Forest is powered by ZK-Snark technology, a cryptographic technique that can be used to prove the correctness of a function without revealing the inputs or logic of the function.

Dark Forest uses this technique to verify moves within the game are valid without revealing the location of planets to folks snooping on-chain. This technique (Zk-snark Proof Generation) is computationally expensive! Let's move that computation outside of your browser instance.

## Dependencies

* Node.js: install [node.js v.14](https://nodejs.org/en/download/)
* Git: follow instructions [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

## Installing on a Local Server (Mac, Unix)

First, get a copy of the code from Github.

`git clone https://github.com/Bind/df-snarker`

Enter the df-snarker directory.

`cd df-snarker`

Install code dependencies from NPM.

`npm install`

Start the server.

`npm run start`

If you are running the server on your machine with the default configuration you can click [here](http://localhost:8082) to verify it's working! You should see `v.6 Round 1 Dark Forest Snarking Server` in your browser.

## Connecting to server

* Copy the remote snarker plugin code from the [plugins repository](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-snarker/plugin.js)
* Add the IP address or the URL of the machine running the server into the plugin and set the concurrency to 1. (You can set the concurrency higher if you have a very powerful machine).

![](https://2977984340-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fe905a3c48c0906e5c581104cbb55eb4593547501.png?generation=1622949356786407\&alt=media)

That is it! You should be generating your move snarks outside of your browser.

## Troubleshooting

Like the remote miner, if your server doesn't have an ssl cert (it probably doesn't) then you need to enable mixed content in your browser.

Be sure to disable adblockers as they can block outbound requests from the browser to the server, causing moves to fail!

If you are running the snarking server on the same machine as your browser be sure to use `http://` not `https://` when connecting to it!


# Contributing to this knowledge base

Edit or add to these guides.

Edits and new guides to the site are always appreciated, but need to be audited for security so are a best effort to be merged by the maintainers and could take a long time. We appreciate your patience.

Fork the [repo](https://github.com/darkforest-eth/developer-guides) and open a PR.


# Developing for Dark Forest!

Dark Forest developer resources

With Ethereum gaming, the closed source server model has been replaced by a few open source Ethereum contracts. This means you can hack literally every other part of the experience to your liking.

Dark forest [publishes npm packages](https://www.npmjs.com/search?q=%40darkforest_eth) for its contract addresses, types, and utilities functions and releases an [official subgraph](https://github.com/darkforest-eth/developer-guides/tree/053b668c7b7a172bb0b251c6288920b9cf09d4a9/subgraph.md) to ease your development workflow.

## Plugins Developers

Anyone can get started scripting with the Dark Forest Console. Just look out for the command that is printed from your mouse actions. You can copy and repaste that command to run it again any time, or modify it slightly to try something new. Mostly you'll just be replaying a command so dont worry too much about breaking anything, give it a shot. The [df object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameManager.default.md) and the [ui object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameUIManager.default.md) are the main api surfaces for plugins developers so you'll want to familiarize yourself.

Our community plugins developers have written mini maps, automation plugins, remote miners and much much more. Check the [Dark Forest Community Plugins Showcase](https://plugins.zkga.me/) for inspiration and to copy existing plugins and make them your own. Please join the community by submitting your plugins back there as well.

## Client developers

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

## Contract Developers

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.

## Circuits developers

Dark Forest's innovative gameplay comes in no small part from its [ZK circuits](https://github.com/darkforest-eth/circuits) design utilizing [iden3's circomlib](https://github.com/iden3/circomlib)

## Unaudited Community Resources

**WARNING** Nothing in the Dark Forest ecosystem has any guarantee of being audited. Smart contracts could be malicious or be found to be insecure. Further, all plugins and pasted code in the Dark Forest console have access to your private key and ability to sign transactions (without a cpnfirmation popup). This means they could now or in the future take all your funds, planets, artifacts etc from your burner wallet. You should rotate burner wallets often, not keep more funds or nfts than you're willing to lose, and be careful using any plugins that you haven't written yourself or by someone you trust completely. Further, some plugins dynamically load dependencies under the hood meaning a 'safe' plugin could become unsafe in the future! All use is at your own risk.

Theres a whole wild world of amazing community creations. They're mostly being tracked at the [awesome darkforest repo](https://github.com/snowtigersoft/awesome-darkforest)


# What is an RPC endpoint?

As a decentralized game, Dark Forest stores all public game data on a *blockchain*. Currently, Dark Forest v0.6 is run on the [xDAI blockchain](https://www.xdaichain.com/)--an EVM compatible sidechain.

To connect to and retrieve data from a blockchain, you'll need to connect to a *node* on the blockchain network. A *node* is a participant in the network that stores and serves the latest blockchain state. Users who wish to download blockchain data can either run a node themselves, or connect to a publicly-provided node via the node's *RPC endpoint*. An RPC (remote procedure call) endpoint is like a node's address: it's a URL which requests for blockchain data can be sent to.

The Ethereum [JSON-RPC spec](https://eth.wiki/json-rpc/API) defines the methods which you can use to retrieve data from a node. As a player or 3rd-party developer, you likely won't need to make RPC calls directly with this API--these calls are typically abstracted by web3 libraries like [ethers.js](https://docs.ethers.io/v5/).

By default, the Dark Forest webclient will connect to <https://rpc-df.xdaichain.com/>, a public endpoint provided by the xDAI team. xDAI maintains a fleet of nodes which respond to requests made to this endpoint. There are other public endpoints you can connect to as well; if you'd like a dedicated node to serve your requests, you can also run your own xDAI node and connect to the endpoint it exposes.


# Changing your RPC endpoint

You can change the RPC endpoint that the Dark Forest client connects to in the settings pane of the game.

![](https://3211697078-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F107c00a0669bc080fb981b497a1275c649aa265b.png?generation=1622752883654441\&alt=media)

In addition to the xDAI-provided <https://rpc-df.xdaichain.com> endpoint, xDAI also provides a number of other [public endpoints](https://www.xdaichain.com/for-developers/developer-resources).

Last but not least, Pocket Network has gifted the Dark Forest community an xDAI RPC load-balanced endpoint capable of handling up to 10,000,000 requests per day by staking upwards of 250k POKT on their behalf.

<https://poa-xdai.gateway.pokt.network/v1/lb/60b13899d3279c22da2a444d>

Overtime, this will be scaled up to handle more traffic!


# Running your own xDAI node

This article is a stub. Maybe you can help write it!


# What is a plugin?

Dark Forest allows players to customize the default webclient via the *plugins* system. Plugins are snippets of code that players can write to generate alternate views of game data, automate common gameplay flows, or even reskin the game. Essentially, Dark Forest allows players can interact programmatically with the webclient in any way they'd like.

We encourage players to share plugins with the larger community. A community-maintained plugins showcase can be found [here](https://plugins.zkga.me/), with the underlying source code available in [this repository](https://github.com/darkforest-eth/plugins). Follow the instructions in the plugins showcase [README](https://github.com/darkforest-eth/plugins#adding-your-plugin) to submit your plugin to the repository.

It's worth noting that plugins are evaluated in the context of your game and can access all of your private information (including your burner wallet private key!). Additionally, plugins can dynamically load data, which can be switched out from under you. **Use these plugins at your own risk.**

Therefore, it can be dangerous to use any plugins that you haven't written/reviewed yourself or by someone you trust completely. You or someone you trust should control the entire pipeline (such as imported dependencies) and should review plugins before you use them.


# Writing your first plugin

This article is a stub. Maybe you can help write it!


# Porting v0.5 plugins to v0.6

For most v0.5 plugins, upgrading is as simple as following these two steps:

* First, replace `plugin.register(new Plugin());` (usually the last line of the v0.5 plugin) with `export default Plugin;`.
* If the plugin is tracked in the [plugins repository](https://github.com/darkforest-eth/plugins), replace `0.5.0` in the `version` field with `0.6.0`, and the `date` to the current date.

Here's an [example](https://github.com/darkforest-eth/plugins/pull/63/files) port (doesn't update the `date` field).

In a few cases, you might have to alter a few more lines. Here is a (possibly incomplete) list of additional modifications you may have to make:

* If the plugin is importing utils dynamically with `import('https://plugins.zkga.me/utils/utils.js')`, you should replace any instances of `canUpgrade` with `canPlanetUpgrade`. [example](https://github.com/darkforest-eth/plugins/pull/70/files)
* `entityStore.planetCanUpgrade` is now a static method; any instance of `df.entityStore.planetCanUpgrade(planet)` should be replaced with `df.entityStore.constructor.planetCanUpgrade(planet)`.

If you want to inspect the differences between the v0.5 and v0.6 clients, you can find the last v0.5 client source code [here](https://github.com/darkforest-eth/client/tree/e13caedd3497fbd3822056694d445ddcb25dca88). Documentation on the v0.6 `df` and `ui` objects can be found [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gamemanager.default.md) and [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gameuimanager.default.md), and the source code can be found in the [Dark Forest open-source client](https://github.com/darkforest-eth/client).


# What is mining?

Dark Forest's key mechanic is its cryptographic *fog of war*. When you first join the game, you have no information on where other players are located.

Players must compute hashes in order to uncover points of interest in the universe, such as the locations of planets and other players. These hashes are saved to your browser's local storage, and are considered secret data.

![](https://3211697078-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb0b7540e0bf498ac077c46361d5c6f1a5311e6c4.png?generation=1622752884381350\&alt=media)

By default, the Dark Forest default web client uses a single-threaded Javascript miner to explore the universe, but there are a number of things that you can do to increase your hashrate.

You can set your webclient to use additional cores next to the play pause mining button. The performance of your miner will plateau if you try to set the number of cores to be greater than your computer's actual number of cores.

![](https://3211697078-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fda4989a9b860a4c4b6bcb81fdcb2c6c2fcf1f6da.png?generation=1625245334593799\&alt=media)

Community-maintained headless miner implementations, such as [mimc-fast](https://github.com/projectsophon/darkforest-rs/tree/main/mimc-fast) (and a [complimentary client plugin](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-explore/plugin.js)), are available online.

![](https://3211697078-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fc8f0aab403eea4a869363813767f2791170e1183.png?generation=1622752885238239\&alt=media)


# Sharing map data

As your miner uncovers regions of the universe, your webclient will save information associated with these uncovererd regions to your browser's local storage.

Dark Forest saves data to IndexedDB. You can copy a JSON representation of your full map data to your clipboard through the settings pane. You can also use the settings pane to import a map from your clipboard (or by copying map data into the text box shown below.)

![](https://3211697078-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Feb47020eeb9d1d04cc4169c98f7cb91c938a8585.png?generation=1622752883869456\&alt=media)

A community plugin also exists that allows you to [export snippets of your map](https://github.com/darkforest-eth/plugins/blob/master/content/utilities/map-export/plugin.js).

## Map JSON Structure


# Running a headless miner

This article is a stub. Maybe you can help write it!


# Connecting to a remote (headless) miner

Connecting to a remote explorer should be as simple as putting your miners url in the built in Remote Miner plugin. However if that remote explorer isnt running on your localhost machine, your browser security will reject the connection. The explorer guide gives 2 options to fix this browser limitation.

1\) you can put an ssl cert on your remote server (difficult, costly) 2) disable insecure content for the zkga.me domain (not good security practice in crypto where we really need good security practices).

But those aren't the only solutions!. Instead we can make a remote server look like a local server with a few command lines.

## Port forward with ssh

SSH is a way to access remote machines and allows port forwarding. To set this up there are a few simple steps:

### 1. Installing ssh

SSH is already installed on GNU/Linux. For Windows install your favorite application.

### 2. Editing `~/.ssh/config`

This step is done so that you can ssh into machines without typing commandflags each time. Replace the 192 ip and user with your server.

Here is an example entry:

```bash
    Host miner
        Hostname 192.168.178.132
        User user
        Port 22
        Localforward 8001 localhost:8000
```

> If you have multiple miner copy/paste the entry and then increment the first port number by one

### Connecting

Use `ssh miner` to connect to the remote server and forward the port. Notice how `miner` stands for the ip address in the `~/.ssh/config`.

Once you drop into the shell start `mimc-fast` or whatever remote miner client you're using.

### Plugin use

The Plugin is called Remote Explorer and is in the official client, but does need one change from the default. Instead the default url `http://0.0.0.0:8000/mine` well use `http://localhost:8001/mine`

### Using key based authentication

If you're sick of typing your password to your server, we can fix that too. On your local machine client generate a key with `ssh-keygen`

Then copy it over to your miner with `ssh-copy-id miner` and type your user password for the last time ever.


# Running a custom client

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

Also with the local client running you can develop plugins in your usual text editor. The webpack loader will watch the embedded\_plugins directory for changes and reload your plugin automatically.


# Developing plugins locally

This article is a stub. Maybe you can help write it!


# 3rd-party contract development

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.


# Dark Forest subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

## Forking the subgraph

The [graph schema and mappings](https://github.com/darkforest-eth/eth/tree/master/subgraph) are open sourced and offered as a starting point. Feel free to PR bug fixes and or new features but remember you dont have to rely on our existing graph implementation or hosted url. You can and should publish your instance of thegraph on the hosted site or better yet on your own infrastructure which will be FAR faster to sync. The legacy hosted solution can take days to sync weeks of chain data making patching within the round a difficult task. Syncing a subgraph requires an archive node. xDai offers a free endpoint which thegraph uses which, again, is very slow for being free and open. It would be far better to sync your own xdai archive node.

## Previous Dark Forest subgraphs

* [v5](https://thegraph.com/legacy-explorer/subgraph/jacobrosenthal/dark-forest-v05)
* [v6 R1](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-1)
* [V6 R2](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-2)
* [V6 R3](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-3)


# How to query a subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

You might want to familiarize yourself with the [df wikis more technical explanation](https://dfwiki.net/wiki/Technical_Explanations) of how the game works in order to understand lazy state and what is actually stored in the blockchain.

Like the contract, the subgraph doesn’t know any map data and can’t tell you anything about (x, y) coordinates. Also, like the contract, the subgraph only knows about planets have been interacted with at least once. However UNLIKE the contract, the subgraph DOES apply voyage arrivals as they occur, and therefore has all the most recent ownership data!

## How to query

The query language is called graphql and can take some getting used to. Thegraph explorer has a nice right column that allows you to investigate the schema to see what columns and fields are available.

A little guide of a small query getting upgraded to a big one using different commands/properties. This query will show you all the planet ids (well the first 100 by default) that the contract knows about.

```bash
{
  planets {
    id
  }
}
```

Query that shows planets that are foundries (RUINS=Foundries) ordered by their id

```bash
{
  planets(where:{planetType:RUINS}) {
    id
  }
}
```

Query that shows planets that are foundries with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level and the owners id of each foundry

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner and coords (Coords only will be shown if the planet has been broadcasted by someone)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows the first 10 planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:10) {
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

Query that shows the planets in the range 101-201 that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:100, skip:100){
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

## Troubleshooting

### lower case

All ids like are lower case like 0x0f45aba574aceba2e0717ca86e910211b34f9db9. Sadly blockscout and metamask can occasionally mix case in ids like 0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9!

So for example this might return data:

```bash
{
  players(where: {id: "0x0f45aba574aceba2e0717ca86e910211b34f9db9"}) {
      id
  }
}
```

But this won't:

```bash
{
  players(where: {id: "0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9"}) {
      id
  }
}
```

Theres online [case converters](https://search.brave.com/search?q=tolowercase+online\&source=web) that can help if you find yourself in this predicimant

### Leading 0x and padding

User ids (which are actually ethereum wallet addresses) are always shown with a leading 0x and are zero paddded to 42 characters (0x0f45aba574aceba2e0717ca86e910211b34f9db9) . However planet locationId (00000000004896511cb246d2e6dfcde2dccc1b3855fcf69b53e046b09a929953) do NOT use a 0x in front and are 0 padded to 64 characters.


# Running a remote SNARKer

Dark Forest is powered by ZK-Snark technology, a cryptographic technique that can be used to prove the correctness of a function without revealing the inputs or logic of the function.

Dark Forest uses this technique to verify moves within the game are valid without revealing the location of planets to folks snooping on-chain. This technique (Zk-snark Proof Generation) is computationally expensive! Let's move that computation outside of your browser instance.

## Dependencies

* Node.js: install [node.js v.14](https://nodejs.org/en/download/)
* Git: follow instructions [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

## Installing on a Local Server (Mac, Unix)

First, get a copy of the code from Github.

`git clone https://github.com/Bind/df-snarker`

Enter the df-snarker directory.

`cd df-snarker`

Install code dependencies from NPM.

`npm install`

Start the server.

`npm run start`

If you are running the server on your machine with the default configuration you can click [here](http://localhost:8082) to verify it's working! You should see `v.6 Round 1 Dark Forest Snarking Server` in your browser.

## Connecting to server

* Copy the remote snarker plugin code from the [plugins repository](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-snarker/plugin.js)
* Add the IP address or the URL of the machine running the server into the plugin and set the concurrency to 1. (You can set the concurrency higher if you have a very powerful machine).

![](https://3211697078-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fe905a3c48c0906e5c581104cbb55eb4593547501.png?generation=1622949356786407\&alt=media)

That is it! You should be generating your move snarks outside of your browser.

## Troubleshooting

Like the remote miner, if your server doesn't have an ssl cert (it probably doesn't) then you need to enable mixed content in your browser.

Be sure to disable adblockers as they can block outbound requests from the browser to the server, causing moves to fail!

If you are running the snarking server on the same machine as your browser be sure to use `http://` not `https://` when connecting to it!


# Contributing to this knowledge base

Edit or add to these guides.

Edits and new guides to the site are always appreciated, but need to be audited for security so are a best effort to be merged by the maintainers and could take a long time. We appreciate your patience.

Fork the [repo](https://github.com/darkforest-eth/developer-guides) and open a PR.


# Initial page


# plugins


# Using the Dark Forest subgraph

This article is a stub. Maybe you can help write it!


# Contributing

## Prerequisites

Install `yarn` and run `yarn` to install the dependencies

## Building locally

* `yarn serve`
* Then browse to `http://localhost:4000/`


# Developing for Dark Forest!

Dark Forest developer resources

With Ethereum gaming, the closed source server model has been replaced by a few open source Ethereum contracts. This means you can hack literally every other part of the experience to your liking.

Dark forest [publishes npm packages](https://www.npmjs.com/search?q=%40darkforest_eth) for its contract addresses, types, and utilities functions and releases an [official subgraph](https://github.com/darkforest-eth/developer-guides/tree/4a22c121752f9193de63b5712aa5d9de0eaf77e3/subgraph.md) to ease your development workflow.

## Plugins Developers

Anyone can get started scripting with the Dark Forest Console. Just look out for the command that is printed from your mouse actions. You can copy and repaste that command to run it again any time, or modify it slightly to try something new. Mostly you'll just be replaying a command so dont worry too much about breaking anything, give it a shot. The [df object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameManager.default.md) and the [ui object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameUIManager.default.md) are the main api surfaces for plugins developers so you'll want to familiarize yourself.

Our community plugins developers have written mini maps, automation plugins, remote miners and much much more. Check the [Dark Forest Community Plugins Showcase](https://plugins.zkga.me/) for inspiration and to copy existing plugins and make them your own. Please join the community by submitting your plugins back there as well.

## Client developers

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

## Contract Developers

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.

## Circuits developers

Dark Forest's innovative gameplay comes in no small part from its [ZK circuits](https://github.com/darkforest-eth/circuits) design utilizing [iden3's circomlib](https://github.com/iden3/circomlib)

## Unaudited Community Resources

**WARNING** Nothing in the Dark Forest ecosystem has any guarantee of being audited. Smart contracts could be malicious or be found to be insecure. Further, all plugins and pasted code in the Dark Forest console have access to your private key and ability to sign transactions (without a cpnfirmation popup). This means they could now or in the future take all your funds, planets, artifacts etc from your burner wallet. You should rotate burner wallets often, not keep more funds or nfts than you're willing to lose, and be careful using any plugins that you haven't written yourself or by someone you trust completely. Further, some plugins dynamically load dependencies under the hood meaning a 'safe' plugin could become unsafe in the future! All use is at your own risk.

Theres a whole wild world of amazing community creations. They're mostly being tracked at the [awesome darkforest repo](https://github.com/snowtigersoft/awesome-darkforest)


# What is an RPC endpoint?

As a decentralized game, Dark Forest stores all public game data on a *blockchain*. Currently, Dark Forest v0.6 is run on the [xDAI blockchain](https://www.xdaichain.com/)--an EVM compatible sidechain.

To connect to and retrieve data from a blockchain, you'll need to connect to a *node* on the blockchain network. A *node* is a participant in the network that stores and serves the latest blockchain state. Users who wish to download blockchain data can either run a node themselves, or connect to a publicly-provided node via the node's *RPC endpoint*. An RPC (remote procedure call) endpoint is like a node's address: it's a URL which requests for blockchain data can be sent to.

The Ethereum [JSON-RPC spec](https://eth.wiki/json-rpc/API) defines the methods which you can use to retrieve data from a node. As a player or 3rd-party developer, you likely won't need to make RPC calls directly with this API--these calls are typically abstracted by web3 libraries like [ethers.js](https://docs.ethers.io/v5/).

By default, the Dark Forest webclient will connect to <https://rpc-df.xdaichain.com/>, a public endpoint provided by the xDAI team. xDAI maintains a fleet of nodes which respond to requests made to this endpoint. There are other public endpoints you can connect to as well; if you'd like a dedicated node to serve your requests, you can also run your own xDAI node and connect to the endpoint it exposes.


# Changing your RPC endpoint

You can change the RPC endpoint that the Dark Forest client connects to in the settings pane of the game.

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F107c00a0669bc080fb981b497a1275c649aa265b.png?generation=1622752883654441\&alt=media)

* In addition to the game default xDAI-provided <https://rpc-df.xdaichain.com> endpoint, xDAI also provides a number of other [public endpoints](https://www.xdaichain.com/for-developers/developer-resources).
* You can also run your own node locally [or on the cloud](/images/connecting-to-the-blockchain/running-your-own-xdai-node)
* Cloud providers like [Quicknode](https://www.quicknode.com/) will run a node for you with a few clicks for a monthly fee.
* Last but not least, [Pocket Network](https://www.blog.pokt.network/darkforest/) has gifted the Dark Forest community an xDAI RPC load-balanced endpoint node at <https://poa-xdai.gateway.pokt.network/v1/lb/60b13899d3279c22da2a444d>


# Running your own xDAI node

## Why run your own xDai Node?

* No queue of other people's transactions
* No downtime. Thousands of other players are attempting to use the same free rpc endpoint as you otherwise!
* Faster access. The memory and cpu speed of the free rpc is not published. By running your own node you can use a beefier box.&#x20;

The clients that have known xDai support include [OpenEthereum](https://www.xdaichain.com/for-developers/install-xdai-client/parity) (formerly Parity) and [Nethermind](https://www.xdaichain.com/for-developers/install-xdai-client/nethermind).

## Why Nethermind

from xDai [docs](https://www.xdaichain.com/for-developers/install-xdai-client/nethermind)

> A majority of xDai validators are now running the Nethermind client. The latest version includes support for MEV via flashbots and increased default xDAI TxPool size from 1024 transactions to 2048.

## Why Digital Ocean for hosting

from Nethermind [docs](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/hardware-requirements)

> Generally the faster IO operations the better. For this reason Digital Ocean and UpCloud are so far the best cloud providers we have tested when running Nethermind nodes.

## 1. Setting up a Digital Ocean Instance

1. Buy a droplet (cloud computer). I recommend a machine with *at least* the following specs ($40/month):
   * `Ubuntu 20.4 / 8 GB / 4 CPUs 160 GB SSD Disk 5 TB transfer`
   * If this too slow, I synced a node in \~6 hours with the $80/month option

     > If your sync is very slow (extended beyond two days) then very likely your setup cannot catch up with the chain progress.
   * ![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F30b189753da9979dbf0f70ab75f79fa7751675d9.png?generation=1633130009834050\&alt=media)
2. Remotely [connect](https://docs.digitalocean.com/products/droplets/how-to/connect-with-ssh/) to the Droplet using ssh. Probably something like `ssh root@157.245.5.42`
3. You should see the following on success:
4. ![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb2d526c1f6f841bd61fd2c2c5f501449ecdbd912.png?generation=1633130005677758\&alt=media)

## 2. Install Nethermind and dependencies

*Note: these commands are verbatim from* [*here*](https://docs.nethermind.io/nethermind/ethereum-client/running-nethermind/running-the-client)

1. `wget [NETHERMIND_URL]` - use the most recent linux amd64 release from [downloads](https://downloads.nethermind.io/))  Probably something like `wget https://nethdev.blob.core.windows.net/builds/nethermind-linux-amd64-1.11.3-fe90423.zip`
2. `sudo apt-get update && sudo apt-get install libsnappy-dev libc6-dev libc6 unzip -y` - Linux dependencies
3. `unzip NETHERMIND_URL -d nethermind` - unzip to nethermind folder

At this point, I diverged from the basic installation. This is because there are some specific configuration settings that are nice for running a node (and playing Dark Forest).

## 3. Configure Nethermind for Dark Forest

So in the `nethermind` folder you will see `Nethermind.Launcher` and `Nethermind.Runner`.

* ![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fd1b91eeee4753c33072893acf1988a94b4861947.png?generation=1633130006577923\&alt=media)

From [ethhub](https://docs.ethhub.io/using-ethereum/ethereum-clients/nethermind/)

> Nethermind.Launcher is an interactive prompt that allows you to choose the network which then calls Nethermind.Runner with the appropriate config file. This is the quickest way to get up and running. Nethermind.Runner is the actual client binary similar to the geth binary and supports both cli options or a JSON configuration file. `Nethermind.Runner --config <path_to_config>`

I added some custom configurations, so I choose to use the `Nethermind.Runner` binary with my custom config file.

1. `cd nethermind`
   * We want to sync an xDai node, so here are the options for xDai (xdai\_dfdao is my custom config):&#x20;
   * ![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F063e3db236ad4364d1756b5edff05768c2691ead.png?generation=1633130010610154\&alt=media)
   * I choose to copy `xdai_pruned_mev.cfg` because:
     1. I want the experiment with [mev](https://www.xdaichain.com/for-developers/developer-resources/mev-and-flashbots) on xDai
     2. I want to save size by pruning, at the cost of historical queries: &#x20;

        > pruning is the process of removing some of the intermediary state nodes - it saves some disk space but makes most of the historical state queries fail.
2. `cp configs/CONFIG_FILE configs/YOUR_CONFIGNAME`
   * for me, this was `cp configs/xdai_pruned_mev.cfg configs/xdai_dfdao.cfg`

Edit your config file with something like `nano configs/xdai_dfdao.cfg` and change the following fields to allow access to your node from the internet: 1. Your JSON RPC should look like this:

```
 "JsonRpc": {
   "Enabled": true,
   "Timeout": 20000,
   "Host": "IP ADDRESS",
   "Port": 8545,
   "WebSocketsPort": 8546,
   "EthModuleConcurrentInstances": 6
 }
```

1. Under Network add a new field.

   ```
   "Network": {
   ...
    "ActivePeersMaxCount": 256,
   ```

   > if you have a good connection and a reasonable machine then setting --Network.MaxActiveSyncPeers to 256 (see NetworkConfig secion in configuration) should give much better fast sync times (we use 256 peers to get 5 hours syncs)
   >
   > * Note that even though `ActivePeersMaxCount` is [deprecated](https://docs.nethermind.io/nethermind/ethereum-client/configuration/network), this setting worked for me (and `MaxActiveSyncPeers`) didn't.
2. Exit and save the file

## 4. Run Nethermind in background

So now we're ready to go.

However, if you run `./Nethermind.Runner --config <path-to-config-file>` and logout, your process will stop.

To avoid this, you can use [nohup](https://www.geeksforgeeks.org/nohup-command-in-linux-with-examples/) and the `&` operator to run your process in the background.

1. `nohup ./Nethermind.Runner --config <path-to-config-file> &`
2. optional: If you want to enable Health [Checks](https://docs.nethermind.io/nethermind/ethereum-client/monitoring-node-health), run the following:
   * `nohup ./Nethermind.Runner --config <path-to-config-file> --HealthChecks.Enabled true &`

This command will create a new file `nohup.out` (name can be configured with `nohup ... > output.txt`) in the `nethermind` directory, with logs that you can inspect.

You can find the process id in order to stop the now backgrounded syncing process with `ps`:

```
root@ubuntu-s-4vcpu-8gb-nyc3-01:~/nethermind# ps
    PID TTY          TIME CMD
   8083 pts/0    00:00:00 bash
  13059 pts/0    00:07:10 Nethermind.Runn
  13441 pts/0    00:00:00 ps
```

And kill it with `ps PID` like `kill 13059` You can also check out the Digital Ocean Droplet Activity Dashboard, which should show a large increase in activity while syncing occurs.

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fffdd406f8c28bb3b5e05362f15843369ded7a65e.png?generation=1633130009636312\&alt=media)

1. Go to `http://DIGITAL_OCEAN_IP:8545` and you should see the following:
   * ![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F8a1daf12f504d42d01a88f27e4407f2e086c5680.png?generation=1633130007508261\&alt=media)

## 5. Inspect logs and check node's health

Logs are in two places: `nohup.out` (or whatever you name your output file) and `nethermind/logs/xdai.logs.txt`.

I inspected both sets of logs with the `cat filename` command and once the file got too big `tail -n 10 filename` to view the newest entries.

Nethermind provides an excellent [explanation](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/getting-started#explaining-nethermind-logs) of what the logs are telling you about the speed of your fast sync.

I suggest following along and learning about the logs.

Finally, once your node is synced or near synced, you can confirm your node is in good shape:

`http://DIGITAL_OCEAN_IP:8545/health`

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F7b859e6b9d4ce67f44e5a07660342a8fe0b01649.png?generation=1633130004756417\&alt=media)

**Thanks for reading!**

This guide was originally submitted by [cha0sg0d11](https://twitter.com/cha0sg0d11).


# What is a plugin?

Dark Forest allows players to customize the default webclient via the *plugins* system. Plugins are snippets of code that players can write to generate alternate views of game data, automate common gameplay flows, or even reskin the game. Essentially, Dark Forest allows players can interact programmatically with the webclient in any way they'd like.

We encourage players to share plugins with the larger community. A community-maintained plugins showcase can be found [here](https://plugins.zkga.me/), with the underlying source code available in [this repository](https://github.com/darkforest-eth/plugins). Follow the instructions in the plugins showcase [README](https://github.com/darkforest-eth/plugins#adding-your-plugin) to submit your plugin to the repository.

It's worth noting that plugins are evaluated in the context of your game and can access all of your private information (including your burner wallet private key!). Additionally, plugins can dynamically load data, which can be switched out from under you. **Use these plugins at your own risk.**

Therefore, it can be dangerous to use any plugins that you haven't written/reviewed yourself or by someone you trust completely. You or someone you trust should control the entire pipeline (such as imported dependencies) and should review plugins before you use them.


# Writing your first plugin

This article is a stub. Maybe you can help write it!


# Porting v0.5 plugins to v0.6

For most v0.5 plugins, upgrading is as simple as following these two steps:

* First, replace `plugin.register(new Plugin());` (usually the last line of the v0.5 plugin) with `export default Plugin;`.
* If the plugin is tracked in the [plugins repository](https://github.com/darkforest-eth/plugins), replace `0.5.0` in the `version` field with `0.6.0`, and the `date` to the current date.

Here's an [example](https://github.com/darkforest-eth/plugins/pull/63/files) port (doesn't update the `date` field).

In a few cases, you might have to alter a few more lines. Here is a (possibly incomplete) list of additional modifications you may have to make:

* If the plugin is importing utils dynamically with `import('https://plugins.zkga.me/utils/utils.js')`, you should replace any instances of `canUpgrade` with `canPlanetUpgrade`. [example](https://github.com/darkforest-eth/plugins/pull/70/files)
* `entityStore.planetCanUpgrade` is now a static method; any instance of `df.entityStore.planetCanUpgrade(planet)` should be replaced with `df.entityStore.constructor.planetCanUpgrade(planet)`.

If you want to inspect the differences between the v0.5 and v0.6 clients, you can find the last v0.5 client source code [here](https://github.com/darkforest-eth/client/tree/e13caedd3497fbd3822056694d445ddcb25dca88). Documentation on the v0.6 `df` and `ui` objects can be found [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gamemanager.default.md) and [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gameuimanager.default.md), and the source code can be found in the [Dark Forest open-source client](https://github.com/darkforest-eth/client).


# What is mining?

Dark Forest's key mechanic is its cryptographic *fog of war*. When you first join the game, you have no information on where other players are located.

Players must compute hashes in order to uncover points of interest in the universe, such as the locations of planets and other players. These hashes are saved to your browser's local storage, and are considered secret data.

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb0b7540e0bf498ac077c46361d5c6f1a5311e6c4.png?generation=1622752884381350\&alt=media)

By default, the Dark Forest default web client uses a single-threaded Javascript miner to explore the universe, but there are a number of things that you can do to increase your hashrate.

You can set your webclient to use additional cores next to the play pause mining button. The performance of your miner will plateau if you try to set the number of cores to be greater than your computer's actual number of cores.

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fda4989a9b860a4c4b6bcb81fdcb2c6c2fcf1f6da.png?generation=1625245334593799\&alt=media)

Community-maintained headless miner implementations, such as [mimc-fast](https://github.com/projectsophon/darkforest-rs/tree/main/mimc-fast) (and a [complimentary client plugin](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-explore/plugin.js)), are available online.

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fc8f0aab403eea4a869363813767f2791170e1183.png?generation=1622752885238239\&alt=media)


# Sharing map data

As your miner uncovers regions of the universe, your webclient will save information associated with these uncovererd regions to your browser's local storage.

Dark Forest saves data to IndexedDB. You can copy a JSON representation of your full map data to your clipboard through the settings pane. You can also use the settings pane to import a map from your clipboard (or by copying map data into the text box shown below.)

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Feb47020eeb9d1d04cc4169c98f7cb91c938a8585.png?generation=1622752883869456\&alt=media)

A community plugin also exists that allows you to [export snippets of your map](https://github.com/darkforest-eth/plugins/blob/master/content/utilities/map-export/plugin.js).

## Map JSON Structure


# Running a headless miner

This article is a stub. Maybe you can help write it!


# Connecting to a remote (headless) miner

Connecting to a remote explorer should be as simple as putting your miners url in the built in Remote Miner plugin. However if that remote explorer isnt running on your localhost machine, your browser security will reject the connection. The explorer guide gives 2 options to fix this browser limitation.

1\) you can put an ssl cert on your remote server (difficult, costly) 2) disable insecure content for the zkga.me domain (not good security practice in crypto where we really need good security practices).

But those aren't the only solutions!. Instead we can make a remote server look like a local server with a few command lines.

## Port forward with ssh

SSH is a way to access remote machines and allows port forwarding. To set this up there are a few simple steps:

### 1. Installing ssh

SSH is already installed on GNU/Linux. For Windows install your favorite application.

### 2. Editing `~/.ssh/config`

This step is done so that you can ssh into machines without typing commandflags each time. Replace the 192 ip and user with your server.

Here is an example entry:

```bash
    Host miner
        Hostname 192.168.178.132
        User user
        Port 22
        Localforward 8001 localhost:8000
```

> If you have multiple miner copy/paste the entry and then increment the first port number by one

### Connecting

Use `ssh miner` to connect to the remote server and forward the port. Notice how `miner` stands for the ip address in the `~/.ssh/config`.

Once you drop into the shell start `mimc-fast` or whatever remote miner client you're using.

### Plugin use

The Plugin is called Remote Explorer and is in the official client, but does need one change from the default. Instead the default url `http://0.0.0.0:8000/mine` well use `http://localhost:8001/mine`

### Using key based authentication

If you're sick of typing your password to your server, we can fix that too. On your local machine client generate a key with `ssh-keygen`

Then copy it over to your miner with `ssh-copy-id miner` and type your user password for the last time ever.


# Running a custom client

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

Also with the local client running you can develop plugins in your usual text editor. The webpack loader will watch the embedded\_plugins directory for changes and reload your plugin automatically.


# Developing plugins locally

This article is a stub. Maybe you can help write it!


# 3rd-party contract development

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.


# Dark Forest subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

## Forking the subgraph

The [graph schema and mappings](https://github.com/darkforest-eth/eth/tree/master/subgraph) are open sourced and offered as a starting point. Feel free to PR bug fixes and or new features but remember you dont have to rely on our existing graph implementation or hosted url. You can and should publish your instance of thegraph on the hosted site or better yet on your own infrastructure which will be FAR faster to sync. The legacy hosted solution can take days to sync weeks of chain data making patching within the round a difficult task. Syncing a subgraph requires an archive node. xDai offers a free endpoint which thegraph uses which, again, is very slow for being free and open. It would be far better to sync your own xdai archive node.

## Previous Dark Forest subgraphs

* [v5](https://thegraph.com/legacy-explorer/subgraph/jacobrosenthal/dark-forest-v05)
* [v6 R1](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-1)
* [V6 R2](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-2)
* [V6 R3](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-3)


# How to query a subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

You might want to familiarize yourself with the [df wikis more technical explanation](https://dfwiki.net/wiki/Technical_Explanations) of how the game works in order to understand lazy state and what is actually stored in the blockchain.

Like the contract, the subgraph doesn’t know any map data and can’t tell you anything about (x, y) coordinates. Also, like the contract, the subgraph only knows about planets have been interacted with at least once. However UNLIKE the contract, the subgraph DOES apply voyage arrivals as they occur, and therefore has all the most recent ownership data!

## How to query

The query language is called graphql and can take some getting used to. Thegraph explorer has a nice right column that allows you to investigate the schema to see what columns and fields are available.

A little guide of a small query getting upgraded to a big one using different commands/properties. This query will show you all the planet ids (well the first 100 by default) that the contract knows about.

```bash
{
  planets {
    id
  }
}
```

Query that shows planets that are foundries (RUINS=Foundries) ordered by their id

```bash
{
  planets(where:{planetType:RUINS}) {
    id
  }
}
```

Query that shows planets that are foundries with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level and the owners id of each foundry

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner and coords (Coords only will be shown if the planet has been broadcasted by someone)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows the first 10 planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:10) {
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

Query that shows the planets in the range 101-201 that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:100, skip:100){
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

## Troubleshooting

### lower case

All ids like are lower case like 0x0f45aba574aceba2e0717ca86e910211b34f9db9. Sadly blockscout and metamask can occasionally mix case in ids like 0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9!

So for example this might return data:

```bash
{
  players(where: {id: "0x0f45aba574aceba2e0717ca86e910211b34f9db9"}) {
      id
  }
}
```

But this won't:

```bash
{
  players(where: {id: "0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9"}) {
      id
  }
}
```

Theres online [case converters](https://search.brave.com/search?q=tolowercase+online\&source=web) that can help if you find yourself in this predicimant

### Leading 0x and padding

User ids (which are actually ethereum wallet addresses) are always shown with a leading 0x and are zero paddded to 42 characters (0x0f45aba574aceba2e0717ca86e910211b34f9db9) . However planet locationId (00000000004896511cb246d2e6dfcde2dccc1b3855fcf69b53e046b09a929953) do NOT use a 0x in front and are 0 padded to 64 characters.


# Running a remote SNARKer

Dark Forest is powered by ZK-Snark technology, a cryptographic technique that can be used to prove the correctness of a function without revealing the inputs or logic of the function.

Dark Forest uses this technique to verify moves within the game are valid without revealing the location of planets to folks snooping on-chain. This technique (Zk-snark Proof Generation) is computationally expensive! Let's move that computation outside of your browser instance.

## Dependencies

* Node.js: install [node.js v.14](https://nodejs.org/en/download/)
* Git: follow instructions [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

## Installing on a Local Server (Mac, Unix)

First, get a copy of the code from Github.

`git clone https://github.com/Bind/df-snarker`

Enter the df-snarker directory.

`cd df-snarker`

Install code dependencies from NPM.

`npm install`

Start the server.

`npm run start`

If you are running the server on your machine with the default configuration you can click [here](http://localhost:8082) to verify it's working! You should see `v.6 Round 1 Dark Forest Snarking Server` in your browser.

## Connecting to server

* Copy the remote snarker plugin code from the [plugins repository](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-snarker/plugin.js)
* Add the IP address or the URL of the machine running the server into the plugin and set the concurrency to 1. (You can set the concurrency higher if you have a very powerful machine).

![](https://1973884391-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fe905a3c48c0906e5c581104cbb55eb4593547501.png?generation=1622949356786407\&alt=media)

That is it! You should be generating your move snarks outside of your browser.

## Troubleshooting

Like the remote miner, if your server doesn't have an ssl cert (it probably doesn't) then you need to enable mixed content in your browser.

Be sure to disable adblockers as they can block outbound requests from the browser to the server, causing moves to fail!

If you are running the snarking server on the same machine as your browser be sure to use `http://` not `https://` when connecting to it!


# Contributing to this knowledge base

Edit or add to these guides.

Edits and new guides to the site are always appreciated, but need to be audited for security so are a best effort to be merged by the maintainers and could take a long time. We appreciate your patience.

Fork the [repo](https://github.com/darkforest-eth/developer-guides) and open a PR.


# Developing for Dark Forest!

Dark Forest developer resources

With Ethereum gaming, the closed source server model has been replaced by a few open source Ethereum contracts. This means you can hack literally every other part of the experience to your liking.

Dark forest [publishes npm packages](https://www.npmjs.com/search?q=%40darkforest_eth) for its contract addresses, types, and utilities functions and releases an [official subgraph](/developer-resources/subgraph) to ease your development workflow.

## Plugins Developers

Anyone can get started scripting with the Dark Forest Console. Just look out for the command that is printed from your mouse actions. You can copy and repaste that command to run it again any time, or modify it slightly to try something new. Mostly you'll just be replaying a command so dont worry too much about breaking anything, give it a shot. The [df object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameManager.default.md) and the [ui object](https://github.com/darkforest-eth/client/blob/master/docs/classes/Backend_GameLogic_GameUIManager.default.md) are the main api surfaces for plugins developers so you'll want to familiarize yourself.

Our community plugins developers have written mini maps, automation plugins, remote miners and much much more. Check the [Dark Forest Community Plugins Showcase](https://plugins.zkga.me/) for inspiration and to copy existing plugins and make them your own. Please join the community by submitting your plugins back there as well.

## Client developers

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

## Contract Developers

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.

## Circuits developers

Dark Forest's innovative gameplay comes in no small part from its [ZK circuits](https://github.com/darkforest-eth/circuits) design utilizing [iden3's circomlib](https://github.com/iden3/circomlib)

## Unaudited Community Resources

**WARNING** Nothing in the Dark Forest ecosystem has any guarantee of being audited. Smart contracts could be malicious or be found to be insecure. Further, all plugins and pasted code in the Dark Forest console have access to your private key and ability to sign transactions (without a cpnfirmation popup). This means they could now or in the future take all your funds, planets, artifacts etc from your burner wallet. You should rotate burner wallets often, not keep more funds or nfts than you're willing to lose, and be careful using any plugins that you haven't written yourself or by someone you trust completely. Further, some plugins dynamically load dependencies under the hood meaning a 'safe' plugin could become unsafe in the future! All use is at your own risk.

Theres a whole wild world of amazing community creations. They're mostly being tracked at the [awesome darkforest repo](https://github.com/snowtigersoft/awesome-darkforest)


# What is an RPC endpoint?

As a decentralized game, Dark Forest stores all public game data on a *blockchain*. Currently, Dark Forest v0.6 is run on the [xDAI blockchain](https://www.xdaichain.com/)--an EVM compatible sidechain.

To connect to and retrieve data from a blockchain, you'll need to connect to a *node* on the blockchain network. A *node* is a participant in the network that stores and serves the latest blockchain state. Users who wish to download blockchain data can either run a node themselves, or connect to a publicly-provided node via the node's *RPC endpoint*. An RPC (remote procedure call) endpoint is like a node's address: it's a URL which requests for blockchain data can be sent to.

The Ethereum [JSON-RPC spec](https://eth.wiki/json-rpc/API) defines the methods which you can use to retrieve data from a node. As a player or 3rd-party developer, you likely won't need to make RPC calls directly with this API--these calls are typically abstracted by web3 libraries like [ethers.js](https://docs.ethers.io/v5/).

By default, the Dark Forest webclient will connect to <https://rpc-df.xdaichain.com/>, a public endpoint provided by the xDAI team. xDAI maintains a fleet of nodes which respond to requests made to this endpoint. There are other public endpoints you can connect to as well; if you'd like a dedicated node to serve your requests, you can also run your own xDAI node and connect to the endpoint it exposes.


# Changing your RPC endpoint

You can change the RPC endpoint that the Dark Forest client connects to in the settings pane of the game.

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F107c00a0669bc080fb981b497a1275c649aa265b.png?generation=1622752883654441\&alt=media)

* In addition to the game default xDAI-provided <https://rpc-df.xdaichain.com> endpoint, xDAI also provides a number of other [public endpoints](https://www.xdaichain.com/for-developers/developer-resources).
* You can also run your own node locally [or on the cloud](/connecting-to-the-blockchain/running-your-own-xdai-node)
* Cloud providers like [Quicknode](https://www.quicknode.com/) will run a node for you with a few clicks for a monthly fee.
* Last but not least, [Pocket Network](https://www.blog.pokt.network/darkforest/) has gifted the Dark Forest community an xDAI RPC load-balanced endpoint node at <https://poa-xdai.gateway.pokt.network/v1/lb/60b13899d3279c22da2a444d>


# Running your own xDAI node

## Why run your own xDai Node?

* No queue of other people's transactions
* No downtime. Thousands of other players are attempting to use the same free rpc endpoint as you otherwise!
* Faster access. The memory and cpu speed of the free rpc is not published. By running your own node you can use a beefier box.&#x20;

The clients that have known xDai support include [OpenEthereum](https://www.xdaichain.com/for-developers/install-xdai-client/parity) (formerly Parity) and [Nethermind](https://www.xdaichain.com/for-developers/install-xdai-client/nethermind).

## Why Nethermind

from xDai [docs](https://www.xdaichain.com/for-developers/install-xdai-client/nethermind)

> A majority of xDai validators are now running the Nethermind client. The latest version includes support for MEV via flashbots and increased default xDAI TxPool size from 1024 transactions to 2048.

## Why Digital Ocean for hosting

from Nethermind [docs](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/hardware-requirements)

> Generally the faster IO operations the better. For this reason Digital Ocean and UpCloud are so far the best cloud providers we have tested when running Nethermind nodes.

## 1. Setting up a Digital Ocean Instance

1. Buy a droplet (cloud computer). I recommend a machine with *at least* the following specs ($40/month):
   * `Ubuntu 20.4 / 8 GB / 4 CPUs 160 GB SSD Disk 5 TB transfer`
   * If this too slow, I synced a node in \~6 hours with the $80/month option

     > If your sync is very slow (extended beyond two days) then very likely your setup cannot catch up with the chain progress.
   * ![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F30b189753da9979dbf0f70ab75f79fa7751675d9.png?generation=1633130009834050\&alt=media)
2. Remotely [connect](https://docs.digitalocean.com/products/droplets/how-to/connect-with-ssh/) to the Droplet using ssh. Probably something like `ssh root@157.245.5.42`
3. You should see the following on success:
4. ![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb2d526c1f6f841bd61fd2c2c5f501449ecdbd912.png?generation=1633130005677758\&alt=media)

## 2. Install Nethermind and dependencies

*Note: these commands are verbatim from* [*here*](https://docs.nethermind.io/nethermind/ethereum-client/running-nethermind/running-the-client)

1. `wget [NETHERMIND_URL]` - use the most recent linux amd64 release from [downloads](https://downloads.nethermind.io/))  Probably something like `wget https://nethdev.blob.core.windows.net/builds/nethermind-linux-amd64-1.11.3-fe90423.zip`
2. `sudo apt-get update && sudo apt-get install libsnappy-dev libc6-dev libc6 unzip -y` - Linux dependencies
3. `unzip NETHERMIND_URL -d nethermind` - unzip to nethermind folder

At this point, I diverged from the basic installation. This is because there are some specific configuration settings that are nice for running a node (and playing Dark Forest).

## 3. Configure Nethermind for Dark Forest

So in the `nethermind` folder you will see `Nethermind.Launcher` and `Nethermind.Runner`.

* ![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fd1b91eeee4753c33072893acf1988a94b4861947.png?generation=1633130006577923\&alt=media)

From [ethhub](https://docs.ethhub.io/using-ethereum/ethereum-clients/nethermind/)

> Nethermind.Launcher is an interactive prompt that allows you to choose the network which then calls Nethermind.Runner with the appropriate config file. This is the quickest way to get up and running. Nethermind.Runner is the actual client binary similar to the geth binary and supports both cli options or a JSON configuration file. `Nethermind.Runner --config <path_to_config>`

I added some custom configurations, so I choose to use the `Nethermind.Runner` binary with my custom config file.

1. `cd nethermind`
   * We want to sync an xDai node, so here are the options for xDai (xdai\_dfdao is my custom config):&#x20;
   * ![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F063e3db236ad4364d1756b5edff05768c2691ead.png?generation=1633130010610154\&alt=media)
   * I choose to copy `xdai_pruned_mev.cfg` because:
     1. I want the experiment with [mev](https://www.xdaichain.com/for-developers/developer-resources/mev-and-flashbots) on xDai
     2. I want to save size by pruning, at the cost of historical queries: &#x20;

        > pruning is the process of removing some of the intermediary state nodes - it saves some disk space but makes most of the historical state queries fail.
2. `cp configs/CONFIG_FILE configs/YOUR_CONFIGNAME`
   * for me, this was `cp configs/xdai_pruned_mev.cfg configs/xdai_dfdao.cfg`

Edit your config file with something like `nano configs/xdai_dfdao.cfg` and change the following fields to allow access to your node from the internet: 1. Your JSON RPC should look like this:

```
 "JsonRpc": {
   "Enabled": true,
   "Timeout": 20000,
   "Host": "IP ADDRESS",
   "Port": 8545,
   "WebSocketsPort": 8546,
   "EthModuleConcurrentInstances": 6
 }
```

1. Under Network add a new field.

   ```
   "Network": {
   ...
    "ActivePeersMaxCount": 256,
   ```

   > if you have a good connection and a reasonable machine then setting --Network.MaxActiveSyncPeers to 256 (see NetworkConfig secion in configuration) should give much better fast sync times (we use 256 peers to get 5 hours syncs)
   >
   > * Note that even though `ActivePeersMaxCount` is [deprecated](https://docs.nethermind.io/nethermind/ethereum-client/configuration/network), this setting worked for me (and `MaxActiveSyncPeers`) didn't.
2. Exit and save the file

## 4. Run Nethermind in background

So now we're ready to go.

However, if you run `./Nethermind.Runner --config <path-to-config-file>` and logout, your process will stop.

To avoid this, you can use [nohup](https://www.geeksforgeeks.org/nohup-command-in-linux-with-examples/) and the `&` operator to run your process in the background.

1. `nohup ./Nethermind.Runner --config <path-to-config-file> &`
2. optional: If you want to enable Health [Checks](https://docs.nethermind.io/nethermind/ethereum-client/monitoring-node-health), run the following:
   * `nohup ./Nethermind.Runner --config <path-to-config-file> --HealthChecks.Enabled true &`

This command will create a new file `nohup.out` (name can be configured with `nohup ... > output.txt`) in the `nethermind` directory, with logs that you can inspect.

You can find the process id in order to stop the now backgrounded syncing process with `ps`:

```
root@ubuntu-s-4vcpu-8gb-nyc3-01:~/nethermind# ps
    PID TTY          TIME CMD
   8083 pts/0    00:00:00 bash
  13059 pts/0    00:07:10 Nethermind.Runn
  13441 pts/0    00:00:00 ps
```

And kill it with `ps PID` like `kill 13059` You can also check out the Digital Ocean Droplet Activity Dashboard, which should show a large increase in activity while syncing occurs.

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fffdd406f8c28bb3b5e05362f15843369ded7a65e.png?generation=1633130009636312\&alt=media)

1. Go to `http://DIGITAL_OCEAN_IP:8545` and you should see the following:
   * ![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F8a1daf12f504d42d01a88f27e4407f2e086c5680.png?generation=1633130007508261\&alt=media)

## 5. Inspect logs and check node's health

Logs are in two places: `nohup.out` (or whatever you name your output file) and `nethermind/logs/xdai.logs.txt`.

I inspected both sets of logs with the `cat filename` command and once the file got too big `tail -n 10 filename` to view the newest entries.

Nethermind provides an excellent [explanation](https://docs.nethermind.io/nethermind/first-steps-with-nethermind/getting-started#explaining-nethermind-logs) of what the logs are telling you about the speed of your fast sync.

I suggest following along and learning about the logs.

Finally, once your node is synced or near synced, you can confirm your node is in good shape:

`http://DIGITAL_OCEAN_IP:8545/health`

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2F7b859e6b9d4ce67f44e5a07660342a8fe0b01649.png?generation=1633130004756417\&alt=media)

**Thanks for reading!**

This guide was originally submitted by [cha0sg0d11](https://twitter.com/cha0sg0d11).


# What is a plugin?

Dark Forest allows players to customize the default webclient via the *plugins* system. Plugins are snippets of code that players can write to generate alternate views of game data, automate common gameplay flows, or even reskin the game. Essentially, Dark Forest allows players can interact programmatically with the webclient in any way they'd like.

We encourage players to share plugins with the larger community. A community-maintained plugins showcase can be found [here](https://plugins.zkga.me/), with the underlying source code available in [this repository](https://github.com/darkforest-eth/plugins). Follow the instructions in the plugins showcase [README](https://github.com/darkforest-eth/plugins#adding-your-plugin) to submit your plugin to the repository.

It's worth noting that plugins are evaluated in the context of your game and can access all of your private information (including your burner wallet private key!). Additionally, plugins can dynamically load data, which can be switched out from under you. **Use these plugins at your own risk.**

Therefore, it can be dangerous to use any plugins that you haven't written/reviewed yourself or by someone you trust completely. You or someone you trust should control the entire pipeline (such as imported dependencies) and should review plugins before you use them.


# Writing your first plugin

This article is a stub. Maybe you can help write it!


# Porting v0.5 plugins to v0.6

For most v0.5 plugins, upgrading is as simple as following these two steps:

* First, replace `plugin.register(new Plugin());` (usually the last line of the v0.5 plugin) with `export default Plugin;`.
* If the plugin is tracked in the [plugins repository](https://github.com/darkforest-eth/plugins), replace `0.5.0` in the `version` field with `0.6.0`, and the `date` to the current date.

Here's an [example](https://github.com/darkforest-eth/plugins/pull/63/files) port (doesn't update the `date` field).

In a few cases, you might have to alter a few more lines. Here is a (possibly incomplete) list of additional modifications you may have to make:

* If the plugin is importing utils dynamically with `import('https://plugins.zkga.me/utils/utils.js')`, you should replace any instances of `canUpgrade` with `canPlanetUpgrade`. [example](https://github.com/darkforest-eth/plugins/pull/70/files)
* `entityStore.planetCanUpgrade` is now a static method; any instance of `df.entityStore.planetCanUpgrade(planet)` should be replaced with `df.entityStore.constructor.planetCanUpgrade(planet)`.

If you want to inspect the differences between the v0.5 and v0.6 clients, you can find the last v0.5 client source code [here](https://github.com/darkforest-eth/client/tree/e13caedd3497fbd3822056694d445ddcb25dca88). Documentation on the v0.6 `df` and `ui` objects can be found [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gamemanager.default.md) and [here](https://github.com/darkforest-eth/client/blob/master/docs/classes/backend_gamelogic_gameuimanager.default.md), and the source code can be found in the [Dark Forest open-source client](https://github.com/darkforest-eth/client).


# What is mining?

Dark Forest's key mechanic is its cryptographic *fog of war*. When you first join the game, you have no information on where other players are located.

Players must compute hashes in order to uncover points of interest in the universe, such as the locations of planets and other players. These hashes are saved to your browser's local storage, and are considered secret data.

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fb0b7540e0bf498ac077c46361d5c6f1a5311e6c4.png?generation=1622752884381350\&alt=media)

By default, the Dark Forest default web client uses a single-threaded Javascript miner to explore the universe, but there are a number of things that you can do to increase your hashrate.

You can set your webclient to use additional cores next to the play pause mining button. The performance of your miner will plateau if you try to set the number of cores to be greater than your computer's actual number of cores.

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fda4989a9b860a4c4b6bcb81fdcb2c6c2fcf1f6da.png?generation=1625245334593799\&alt=media)

Community-maintained headless miner implementations, such as [mimc-fast](https://github.com/projectsophon/darkforest-rs/tree/main/mimc-fast) (and a [complimentary client plugin](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-explore/plugin.js)), are available online.

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fc8f0aab403eea4a869363813767f2791170e1183.png?generation=1622752885238239\&alt=media)


# Sharing map data

As your miner uncovers regions of the universe, your webclient will save information associated with these uncovererd regions to your browser's local storage.

Dark Forest saves data to IndexedDB. You can copy a JSON representation of your full map data to your clipboard through the settings pane. You can also use the settings pane to import a map from your clipboard (or by copying map data into the text box shown below.)

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Feb47020eeb9d1d04cc4169c98f7cb91c938a8585.png?generation=1622752883869456\&alt=media)

A community plugin also exists that allows you to [export snippets of your map](https://github.com/darkforest-eth/plugins/blob/master/content/utilities/map-export/plugin.js).

## Map JSON Structure


# Running a headless miner

This article is a stub. Maybe you can help write it!


# Connecting to a remote (headless) miner

Connecting to a remote explorer should be as simple as putting your miners url in the built in Remote Miner plugin. However if that remote explorer isnt running on your localhost machine, your browser security will reject the connection. The explorer guide gives 2 options to fix this browser limitation.

1\) you can put an ssl cert on your remote server (difficult, costly) 2) disable insecure content for the zkga.me domain (not good security practice in crypto where we really need good security practices).

But those aren't the only solutions!. Instead we can make a remote server look like a local server with a few command lines.

## Port forward with ssh

SSH is a way to access remote machines and allows port forwarding. To set this up there are a few simple steps:

### 1. Installing ssh

SSH is already installed on GNU/Linux. For Windows install your favorite application.

### 2. Editing `~/.ssh/config`

This step is done so that you can ssh into machines without typing commandflags each time. Replace the 192 ip and user with your server.

Here is an example entry:

```bash
    Host miner
        Hostname 192.168.178.132
        User user
        Port 22
        Localforward 8001 localhost:8000
```

> If you have multiple miner copy/paste the entry and then increment the first port number by one

### Connecting

Use `ssh miner` to connect to the remote server and forward the port. Notice how `miner` stands for the ip address in the `~/.ssh/config`.

Once you drop into the shell start `mimc-fast` or whatever remote miner client you're using.

### Plugin use

The Plugin is called Remote Explorer and is in the official client, but does need one change from the default. Instead the default url `http://0.0.0.0:8000/mine` well use `http://localhost:8001/mine`

### Using key based authentication

If you're sick of typing your password to your server, we can fix that too. On your local machine client generate a key with `ssh-keygen`

Then copy it over to your miner with `ssh-copy-id miner` and type your user password for the last time ever.


# Running a custom client

By forking the [React/WebGL client frontend](https://github.com/darkforest-eth/client) and running one yarn command you'll be running a webpack local dev client against mainnet. This allows you to edit the client to your liking customizing any part of the game and the license even allows you to fork to your own open source version and publish to IPFS or a static site host like netlify to share with your guild or friends.

Also with the local client running you can develop plugins in your usual text editor. The webpack loader will watch the embedded\_plugins directory for changes and reload your plugin automatically.


# Developing plugins locally

This article is a stub. Maybe you can help write it!


# 3rd-party contract development

If you're interested in Ethereum smart contract development and Hardhat tooling we release all [smart contract source code and scripts](https://github.com/darkforest-eth/eth) used in developing and maintaining the game

But thats not all. With that knowledge you should be able to write contracts that interact with the mainnet Dark Forest universe, no permission needed. See the [Sophon Reveal Marketplace](https://github.com/projectsophon/df-play-to-earn) example for a contract that lets users sell their daily reveal to the first bidder.


# Dark Forest subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

## Forking the subgraph

The [graph schema and mappings](https://github.com/darkforest-eth/eth/tree/master/subgraph) are open sourced and offered as a starting point. Feel free to PR bug fixes and or new features but remember you dont have to rely on our existing graph implementation or hosted url. You can and should publish your instance of thegraph on the hosted site or better yet on your own infrastructure which will be FAR faster to sync. The legacy hosted solution can take days to sync weeks of chain data making patching within the round a difficult task. Syncing a subgraph requires an archive node. xDai offers a free endpoint which thegraph uses which, again, is very slow for being free and open. It would be far better to sync your own xdai archive node.

## Previous Dark Forest subgraphs

* [v5](https://thegraph.com/legacy-explorer/subgraph/jacobrosenthal/dark-forest-v05)
* [v6 R1](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-1)
* [V6 R2](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-2)
* [V6 R3](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-3)
* [V6 R4](https://thegraph.com/legacy-explorer/subgraph/darkforest-eth/dark-forest-v06-round-4)


# How to query a subgraph

[The Graph](https://thegraph.com/docs/about/introduction) is a decentralized protocol for indexing and querying data from blockchains. It makes it possible to query data that is difficult to query directly from the smart contract itself.

For Dark Forest the subgraph acts almost as a read only excel spreadsheet client to the game where you can query for any information that is public in the smart contract.

You might want to familiarize yourself with the [df wikis more technical explanation](https://dfwiki.net/wiki/Technical_Explanations) of how the game works in order to understand lazy state and what is actually stored in the blockchain.

Like the contract, the subgraph doesn’t know any map data and can’t tell you anything about (x, y) coordinates. Also, like the contract, the subgraph only knows about planets have been interacted with at least once. However UNLIKE the contract, the subgraph DOES apply voyage arrivals as they occur, and therefore has all the most recent ownership data!

## How to query

The query language is called graphql and can take some getting used to. Thegraph explorer has a nice right column that allows you to investigate the schema to see what columns and fields are available.

A little guide of a small query getting upgraded to a big one using different commands/properties. This query will show you all the planet ids (well the first 100 by default) that the contract knows about.

```bash
{
  planets {
    id
  }
}
```

Query that shows planets that are foundries (RUINS=Foundries) ordered by their id

```bash
{
  planets(where:{planetType:RUINS}) {
    id
  }
}
```

Query that shows planets that are foundries with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level (ordered by their id...)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level and the owners id of each foundry

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner and coords (Coords only will be shown if the planet has been broadcasted by someone)

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel) {
    id
    planetLevel
    owner {
      id
    }
    x
    y
    spaceType
  }
}
```

Query that shows the first 10 planets that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:10) {
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

Query that shows the planets in the range 101-201 that are foundries greater or equal to level 8 owned by "0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9" ordered by their level with their respective level, owner, coords and type of space

```bash
{
  planets(where:{planetType:RUINS, planetLevel_gte:8, owner:"0xb5ce86c2ab9e2403ab47acfbe501845e2480fad9"}, orderBy:planetLevel, first:100, skip:100){
    id
    planetLevel
    owner {
      id
     }
     x
     y
     spaceType
   }
 }
```

## Troubleshooting

### lower case

All ids like are lower case like 0x0f45aba574aceba2e0717ca86e910211b34f9db9. Sadly blockscout and metamask can occasionally mix case in ids like 0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9!

So for example this might return data:

```bash
{
  players(where: {id: "0x0f45aba574aceba2e0717ca86e910211b34f9db9"}) {
      id
  }
}
```

But this won't:

```bash
{
  players(where: {id: "0x0f45aBA574AcEbA2E0717Ca86e910211b34f9db9"}) {
      id
  }
}
```

Theres online [case converters](https://search.brave.com/search?q=tolowercase+online\&source=web) that can help if you find yourself in this predicimant

### Leading 0x and padding

User ids (which are actually ethereum wallet addresses) are always shown with a leading 0x and are zero paddded to 42 characters (0x0f45aba574aceba2e0717ca86e910211b34f9db9) . However planet locationId (00000000004896511cb246d2e6dfcde2dccc1b3855fcf69b53e046b09a929953) do NOT use a 0x in front and are 0 padded to 64 characters.


# Running a remote SNARKer

Dark Forest is powered by ZK-Snark technology, a cryptographic technique that can be used to prove the correctness of a function without revealing the inputs or logic of the function.

Dark Forest uses this technique to verify moves within the game are valid without revealing the location of planets to folks snooping on-chain. This technique (Zk-snark Proof Generation) is computationally expensive! Let's move that computation outside of your browser instance.

## Dependencies

* Node.js: install [node.js v.14](https://nodejs.org/en/download/)
* Git: follow instructions [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)

## Installing on a Local Server (Mac, Unix)

First, get a copy of the code from Github.

`git clone https://github.com/Bind/df-snarker`

Enter the df-snarker directory.

`cd df-snarker`

Install code dependencies from NPM.

`npm install`

Start the server.

`npm run start`

If you are running the server on your machine with the default configuration you can click [here](http://localhost:8082) to verify it's working! You should see `v.6 Round 1 Dark Forest Snarking Server` in your browser.

## Connecting to server

* Copy the remote snarker plugin code from the [plugins repository](https://github.com/darkforest-eth/plugins/blob/master/content/productivity/remote-snarker/plugin.js)
* Add the IP address or the URL of the machine running the server into the plugin and set the concurrency to 1. (You can set the concurrency higher if you have a very powerful machine).

![](https://3493251533-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MbI_yHyhttU6wPV6RCb%2Fsync%2Fe905a3c48c0906e5c581104cbb55eb4593547501.png?generation=1622949356786407\&alt=media)

That is it! You should be generating your move snarks outside of your browser.

## Troubleshooting

Like the remote miner, if your server doesn't have an ssl cert (it probably doesn't) then you need to enable mixed content in your browser.

Be sure to disable adblockers as they can block outbound requests from the browser to the server, causing moves to fail!

If you are running the snarking server on the same machine as your browser be sure to use `http://` not `https://` when connecting to it!


# Contributing to this knowledge base

Edit or add to these guides.

Edits and new guides to the site are always appreciated, but need to be audited for security so are a best effort to be merged by the maintainers and could take a long time. We appreciate your patience.

Fork the [repo](https://github.com/darkforest-eth/developer-guides) and open a PR.


