From c463c848aa329519433d9e7e9b8bdc5928a0bad3 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 27 Feb 2024 15:21:42 +0000 Subject: [PATCH] docs: introduction (#2292) Co-authored-by: yonada --- docs/pages/_meta.js | 15 +++++++-- .../guides/replicating-onchain-state.mdx | 2 +- docs/pages/introduction.mdx | 22 +++++++++---- docs/pages/quickstart.mdx | 14 +++++--- docs/pages/state-query/typescript/zustand.mdx | 32 +++++++------------ 5 files changed, 50 insertions(+), 35 deletions(-) diff --git a/docs/pages/_meta.js b/docs/pages/_meta.js index 1eeaffc9e9..da675263ec 100644 --- a/docs/pages/_meta.js +++ b/docs/pages/_meta.js @@ -1,8 +1,14 @@ import worldPackageJson from "../../packages/world/package.json" assert { type: "json" }; export default { - quickstart: "Quickstart", - introduction: "Introduction", + introduction: { + title: "What is MUD?", + theme: { breadcrumb: false }, + }, + quickstart: { + title: "Get started", + theme: { breadcrumb: false }, + }, protocol: { title: "Protocol", type: "separator", @@ -23,7 +29,10 @@ export default { }, guides: "Guides", templates: "Templates", - contribute: "Contribute", + contribute: { + title: "Contribute", + theme: { breadcrumb: false }, + }, changelog: "Changelog", retrospectives: "Retrospectives", // -------------------- diff --git a/docs/pages/guides/replicating-onchain-state.mdx b/docs/pages/guides/replicating-onchain-state.mdx index 7288cb075f..fa554d1fc1 100644 --- a/docs/pages/guides/replicating-onchain-state.mdx +++ b/docs/pages/guides/replicating-onchain-state.mdx @@ -17,7 +17,7 @@ MUD emits the following events for its onchain storage operations: ```solidity event Store_SetRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData) event Store_SpliceStaticData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, bytes data) -event Store_SpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes32 encodedLengths, bytes data) +event Store_SpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint8 dynamicFieldIndex, uint48 start, uint40 deleteCount, bytes32 encodedLengths, bytes data) event Store_DeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple) ``` diff --git a/docs/pages/introduction.mdx b/docs/pages/introduction.mdx index 2ead1352da..8dc2676d4b 100644 --- a/docs/pages/introduction.mdx +++ b/docs/pages/introduction.mdx @@ -1,13 +1,21 @@ -# MUD Introduction +# What is MUD? -MUD is a framework for ambitious Ethereum applications. It compresses the complexity of building EVM apps with a tightly integrated software stack. +MUD is a framework for ambitious onchain applications. It reduces the complexity of building [Ethereum](https://ethereum.org/) apps with a tightly integrated software stack. It's [open source](https://github.com/latticexyz/mud) and [free to use](https://github.com/latticexyz/mud/blob/main/LICENSE). -MUD evolved out of our experiences building onchain games like [Dark Forest](https://zkga.me/) and zkDungeon. We identified many difficulties along the way: coupling of state and logic in smart contracts makes upgrading logic difficult, lack of synchrony between the chain and client can lead to inconsistencies in game state, irregularities with access controls pose problems for would-be third-party developers attempting to create their own plugins and clients. This revealed the need for a framework and a protocol to handle the inevitable complexity of game code, and to counteract the developer-unfriendly patterns inherent in the way smart contracts are traditionally written. We built MUD with solutions to these problems in mind. +## Why MUD? + +Writing smart contracts is only a small part of building user-friendly EVM apps. Your frontend needs get data from the chain. You've kept your onchain logic simple to save users gas, but now getting data from the RPC is tricky and slow. So you spin up an indexer, write event handlers, and teach your frontend how to talk to another backend. Complicated, right? + +MUD provides much of this out of the box. It uses a [familiar data model](/store/data-model) with tables and fields, built on a standardized storage protocol. This lets us to provide you with an [automatic indexer](/services/indexer), no code necessary. And because it's all standarized, our client libraries already know how to get your app's onchain state and keep your frontend [in sync with the chain](/guides/replicating-onchain-state). -The projects built with MUD speak for themselves: some of the most complex applications on Ethereum have been built with the framework in record time. OPCraft, a fully onchain voxel world, was built by Lattice in 1.5 months. While it didn’t have the security and auditing requirement of financial applications, it handled more transaction throughput than most apps on Mainnet ever did in their lifetime: in 10 days, OPCraft players made 3.5 million transactions, filling the MUD onchain database with billions of gas worth of storage; with the client seamlessly handling synchronizing that state back. OPCraft used MUD without any additional tricks: large onchain applications with minimal client headaches can be yours too! +MUD apps are [autonomous worlds](https://0xparc.org/blog/autonomous-worlds), infinitely extendable by default. They come with access control, upgradability, hooks, plugins, and a suite of great developer tools. -MUD is maximally onchain: the entire application state lives in the EVM, and the only requirement for clients and frontends is an Ethereum Node. You can use all MUD libraries together as a framework and get super-powers, or only pick the parts you like. It’s up to you! +[Give it a try](/quickstart) and [let us know](https://lattice.xyz/discord) what you think! + +## How it started + +MUD evolved out of our experiences building onchain games like [Dark Forest](https://zkga.me/) and zkDungeon. We identified many difficulties along the way: coupling of state and logic in smart contracts makes upgrading logic difficult, lack of synchrony between the chain and client can lead to inconsistencies in game state, irregularities with access controls pose problems for would-be third-party developers attempting to create their own plugins and clients. This revealed the need for a framework and a protocol to handle the inevitable complexity of game code, and to counteract the developer-unfriendly patterns inherent in the way smart contracts are traditionally written. We built MUD with solutions to these problems in mind. -## License +The projects built with MUD speak for themselves: some of the most complex applications on Ethereum have been built with the framework in record time. [OPCraft](https://opcraft.mud.dev/), a fully onchain voxel world, was built by Lattice in 1.5 months. While it didn't have the security and auditing requirement of financial applications, it handled more transaction throughput than most apps on Mainnet ever did in their lifetime: in 10 days, OPCraft players made 3.5 million transactions, filling the MUD onchain database with billions of gas worth of storage; with the client seamlessly handling synchronizing that state back. OPCraft used MUD without any additional tricks: large onchain applications with minimal client headaches can be yours too! -MUD is open-source software [licensed as MIT](https://github.com/latticexyz/mud/blob/main/LICENSE). +MUD is maximally onchain: the entire application state lives in the EVM, and the only requirement for clients and frontends is an Ethereum Node. You can use all MUD libraries together as a framework and get super-powers, or only pick the parts you like. It's up to you! diff --git a/docs/pages/quickstart.mdx b/docs/pages/quickstart.mdx index a6a2175e2c..7de324088b 100644 --- a/docs/pages/quickstart.mdx +++ b/docs/pages/quickstart.mdx @@ -2,13 +2,19 @@ The easiest way to get started with MUD is to use [a template](/templates/typescript/getting-started). -1. Ensure you have [`node`](https://nodejs.org/en/download/package-manager#macos), [`pnpm`](https://pnpm.io/installation) and [`foundry`](https://getfoundry.sh/) installed. -1. Create and start the application: +1. Ensure you have [node](https://nodejs.org/en/download/package-manager#macos) 18+, [pnpm](https://pnpm.io/installation) 8+ and [foundry](https://getfoundry.sh/) installed. +1. Create a new app from a template: ```sh copy - pnpm create mud@next my-project && cd my-project && pnpm dev + pnpm create mud@next my-project + ``` + +1. Start the app: + + ```sh copy + cd my-project + pnpm dev ``` -1. Select the template to use. 1. Browse to the application. Usually it is at [http://localhost:3000](http://localhost:3000), but if that port is in use it might be 3001, 3002, etc. diff --git a/docs/pages/state-query/typescript/zustand.mdx b/docs/pages/state-query/typescript/zustand.mdx index f27bbcf564..398ae8b8e4 100644 --- a/docs/pages/state-query/typescript/zustand.mdx +++ b/docs/pages/state-query/typescript/zustand.mdx @@ -15,18 +15,14 @@ The way you use it is very similar to the way you'd use `useState`, but with a b To initialize the synchronization you use [`syncToZustand`](https://github.com/latticexyz/mud/blob/main/packages/store-sync/src/zustand/syncToZustand.ts). ```ts copy - import { syncToZustand } from "@latticexyz/store-sync/zustand"; - - . - . - . - - const { tables, useStore, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToZustand({ - config: mudConfig, - address: networkConfig.worldAddress as Hex, - publicClient, - startBlock: BigInt(networkConfig.initialBlockNumber), - }); +import { syncToZustand } from "@latticexyz/store-sync/zustand"; + +const { tables, useStore, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToZustand({ + config: mudConfig, + address: networkConfig.worldAddress as Hex, + publicClient, + startBlock: BigInt(networkConfig.initialBlockNumber), +}); ``` The most important fields returned by `syncToZustand` are: @@ -198,15 +194,11 @@ If your application does not use React, you can still use Zustand to read MUD da ```ts copy import { syncToZustand } from "@latticexyz/store-sync/zustand"; - . - . - . - const { tables, useStore, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToZustand({ - config: mudConfig, - address: networkConfig.worldAddress as Hex, - publicClient, - startBlock: BigInt(networkConfig.initialBlockNumber), + config: mudConfig, + address: networkConfig.worldAddress as Hex, + publicClient, + startBlock: BigInt(networkConfig.initialBlockNumber), }); ```