Back to blog

How To Store Procedurally Generated Game Maps on IPFS

How To Store Procedurally Generated Game Maps on IPFS

Pinata

The gaming industry is ever-evolving, with procedural generation leading the charge in creating vast, dynamic worlds. But once these worlds are created, the question of storage becomes critical. Enter IPFS and Pinata: a duo that promises decentralized, persistent, and efficient storage solutions for your procedurally generated landscapes. Let's dive into a practical guide, complete with code snippets, on how to store your game maps on IPFS using Pinata.

Procedural Generation and Serialization

Procedural generation allows for the creation of content algorithmically. In games, this often means terrain, levels, and maps that are unique to each playthrough. Below is a pseudo-code snippet for generating a simple 2D map:

import numpy as np

def generate_map(width, height, seed=None):
    if seed:
        np.random.seed(seed)
    return np.random.randint(0, 2, (width, height))  # Example: 0 for land, 1 for water

# Generate a 100x100 map
game_map = generate_map(100, 100)

After generation, you need to serialize your map. Serialization converts your map into a storable and transmittable format.

import json

# Serialize the numpy array to a list for JSON compatibility
map_list = game_map.tolist()
serialized_map = json.dumps(map_list)

with open('map.json', 'w') as file:
    file.write(serialized_map)

Compressing Serialized Maps

File compression is crucial for optimizing storage. Here's how you can compress your JSON file using Python:

import gzip

with open('map.json', 'rb') as orig_file:
    with gzip.open('map.json.gz', 'wb') as zipped_file:
        zipped_file.writelines(orig_file)

Uploading to IPFS via Pinata

Pinata provides an API that makes it easy to upload files to IPFS. First, you'll need to install the requests library if you haven't already:

pip install requests

Now, let's use the Pinata API to upload our compressed map:

import requests

# Replace 'YOUR_PINATA_JWT' with your actual Pinata API Key JWT
headers = {
    'Authorization': 'Bearer YOUR_PINATA_JWT'
}

# Endpoint for Pinata's 'pin file to IPFS' functionality
url = 'https://api.pinata.cloud/pinning/pinFileToIPFS'

# Read the contents of your compressed file
with open('map.json.gz', 'rb') as fp:
    file_binary = fp.read()

# Use 'multipart/form-data' for uploading files
files = {'file': ('map.json.gz', file_binary)}

response = requests.post(url, files=files, headers=headers)

# Get the IPFS hash (CID) from the response
cid = response.json().get('IpfsHash')
print(f'Successfully uploaded with CID: {cid}')

Retrieving the Content Identifier (CID)

After uploading, Pinata will provide a CID, which you'll use to reference your map:

# Assume response is the result from the previous upload step
if response.status_code == 200:
    cid = response.json()['IpfsHash']
    print(f"Map CID: {cid}")
else:
    print("Upload failed.")

Accessing Your Map in-Game

To retrieve your map in-game, you might use an HTTP request to an IPFS gateway:

// Example in C# for Unity
IEnumerator GetMapFromIPFS(string cid) {
    string url = $"https://gateway.pinata.cloud/ipfs/{cid}";
    UnityWebRequest request = UnityWebRequest.Get(url);

    yield return request.SendWebRequest();

    if (request.isNetworkError || request.isHttpError) {
        Debug.LogError(request.error);
    } else {
        // Handle the retrieved map data
        byte[] mapData = request.downloadHandler.data;
        // ... Decompress and deserialize ...
    }
}

Why Choose IPFS with Pinata for Your Game Maps?

Using IPFS for storing game maps ensures distributed, fault-tolerant access to your content, while Pinata's pinning service guarantees availability. This combo allows for a scalable solution as your game grows.

Conclusion and Next Steps

We've walked through generating, serializing, compressing, uploading, and retrieving game maps with IPFS and Pinata. Implementing this solution in your development pipeline can save on traditional hosting costs and provide a resilient storage solution.

For full integration, consider automating these steps within your game's backend or build pipeline to streamline the process from map generation to player access.

Happy coding!

Subscribe to paid plan image

Share this post:

Stay up to date

Join our newsletter for the latest stories & product updates from the Pinata community.