Skip to main content
This tutorial will guide you through building a high-frequency on-chain game on your Move appchain. BlockForge is a crafting engine that demonstrates Invisible UX: allowing players to interact with the blockchain seamlessly without constant wallet popups. By the end of this tutorial, you will have instructed your AI agent to:
  • Generate and verify a Move smart contract for the game logic.
  • Deploy the contract to your live appchain.
  • Scaffold and connect a React frontend for players to interact with the game.
  • Verify the on-chain functionality.

Your Project Structure

The following steps will instruct your AI agent to create these directories inside your my-initia-project folder:
Project Structure
Prerequisite: Ensure you have a Move-compatible appchain running locally. If you haven’t launched one yet, complete the Set Up Your Appchain first.

Readiness Check

Before you start, verify that your local infrastructure is healthy.
Prompt: Check local infrastructure health

Step 1: Create and Unit Test the Smart Contract

Instead of writing the code yourself, instruct your AI agent to do it for you using the initia-appchain-dev skill. Your AI agent will generate the contract and automatically run unit tests to ensure the logic is sound.
Prompt: Create and test the BlockForge module
Your AI agent will generate the blockforge project, including the items.move module and a test script, and confirm that everything passes.
If you prefer to create the Move module and project manually, follow these steps in your blockforge directory. This is what your AI agent would generate for you.First, create a new Move package named blockforge:
Create Move Package
minitiad move new blockforge creates a package named blockforge in the current working directory. Creating and entering the blockforge/ directory first keeps the generated package in the expected place.
Now, update the Move.toml file to use the Initia stdlib dependency directly. Replace the content of blockforge/Move.toml with the following:
Move.toml
Next, create blockforge/sources/items.move with the following content.
sources/items.move
Add the following unit tests inside the same module blockforge::items { ... } block, immediately before the final closing } of items.move, so you can verify minting, crafting, and the insufficient-shards failure path:
Unit Tests
Once the files are created, verify everything is correct by building and testing the project. Replace <YOUR_HEX_ADDRESS_WITH_0X_PREFIX> with your deployment address hex (0x...).
Build Move Package
If the build succeeds and the tests pass, BlockForge is ready to deploy.

Step 2: Deploy to Your Appchain

Now that the logic is verified, build and publish the contract to your live appchain using the Gas Station account.
Prompt: Deploy the BlockForge module
First, get your Gas Station address and convert it to hex:
Get Gas Station Hex Address
Then, build and publish the compiled module to your appchain. Substitute <YOUR_HEX_ADDRESS_WITH_0X_PREFIX> with 0x + the bytes value from the previous command.
Publish Move Module
Move modules do not have a separate instantiate transaction. For this tutorial, the first gameplay call (for example mint_shard) initializes per-player inventory state on demand.
Redeploy Compatibility Rules: If you are redeploying from the same account, Initia enforces backward compatibility for the existing module. Preserve public function signatures and public struct abilities, or rename the module before republishing. If you see BACKWARD_INCOMPATIBLE_MODULE_UPDATE, this account already has a non-compatible prior version of the module. Use a fresh funded deployer account on the same chain, update blockforge named-address values to its hex, and deploy with --from <FRESH_ACCOUNT>.

Step 3: Smoke Test the Deployed Contract On-Chain

Before frontend work, smoke test the deployed module directly on chain. This keeps contract/module debugging separate from UI integration.
Prompt: Smoke test the BlockForge module
Here are the equivalent minitiad commands to interact with the module.
Mint 3 Shards
Query Inventory
Craft Relic
Query Inventory Again

Step 4: Create a Frontend

A game needs a user interface. Let’s create one using the initia-appchain-dev skill. 1. Scaffold the Frontend:
Prompt: Scaffold the BlockForge frontend
2. Connect to Appchain:
Prompt: Connect the frontend to the BlockForge module
If you prefer to set up the frontend manually, follow these steps:1. Create the Project and Install Dependencies:Create a new Vite + React app and install the dependencies used by the working BlockForge frontend:
Create Frontend Project
Then update vite.config.js so browser builds have the required Node polyfills:
vite.config.js
2. Gather Runtime Values for Frontend Config:Collect the values you will use for frontend configuration:
Gather Frontend Values
3. Create .env from Runtime Values:
Create Frontend Env
4. Set up Providers in main.jsx:Wrap your application with InterwovenKitProvider to enable wallet connectivity. Ensure the customChain includes fee_tokens, staking, and bech32_prefix.
main.jsx
5. Add the Game Component:Then create src/Game.jsx:
Game.jsx
Render <Game /> from src/App.jsx.
Refresh Delay After Transactions: local Move state queries can lag briefly after a successful requestTxSync. Wait about 2 seconds before reloading inventory so the new state is visible.

Step 5: Wallet Funding and UI Verification

Ask your AI agent to fund your browser wallet, then verify frontend behavior manually in the browser:
  1. Start the frontend:
Start Vite Dev Server
Check the browser console if you encounter issues.
  1. Open your browser wallet and copy your address (init1...).
  2. Give this prompt to your AI agent, replacing <YOUR_WALLET_ADDRESS> with the address you just copied:
  1. Connect your wallet in blockforge-frontend.
  2. Test the gameplay flow by minting shards, crafting a relic, and confirming the displayed inventory state updates correctly after each action.
If you get stuck, see the Debugging Workflow guide.

🪢 Native Feature: Auto-signing

To make your BlockForge game natively integrated with the Initia stack, you can enable Auto-signing to create a frictionless experience where players don’t see wallet popups for every game action. Auto-signing works by deriving a unique, application-specific Ghost Wallet from a one-time signature. Your primary wallet then grants this Ghost Wallet permission (Authz) to execute specific functions and use its balance for fees (Feegrant), allowing for seamless, session-based gameplay.

Step 6: Update the Frontend

You can enable session-based signing by modifying your provider configuration and adding a toggle in your UI.
Prompt: Add auto-signing support
First, enable the feature in your provider:
main.jsx
Then, use the useInterwovenKit hook in your component to manage the session:
Game.jsx
Session Expiration: You can check the exact expiration of the current session using autoSign.expiredAtByChain[chainId].
If you want the complete finished frontend after applying the manual steps above, use the consolidated reference below.
If you want a single copyable end-state after completing the manual steps above, use this consolidated reference. It combines:
  • runtime config from .env,
  • InterwovenKit provider wiring in main.jsx,
  • wallet connect/display in App.jsx, and
  • live Move inventory, actions, and auto-sign toggle flow in Game.jsx.
.env
.env
src/main.jsx
src/main.jsx
src/App.jsx
src/App.jsx
src/Game.jsx
src/Game.jsx
This reference assumes:
  • your module owner is stored in .env as bech32,
  • moduleAddress in MsgExecute uses that bech32 value,
  • inventory reads use rest.move.resource with a hex struct tag.

Native Feature Verification

  1. Connect your wallet in blockforge-frontend.
  2. Enable Auto-sign and approve the one-time Auto-sign setup.
  3. Click Mint Shard and confirm the transaction completes without a new wallet signature prompt.
  4. Disable Auto-sign.
  5. Click Mint Shard again and confirm a wallet signature prompt is required.

Next Steps

Now that you’ve mastered a Move application, you’re ready to build your own idea! Ensure your project meets all the Submission Requirements before submitting.