Dark Forest

zkSNARK space warfare

Note: The deadline for the Plugins Contest has been extended to Thursday 1/21

This is a guest post written by Jacob, the winner of Dark Forest v0.4. Jacob has been working on plugins and other useful tooling for Dark Forest v0.5. The post has been lightly edited by the Dark Forest team for clarity!

I’m announcing the successful sync of a Dark Forest subgraph.

You can query for planet stats (like owner, speed, stat boosts, artifact buffs) and other useful information, such as what planets have incoming arrivals (attack notifications on your phone?), who got the first legendary artifact and which one, and almost anything else you can think of. All of that is in fact public on the chain, even if your game doesn’t expose it! Also important, the graph supports historical queries so you could query the scoreboard at 1 day in, 3 days in, or exactly at game end.

I’m hoping to see some clever plugins or even alternate client support from the community. I have some Javascript examples here. The subgraph is a bit more than raw blockchain data, but a bit less than a full game client.

A Tangent on How Dark Forest Works

Almost everything you do in Dark Forest is publicly stored in EVM storage. The only thing that’s cloaked is the x,y coordinates for the locationId of the planet you’re interacting with. Neither the contract or anyone watching knows where your planet is, but they can feel “disturbances in the force” (via emitted events) when you make moves, upgrade, harvest artifacts, or buy hats… ominous.

However - there is no setInterval() in blockchain land. In other words, there is no timer ticking off your silver or energy growth or watching for arrivals to land. The clever way this is implemented by the designers, is to store planet stats like energy as of a lastUpdated timestamp, and to perform all energy calculations lazily on an S-curve. After a voyage lands on a planet, the next person who “touches” the planet pays all the gas costs to fast forward the planet’s energy levels based on the growth curves, apply all previous arrivals, and finally apply their own change! (Also note, only the planets that have ever been “touched” are actual planets paid any attention to in the contract. The 10 thousand level 0s nearby that you never bothered to take aren’t “real” planets.. yet). But as a result, planets in the contract actually don’t show the most recent owners - it takes a “game client” to apply all the arrivals to get the actual current state of the game.

So your game client, in addition to madly trying to explore (mine) x,y coordinates, also has to perform all these updates. On game start you have to download every planet (that you’re interested in knowing about), and all the arrivals, and then fast forward and apply everything. Then while the game runs your client is doing these calculations every tick; it simultaneously listens for new arrivals that you may be interested in, and applies those at the right times in order to stay in sync with the contract so the moves you make are legal and will be accepted by the contract (and not reverted). And every time you explore and find new planets you have to ask the contract if anyone owns those planets and if you should add those to your list of planets to ask the contract about. However this is pretty expensive, and gets worse the more planets you know about! Some people actually remove map data from their game as the game goes on, because keeping track of less planets is less work!

Back to the Subgraph…

Like the contract, the subgraph obviously doesn’t know any map data and can’t tell you anything about (x, y) coordinates. However, like the contract, the subgraph does know about every planet that has been touched. On the contract, energy and silver are lazily-computed and are only updated when someone uses them in a contract call. Most queries probably don’t need to care about exactly how much silver or energy are on a planet though, but if you need to there’s examples of how to fast forward available, it’s not hard it just requires a post process step. But UNLIKE the contract, the subgraph applies voyage arrivals as they occur, and therefore has all the most recent ownership data! It’s the best of both worlds.

I’m still documenting it further and using the Graph myself: Blaine and I built @sophon_eth to be an all knowing watcher of the entire universe. It’s built in Rust and originally just read from pure blockchain data, but it’s now being powered by thegraph endpoint as well (see here).