Skip to main content

Create in-game assets

Estimate time to complete: 20 minutes

This tutorial covers one of the most important parts in constructing your web3 game. Here you will mint, and configure NFTs to power your in-game items. As part of this, you'll learn how to do this with our preset contracts for ERC721.

Note: This tutorial will only cover minting and will not cover when and how you would initiate a mint within a gameplay context.

create game assetscreate game assets

This is a beginners guide, lots of the helpful context, important links and preparation material are in the blue collapsed sections. For those more confident, you can skip those.

We cover minting NFTs by contract function call and Minting API. For more information on the Minting API, check out our following product page.

To start, you may want to first familiarise yourself with these concepts
ConceptsDefinition
In-game itemsIn-game items include cards, consumables, collectables, weapons, clothing and equipment that power the aesthetics and mechanics of your game.
On-chain assets (NFTs)In Web3 games, one of the fundamental value propositions is to power some, if not all your in-game items with on-chain assets. This tutorial uses ERC721 smart contracts to do this.
CollectionsWhen minting NFTs, individual NFTs are created as part of a collection. This guide will teach you how to do this.
MetadataTo enable NFTs to be more descriptive, smart contracts can contain metadata, which is information about the special characteristics of each NFT. The metadata of an NFT can describe its characteristics and properties, such as its name, description, transaction history, traits, link to the hosted image, and more. This tutorial will teach you how to configure this.

Task 1: Set up basic metadata hosting

To enable NFTs to be more descriptive, metadata is used to contain information about the special characteristics of each token. This can include its name, description, transaction history, traits, link to the hosted image, and more.

At scale, you will need to provide this information through a server, but we'll use Github Pages today to minimize the infrastructure setup. Begin by forking our Sample Project Metadata repository:

Sample Project Metadata

You should now have your very own repository! Next, we need to make this repository visible through Github Pages:

  1. Your Repository > Settings > Pages
  2. Set the Source to "deploy from a branch".
  3. Set the Branch to main or master branch and click save.
Visual guide for setting up your Metadata repo

From the Sample Project Metadata repository you can select "Fork" in the toolbar.

Forking your repository

Once forked, you should see "Settings" appear in your forked version of the repository.

Selecting settings

Once in Settings, locate "Pages" on the left hand side menu and set up according to the instructions.

  • Set the Source to "deploy from a branch".
  • Set the Branch to main or master branch and click save.
Selecting up your branch

Task 2: Customise your NFT metadata

We've already provided you with 3 sample metadata files and images out of the box - let's make a few quick changes to customise your collection!

The minimum files you'll need to update are:

  • Metadata files in the ../tokens/ directory: URLs for your images for each NFT (file name contains Token ID value: e.g. 1, 2, 3) under the image field; replacing the https://immutable.github.io/sample-project-metadata/tokens/token1.webp, ../tokens/token2.webp and ../tokens/token3.webp values from the 3 samples provided.
  • collection.json: Name of your collection under the name and description fields. Also populate the collection image URL under the image field
💡If you host your images within your forked GitHub repo
Your URL will look similar to this:
https://<your github name>.github.io/<your fork name>/<directory>/<filename>
First, we need to configure the collection-level metadata for our project by modifying our `collection.json` file:
{
"name": "YOUR_COLLECTION_NAME",
"description": "YOUR_COLLECTION_DESCRIPTION",
"image": "YOUR_IMAGE_URL",
"external_link": "YOUR_WEBSITE_URL"
}

To modify the metadata of the individual NFTs, we need to modify the json files in the /tokens folder. You'll note that the files are named 1, 2 and 3: this corresponds exactly to the unique token_id of each token. NFT metadata follows the standard defined by Opensea, and should look like this:

{
"id": 1,
"image": "YOUR_IMAGE_URL",
"token_id": "1",
"background_color": null,
"animation_url": null,
"youtube_url": null,
"name": "Test zkEVM NFT",
"description": "This NFT is my first zkEVM NFT created on Immutable",
"external_url": null,
"attributes": [
{
"trait_type": "Hat",
"value": "Top Hat"
},
{
"trait_type": "Coat",
"value": "Tails"
},
{
"trait_type": "Neck",
"value": "Bow Tie"
},
{
"display_type": "number",
"trait_type": "Level",
"value": 1
}
]
}

