Getting Started with PAIMA and Scroll
Introduction to PAIMA
PAIMA is an app-specific L2 framework for gamification and running game engines on the blockchain. It simply allows you to build on-chain games utilizing the traditional web2 skill and technologies while adding a little web3 to spice things up.
PAIMA is an EVM-compatible framework, including the scroll blockchain, and can be integrated to run interoperably on other chains.
Web3 Gaming Problems
As astonishing as the blockchain has proven to be in multiple fields of the web3 ecosystem, a groundbreaking technology that solves a lot of problems, there are a few shortcomings when considering building Games on the blockchain.
Cost of Development: Building a protocol or any infrastructure on the blockchain naturally requires a lot of cost in considering the auditing process that costs millions of $$, Minting costs, in gaming terms, where you have to mint multiple NFTs of participating players on the blockchain, across multiple chains.
Uni-Chain Communities and Acquisition: In the world of gaming, where communities are the bedrock of any successful gaming platform, breaching across communities from multiple chains can be quite a hassle.
While the solution to the problem of interoperability in the blockchain has been solved for basic blockchain building by protocols like Axelar, It doesn't apply to the community, In the traditional sense of building a gaming application on-chain, one would have to bring together an interoperable community across multiple chain.
Risk of On-Chain Attacks: The one thing about the blockchain that scares every builder, and developer, is the risk of being hacked.
Running a gaming platform on either web2 or web3 can be costly, especially on the blockchain. And yet is also very volatile as there is the risk of being hacked at any time when the proper exploitation loopholes are not considered before deployment.
Onchain Iteration: One of the key features that make the blockchain so fancy is its immutable possibilities, which is quite the opposite for any gaming application, as games need to be able to upgrade on production on the go constantly.
Upgrades and Modification are key prospects of Gaming that keep the excitement bubbling. Therefore another problem, is that fast iteration is hard to accomplish.
The PAIMA Engine as a Solution
Securing of Assets On-chain: As a solution to the solution to risk of on-chain attacks, Paima engines have an inbuilt feature called STATEFUL NFTs, a non-custodial feature, that takes care of upgrades and assets on-chain without the need to transfer your assets (NFTs), and in an instance of a hack, loosing your them on-chain.
Utilizing the PAIMA Engine, every player has a unique and custom, NFT, with all available data for the player's characters and accomplishments, Data like wins, losses, powers, history, equipment, properties, etc. are being stored on the L2 chain, which in turn relays the updated data as upgrades to your NFTs on the L1 chain.
Traditional Gaming Tech & PAIMA Engine: PAIMA gives you the luxury of implementing your game on the blockchain with basic knowledge of how the blockchain works. You only need your traditional web2 technology, like Javascript, Unity, etc. to build your game. The PAIMA engine helps you deploy features on L1 chains like Polygon, Ethereum, BNB, etc.
PAIMA Whirloop: PAIMA enables a seamless process of user acquisition across multiple chains, where you only have to deploy once and your game works in sync interoperably across different chains rather than in fractions.
PAIMA Wallet Supporting System: PAIMA also utilizes an account abstraction-like solution that gives you the luxury of cross-chain wallet support across 6 of the top 7 main L1 chains. Ethereum, Solana, Polygon, Binance, Arbitrum, ImmutableX, Cardano.
Iteration with PAIMA Engine: Using the PAIMA engine gives you a chance to mint predefined updatable assets (NFTs) on the blockchain using Stateful NFTs, They are fully updatable, which is a key feature for any gaming application.
It also helps you schedule updates to your game on-chain where you can ship out bug fixes and new versions of your game in due time, the updates are being signed in new blocks on the blockchain.
Setting up a PAIMA Engine
To set up up your PAIMA engine you can follow the steps below, or reference the official documentation at any time for more information.
Set up a workspace, by running the commands below
mkdir paima_engine cd paima_engine
assuming you don't have any PAIMA template currently running, run the command
npm install @paima/evm-contracts
to install the Paima templates.Once installed, you can run any of the commands below, for their respective following tasks.
npm run initialize # setup the env vars and install dependencies npm run pack # build your state machine npm run pack:middleware # create middleware to connect your state machine to your UI npm run chain:start # separate terminal - creates a local L1 chain for your app npm run chain:deploy # deploys contracts to your local chain npm run database:up # separate terminal - starts the DB to cache the onchain data to speed up queries ./paima-engine run # separate terminal - runs your game L2 node
To connect your wallet for further testing you can follow the steps here, on how to go about it.
Note: Check out the current gaming template of multiple deployable games using the Paima engine.
Smart Contracts with PAIMA Engine
PAIMA also supports the deployment of smart contracts using Hardhat Ignition. You can follow the process below to simulate deploying to your local networks.
Run the command below to create a new workspace folder and change the directory into the folder.
mkdir paima_contract cd paima_contract
Next, run the command
npx hardhat init
to initialize your hardhat development workspace.Run the command
npm install --save-dev @nomicfoundation/hardhat-ignition-ethers@nomicfoundation/hardhat-toolbox
to install thehardhat ignition
,hardhat toolbox
package.Go to your hadhat.config.js file and add the line of code to import the ignition package.
require ("@nomicfoundation/hardhat-ignition-ethers");
Go to the contract folder and rename the
Lock.sol
file toRocket.sol
, that copy and paste the dummy contract below into the solidity file.// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; contract Rocket { string public name; string public status; constructor(string memory _name) { name = _name; status = "ignition"; } function launch() public { status = "lift-off"; } }
Next, run the commands below to create a
ignition/modules
folder.mkdir ignition mkdir ignition/modules
Create a new typescript file
Apollos.js
in your newly created directory, then copy and paste the code below into the file.const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); module.exports = buildModule("Apollo", (m) => { const apollo = m.contract("Rocket", ["Saturn V"]); m.call(apollo, "launch", []); return { apollo }; });
The code above defines a module named
Apollo
using acallback
function that imports thebuildModule
object to create Future objects representing steps to deploy a contract instance and interact with it. It deploys an instance of theRocket
namedSaturn V
with a specified constructor parameter and indicates an intention to execute thelaunch
function of the deployedRocket
instance.Next, run the command
npx hardhat node
, to spin up a local hardhat node, and you should get a response similar to the one below.While you have your local blockchain running on the current terminal, you can open a new terminal to run the other commands.
$ npx hardhat node Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/ Accounts ======== WARNING: These accounts, and their private keys, are publicly known. Any funds sent to them on Mainnet or any other live network WILL BE LOST. Account #0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH) Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 Account #1: 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (10000 ETH) Private Key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d Account #2: 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC (10000 ETH) Private Key: 0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a =========
Copy one of the pairs, create a
.env
file, and paste it as a variable. Run the commandnpm I dotenv
.Finally, run the command
npx hardhat ignition deploy ignition/modules/Apollo.ts --network
localhost
and you have your contract deployed with the response.Hardhat Ignition 🚀 Deploying [ Apollo ] Batch #1 Executed Apollo#Rocket Batch #2 Executed Apollo#Rocket.launch [ Apollo ] successfully deployed 🚀 Deployed Addresses Apollo#Rocket - 0x007A22900a3B98143368Bd5906f8E17e9867581b
and voila🥂*you have your contract deployed on your local network*...
To add a new contract to your existing project you can add the following code below to your hardhat.config.ts file.
const config: HardhatUserConfig = { dependencyCompiler: { paths: [ source: '<path/to/your/new/contract>' ], }, };
To interact with your deployed contract on the local network, you can use the command
npx hardhat --network
localhost
interact
.Also, to find details like the deployment address of your contract, navigate to the location
./contracts/evm/ignition/deployments/chain-XXX/deployed_addresses.json
in your workspace.
Setting up your DataBase
When setting up your database for PAIMA, it's important to note that while Paima typically operates with on-chain data, for more efficient data management, PostgresDB is utilized.
It aligns with common practices in decentralized applications (dApps) and Layer 1 blockchain networks, providing a reliable and mature platform with extensive community support and tooling.
Snapshots of the database are offered as a quality-of-life feature, streamlining the deployment of new game nodes without the need for full resynchronization from scratch in the event of corruption or deletion.
To set up your database for Paima Engine, you can deploy a Postgres database to store all game node states.
Or you can utilize the provided init.sql file in the
/db/migrations/init
folder to initialize the database.Alternatively, for an automated setup, you can use Docker by following the provided steps in the root folder of your game code, which will download, set up, and initialize Postgres automatically.
Ensure to update the init.sql file as you modify the database schema to maintain compatibility with future game nodes.
Resetting the database can be easily achieved by resetting the Docker image using the command
https://docs.docker.com/compose/install/
. It's essential to have your Paima Engine instance and database co-located for optimal performance, as Paima Engine relies on Postgres LISTEN events for cache management.
DataBase SnapShots
Paima Engine automatically generates local snapshots of the database periodically, primarily serving two purposes: restoring the database in case of errors and expediting new game deployments.
These snapshots are stored in a designated folder and created based on the latest block height stored in the game's state machine, with a frequency of every 21600 blocks
. Snapshots are made using pg_dump
for consistent backups, and the runtime manages snapshot deletion, retaining only the two most recent snapshots.
Data Migrations on PAIMA
Data Migrations in Paima Engine enable developers to add data to the database, such as world setup, NPCs, and items, through structured SQL scripts. These migrations are applied at specific block heights, indicated by file names offset from the START_BLOCKHEIGHT
defined in the environment file. The migrations are automatically run as transactions, ensuring consistency, and if they fail, the block-process-loop halts until the script is fixed and reapplied. It's crucial to note that manual addition of data to the database is discouraged, and changes to migrations require rerunning the packaging process for them to take effect.
Onchain Randomness with PAIMA
Randomness, being one of the most crucial parts of any game, prevents users from exploiting statistical trends, but yet is a feature that cannot be accomplished on the blockchain.
In producing globally accessible state machines, randomness is particularly challenging due to determinism. However, randomness can be derived from uncertain factors like block hashes, user input, and block producer information. A seed generation algorithm was proposed to incorporate these factors for randomness.
Prando, a deterministic stateful randomness generator, is introduced as a solution, utilizing a provided seed to generate random numbers in a deterministic manner. Care must be taken when using Prando in parallel or with optimistic updates. You'll find the code snippet below helpful when starting out using Prando.
import Prando from '@paima/sdk/prando';
const prando = new Prando(block.seed);
const diceRoll = prando.nextInt(1, 6);
This code snippet demonstrates how to use Prando to generate a random integer between 1 and 6 based on a provided block seed.
Conclusion
PAIMA Engine helps you utilize blockchain technology to build web3 games, all you need is good founding knowledge on how the blockchain works, and your traditional web2 gaming skills and technologies. There is a vast number of game ideas you can build on utilizing the blockchain and all the amazing features PAIMA can offer.
This tutorial simply lays out the path toward getting you started with the technology by summarizing the official documentation. Check out their official documentation here, for more information on how to start building your ideas with PAIMA Engine on the blockchain.
Subscribe to my newsletter
Read articles from Mayowa Ogungbola directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Mayowa Ogungbola
Mayowa Ogungbola
Hi I'm Phenzic I simply wanna help you transition into web3 seamlessly...