-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* ✨ Add Bolt v0.1 blog * 📝 Edit blogpost * Add files via upload * Add files via upload * Add files via upload * Update 2024-03-01-bolt-v0.1.md * Add files via upload * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md * Update 2024-03-01-bolt-v0.1.md --------- Co-authored-by: supermarioblock <55660152+supermarioblock@users.noreply.github.com>
- Loading branch information
1 parent
fed62fb
commit f6b35a2
Showing
7 changed files
with
432 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
--- | ||
layout: post | ||
title: "BOLT engine: unstoppable and composable games" | ||
categories: [ Infrastructure ] | ||
image: assets/images/bolt.png | ||
tags: [featured, sticky] | ||
--- | ||
|
||
The V0.1 of BOLT is live. BOLT is an onchain framework that simplifies the development of games that are permissionless, composable and can live forever on the blockchain. The design of BOLT includes an SVM-compatible [acceleration layer](https://arxiv.org/abs/2311.02650) to bring the performance of FOC games on par with traditional multiplayer game servers, without compromising the composability of Solana’s global state. In this early release we are going through the BOLT CLI and Entity Component System (ECS), addressing the recents updates and showcasing how to set up a simple onchain game on Solana. ✨ | ||
|
||
## The ECS pattern | ||
|
||
While Bolt isn't exclusively an Entity Component System (ECS) framework, we encourage the use of this powerful design pattern to enhance composability. ECS is a way of organizing code and data to enable modular and extendible games, key features we seek while building fully onchain. As the name suggests, in an ECS there are: | ||
|
||
- Entities that represent the objects of the game world. They are unique identifiers that don't hold any data or behavior, but simply serve as containers | ||
- Components are raw data structures that can be “attached” to entities | ||
- System performs the game logic or behavior by acting upon entities that hold components | ||
|
||
This separation of concerns enables a highly flexible and modular architecture. You can explore all the benefits of the ECS pattern [here](https://github.com/SanderMertens/ecs-faq?tab=readme-ov-file#what-is-ecs. ). | ||
|
||
## BOLT CLI | ||
|
||
The BOLT CLI is an extension of the Anchor framework. It includes all the features of the popular Solana development framework, plus a superset of functionalities for creating world instances, components and systems. | ||
|
||
### Install BOLT | ||
|
||
```bash | ||
npm install @magicblock-labs/bolt-cli | ||
``` | ||
|
||
You can verify the installation with: | ||
|
||
```bash | ||
bolt -h | ||
``` | ||
|
||
Initialize your first project running: | ||
|
||
```bash | ||
bolt init <new-workspace-name> | ||
``` | ||
|
||
### Components | ||
|
||
The example in the `programs-ecs/components` folder defines a `Position` component containing x, y, z coordinates. Remember that components are plain data structures that contain data relevant to a specific attribute of an entity. They don't contain any logic or methods. | ||
|
||
```rust | ||
use bolt_lang::*; | ||
|
||
declare_id!("Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ"); | ||
|
||
#[component] | ||
#[derive(Copy)] | ||
pub struct Position { | ||
pub x: i64, | ||
pub y: i64, | ||
pub z: i64, | ||
} | ||
``` | ||
|
||
|
||
The **#[component]** macro is taking care of all the underlying Solana-specific behavior. You don’t have to understand how Accounts work, how to allocate bytes or anything other than defining the data structure. | ||
|
||
Components are themselves programs deployed onchain. | ||
|
||
```rust | ||
declare_id!("Fn1JzzEdyb55fsyduWS94mYHizGhJZuhvjX6DVvrmGbQ"); | ||
``` | ||
The id defines the unique address of the component `Position` above. | ||
|
||
### Systems | ||
|
||
Systems contain the logic that manipulates components. A system will typically operate on all entities that have a specific set of components. The `system_movement` example encapsulates the logic for updating the `Position` component. | ||
|
||
```rust | ||
use bolt_lang::*; | ||
use component_position::Position; | ||
|
||
declare_id!("FSa6qoJXFBR3a7ThQkTAMrC15p6NkchPEjBdd4n6dXxA"); | ||
|
||
#[system] | ||
pub mod system_movement { | ||
|
||
pub fn execute(ctx: Context<Components>, args_p: Vec<u8>) -> Result<Components> { | ||
let position = &mut ctx.accounts.position; | ||
position.x += 1; | ||
Ok(ctx.accounts) | ||
} | ||
|
||
// Define the input components | ||
#[system_input] | ||
pub struct Components { | ||
pub position: Position, | ||
} | ||
} | ||
``` | ||
|
||
Each system implements an execute instruction, that will take care of applying the system's logic on an arbitrary number of components. | ||
|
||
The struct marked with the #[system_input] macro, specifies the bundle of components that the system will receive as input. | ||
|
||
The execute instruction returns the modified components, which the World Program will update in the data structures after checking permissions and business logic. | ||
|
||
Again, you don’t need to worry about the underlying blockchain layer by defining the CPI, retrieving the IDL or anything else. Just define the bundle of components you want your system to operate on! | ||
|
||
### Bringing everything together with the World Program | ||
|
||
Now that we have a grasp of how components and systems operate, let’s create a game instance with the World Program from the TypeScript SDK. The World Program is the entrypoint for creating world instances, entities, attaching components, and executing systems. The SDK provides a convenient interface and methods for interacting with BOLT. | ||
|
||
#### Installation | ||
To install the bolt sdk, run the following command: | ||
|
||
```bash | ||
npm install @magicblock-labs/bolt-sdk --save-dev | ||
``` | ||
|
||
##### Create a world instance | ||
|
||
```ts | ||
const world = await World.fromAccountAddress(provider.connection, worldPda); | ||
const entityId = new anchor.BN(world.entities); | ||
entityPda = FindEntityPda(worldId, entityId); | ||
|
||
let createEntityIx = createAddEntityInstruction({ | ||
world: worldPda, | ||
payer: provider.wallet.publicKey, | ||
entity: entityPda, | ||
}); | ||
const tx = new anchor.web3.Transaction().add(createEntityIx); | ||
await provider.sendAndConfirm(tx); | ||
``` | ||
|
||
###### Add a new entity | ||
|
||
```ts | ||
const world = await World.fromAccountAddress(provider.connection, worldPda); | ||
const entityId = new anchor.BN(world.entities); | ||
entityPda = FindEntityPda(worldId, entityId); | ||
|
||
let createEntityIx = createAddEntityInstruction({ | ||
world: worldPda, | ||
payer: provider.wallet.publicKey, | ||
entity: entityPda, | ||
}); | ||
const tx = new anchor.web3.Transaction().add(createEntityIx); | ||
await provider.sendAndConfirm(tx); | ||
``` | ||
|
||
##### Attach the Position component to the the entity | ||
|
||
```ts | ||
const positionComponentPda = FindComponentPda(positionComponent.programId, entityPda, ""); | ||
let initComponentIx = createInitializeComponentInstruction({ | ||
payer: provider.wallet.publicKey, | ||
entity: entityPda, | ||
data: positionComponentPda, | ||
componentProgram: positionComponent.programId, | ||
}); | ||
const tx = new anchor.web3.Transaction().add(initComponentIx); | ||
await provider.sendAndConfirm(tx); | ||
``` | ||
|
||
##### Execute the movement system on the position Component | ||
|
||
```ts | ||
let applySystemIx = createApplyInstruction({ | ||
componentProgram: positionComponent.programId, | ||
boltSystem: systemMovement.programId, | ||
boltComponent: positionComponentPda, | ||
}); | ||
const tx = new anchor.web3.Transaction().add(applySystemIx); | ||
await provider.sendAndConfirm(tx); | ||
``` | ||
|
||
In this simple example we have created an entity Player that holds a Position component with x,y,z coordinates. We can execute the movement system to change its state. | ||
Here's the best part. By defining your game data structure with the BOLT ECS, you’ll not only be able to reuse existing systems and components, but you can easily allow for mods or extensions of your game. | ||
Let’s think of a slightly more sophisticated movement dynamics, with a Velocity component that alters the position defined as: | ||
|
||
```rust | ||
use bolt_lang::*; | ||
|
||
declare_id!("CbHEFbSQdRN4Wnoby9r16umnJ1zWbULBHg4yqzGQonU1"); | ||
|
||
#[component] | ||
#[derive(Copy)] | ||
pub struct Velocity { | ||
pub x: i64 | ||
} | ||
``` | ||
|
||
Someone might want to introduce a new power-up for faster movement. They could do this simply by adding a new system that acts on the Position component using Velocity | ||
|
||
```rust | ||
#[system] | ||
pub mod system_apply_velocity { | ||
|
||
pub fn execute(ctx: Context<Components>, _args: Vec<u8>) -> Result<Components> { | ||
ctx.accounts.position.x += ctx.accounts.velocity.x; | ||
Ok(ctx.accounts) | ||
} | ||
|
||
#[system_input] | ||
pub struct Components { | ||
pub position: Position, | ||
pub velocity: Velocity, | ||
} | ||
} | ||
``` | ||
Notice how simple this snippet of code is. This new system takes as inputs the Position and Velocity components, and defines the logic of the power-up. There is no notion of Solana accounts or CPI - the proxy [World program](https://github.com/magicblock-labs/bolt/tree/main/programs/world) is taking care of everything here. | ||
|
||
With a few lines of code and barely any blockchain knowledge, we have just introduced a new game behavior! | ||
|
||
### Summing up | ||
|
||
BOLT leverages an ECS pattern to enable game developers to create highly modular, efficient and composable games. Entities serve as containers for components, raw data structure, allowing for dynamic customization without altering the underlying codebase. Systems interact with these components, infusing logic and behavior into the game entities. This separation of concerns not only simplifies the development process, but makes game logic more reusable and enhances the ability to extend and modify games post-launch, in a permissionless fashion. | ||
|
||
We can’t wait to see the mechanics that will emerge out of this framework. | ||
|
||
Start building with BOLT [here](https://docs.magicblock.gg/BOLT/getting_started/installation) and share your feedback with our community on [Discord](https://discord.com/invite/MBkdC3gxcv)! |
Oops, something went wrong.