As you've probably noticed, modifying this metadata for each NFT individually is slow and frustrating. This is OK for our quickstart tutorial, but is not recommended for real games! If you want to learn how to set up metadata hosting at scale, see our metadata documentation.

We now have two very important URLs - remember these for later!

  • Contract Metadata URI: https://<your github name>.github.io/<your fork name>/collection.json
  • Token Base URI: https://<your github name>.github.io/<your fork name>/tokens/
tip

Blockscout currently requires a '/' at the end of the Token Base URI to index metadata correctly. Immutable's Blockchain Data API does not require this, however for consistency we recommend adding a '/' to the end of the Token Base URI for Blockscout compatibility.

Task 3: Setup admin wallet

For the purpose of this tutorial, all you'll need to do is download the Metamask browser wallet and follow the steps to store your seed phrase in a safe location.

Immutable Hub will take care of setting up the chain network details and faucet the tIMX tokens (for Testnet only) you'll need to pay for gas automatically in Task 4 as you deploy your contract.

If you need to manually top up your tIMX tokens you can do so via Immutable Hub by visiting the Faucet.

Task 4: Deploy ERC-721 preset contract

Go to the project you've previously set up in Immutable Hub.

Connect your minting Metamask wallet by clicking the Connect Wallet button on the top right menu of the Immutable Hub and navigate to your project and environment.

In the Collections submenu, click Deploy contract:

  • Create a Name for your collection
  • Create a Symbol for your collection that is 2-3 characters long
  • Paste the Token Base URI from above into the Base URI field
  • Paste the Contract Metadata URI from above into the Collection Metadata URI field
Deploy contract modal
  • Enter the wallet address you created earlier as the royalty recipient
  • Enter 5 for Royalty fee. For the purpose of this tutorial, we will set royalty to be 5% default.
  • Click on the Use connected wallet button for Minter Address. This will automatically populate the field with your connected wallet address, allowing it to mint tokens. Alternatively, you can enter the address of another wallet.
  • If you want to use the Minting API, check the Enable Minting API checkbox.
  • Click Deploy
  • Immutable Hub will automatically check your wallet's connected network. If your network is not already connected to the respective chain (IMX zkEVM Testnet or IMX zkEVM Mainnet), then you will prompted in Metamask to switch. Here, select Switch Network. If you are deploying on Testnet, tIMX will be automatically given to you via our faucet as part of the process.
Switching network
  • You will be prompted to sign a transaction with your wallet. This step costs gas and will deploy your contract.
Deploying contract
  • You will be prompted to sign a message with your wallet. This step is gasless and will link your collection to your project's environment.
Linking collection
  • Finally, you will be prompted to sign a transaction with your wallet. This step costs gas and will assign your wallet the minter role, so that you can mint tokens on the collection.
Granting minter role
🎉Contract Deployed Successfully!
You can now view your contract on the Immutable zkEVM Testnet Explorer or the Immutable zkEVM Mainnet Explorer by searching for your collection address (visible in Hub). Alternatively, you can click on your deployed contract in the Immutable Hub and click the Block Explorer link.
💡Advanced: launch contract manually
Instead of using Immutable Hub, you can launch your contracts via code with these steps:
  1. Set up your admin wallet and the zkEVM Testnet Network by following instructions here
  2. Follow instructions on deploying your contracts via code and request to be allowlisted
All collections on zkEVM are required to use Immutable's operator allowlist to protect content creators royalties and Immutable's 2% protocol fee. All Immutable Hub collections automatically utilise this functionality.
💡MANDATORY COMPLIANCE

To make sure that creators receive their hard earned loyalties, Immutable requires that all collections of ERC-721/1155s deployed on Immutable zkEVM implement the Operator Allowlist. Not implementing will have these effects for your collection (i.e. ERC-721/1155s):

  1. You may forfeit any token grants you may have received.
  2. Passport users will receive a warnings that your collection is likely to be counterfeit.
  3. Your collection will not appear on any of the 3rd party marketplaces in our ecosystem.

For more information on the Operator Allowlist, please see this guide.

Task 5: Mint tokens

You can mint tokens in three different ways: via a contract function call, via the Minting API with a reference ID, or via the Minting API with a token ID. Select the option that best suits your needs below:

caution

Immutable's recommended ERC721 preset contract has multiple batch minting strategies tailored for different minting scenarios, which can save significant gas costs while minting.

5.4.1: Set up your project backend (Node.js)

We have already created a sample project which you can clone to mint quickly and easily:

Basic Preset Minting

git clone https://github.com/immutable/basic-preset-minting
cd basic-preset-minting
npm i

5.4.2: Grant minting permissions

💡This may already be done for you
If you have deployed a contract through the Immutable Hub, and you've used your deployed wallet address as the input to the `Minter Address` field this will already have been done for you. If not, you can follow the steps below.

To mint NFTs, we need to use our "owner" wallet (which deployed our contract) to grant another wallet minting rights for our collection. In this tutorial, we're going to add the "minter" role to our existing "owner", so you don't need to set up a new wallet.

First, we will need to export your owner wallet's private key so it can be used in local scripts.

5.4.2.1 Locate your wallet's private key

💡Protect your private key
The script needs your wallet's private key, obtainable from Metamask by following these steps. Be cautious not to expose it in public or production code to safeguard your wallet's security.
  1. Open Metamask
  2. Make sure the network at the top of the screen is the test network you wish to deploy to
  3. Open Account details by clicking on the following button and selecting Account details
Upload File
  1. Select Show Private Key and enter your password
  2. Copy the long string provided (your private key) as this will be needed in the next step.

5.4.2.2 Add your private key to the .env file

We now need to configure your project with your private key in order to grant it the requisite authorisation to mint tokens. First, copy the code in .env.sample into a new .env file. Next, add the two variables below - the remaining variables will be set later:

  • CONTRACT_ADDRESS - The contract address of your collection - you can find this on Immutable Hub.
  • OWNER_PRIVATE_KEY - The private key you exported.

5.4.2.3 Perform the role grant

To complete the grant, simply run the following script:

npm run grant-role

5.4.3: Minting directly via the collection's mint function

To mint our first NFTs, we're once again going to use a sample script from the repository we cloned earlier. In the sample script, we mint 3 NFTs and distribute them to 2 recipient wallets - you can change this to suit your requirements.

All we need to do is ensure the remaining variables are now set in our .env file:

  • MINTER_PRIVATE_KEY - The private key of the wallet we just granted the minter role (may be same as Owner Private Key)
  • RECIPIENT_ONE - The first address of the wallet that will own the NFTs being minted in the batch
  • RECIPIENT_TWO - The second address of the wallet that will own the NFTs being minted in the batch

Now all that's left is to execute the mint itself:

npm run mint
🎉Congratulations on minting your first zkEVM NFTs!
You can use the tokens section of the Immutable zkEVM Testnet Explorer or the Immutable zkEVM Mainnet Explorer to verify that your assets have been minted on-chain (search for your collection address). You can also verify that the NFT is minted via the Immutable Hub interface.

6: Have Immutable verify your assets

Once you've deployed your collection or token, Immutable recommends all games verify their asset contracts, as it enhances player and trader confidence in engaging with transactions involving verified assets. For detailed information about Immutable's asset verification procedures, please refer to this guide.

To verify your assets do the following:

  1. Verify your contract via Immutable's explorer. For more information on verifying your smart contract on Immutable's Explorer check out this guide.
  2. In Hub, navigate to your deployed collection and click on it to view the details. Click the Verify with Immutable button located in the top right-hand corner.
verify button in hub
  1. Immutable will review your request and assign a verification status. Once this process is complete, your collection will display the assigned verification status.
verified collections in hub
tip

If you deploy an erroneous collection on mainnet, please inform your Immutable account manager or notify us via Discord to have the collection labeled as Inactive. This status will indicate to your gaming community and marketplaces that the assets associated with this collection should be ignored.