Terracore HUB - Dev Diary #1

in HiveDevslast year

Considering this is my fourth consecutive post about Terracore, it should be clear to everyone that I'm a fan of the game mechanics and impressed by how fast @crypt0gnome is pushing it forward 😄

However, this post has a slightly different focus as it is more oriented towards software developers. If you're not interested in software development-related topics, you can stop reading now or proceed at your own risk ⚠️

Dev Diary #1


A couple of weeks ago, I came across this exciting announcement: https://vercel.com/storage/postgres
Basically a service that provides a simple way to connect to a Postgres database from a serverless environment.

Vercel Postgres

Since TerracoreHUB was already deployed on Vercel, I decided to give it a try. It's also a perfect fit for a new feature I had in mind that couldn't be implemented using the official Terracore API.

The new feature I wanted to create was relatively straightforward: an Item Archive page that allows players to view all items ever created and query/sort them using specific filters.

To help you understand the process, I'll provide a short step-by-step guide. Overall, I'm thrilled with how easy it was to set up this new feature, and I hope others will find it useful too.

Step 1 - Creating the Database

Creating the database was incredibly easy and straightforward. Everything can be done directly from the Vercel dashboard:

image.png

Once the database is created, it can be attached to an existing project. The setup process is quite similar to creating and using a database on Heroku.

Step 2 - Connect to the Database

After connecting the database to the project, some environment variables are automatically injected into the project settings. These variables allow the Node.js code to connect to the database using a standard Postgres library or an ORM framework. I have some previous experience with Prisma, and the good news is that it is one of the supported frameworks. There's also a "starter" project available at https://vercel.com/templates/next.js/postgres-prisma. Since I don't use Next.js for TerracoreHUB, I had to adapt the starter project to my specific needs.

The dependencies for this project are minimal, and the package.json file is quite short:

  "scripts": {
    "build": "prisma generate && prisma db push"
  },
  "dependencies": {
    "@prisma/client": "4.13.0",
    "@types/node": "18.15.11",
    "@vercel/node": "^2.14.0",
    "@vercel/postgres": "^0.1.3",
    "axios": "^1.4.0",
    "ts-node": "^10.9.1",
    "typescript": "5.0.4"
  },
  "devDependencies": {
    "prisma": "^4.13.0"
  }

The Prisma schema used to store the NFTs/items is also straightforward:

  model items {
    item_number     Int      @id
    createdAt       DateTime @default(now())
    updatedAt       DateTime @default(now())
    name            String
    id              Int
    edition         String
    max_supply      Int
    description     String
    image           String
    type            String
    rarity          String
    defense         Float
    damage          Float
    engineering     Float
    dodge           Float
    crit            Float
    luck            Float

    @@index([item_number(sort: Desc)])
    /* More indexes here ... */
  }

Step 3 - Fetching NFTs from Terracore

To populate the database, we need to fetch item details from the Terracore game itself. There is an API endpoint to fetch the details of a specific item:

https://terracore.herokuapp.com/item/{ITEM_NUMBER}

Since new items are created frequently, I wrote a simple function to check the latest item_number stored in the Postgres database and use the Terracore API to see if a new item has been minted. If there are new items, they are fetched and stored. Otherwise, the local database is up to date, and there is nothing else to do.

Here's the minimal code for this function:

  console.info('Fetching new items from Terracore API')

  const lastItemRecords = await prisma.items.findMany({
    orderBy: { item_number: 'desc' },
    take: 1
  })

  const lastItemNumber = lastItemRecords.length ? lastItemRecords[0].item_number : 0
  console.info('Last stored item_number: ' + lastItemNumber)

  let nextItemNumber = lastItemNumber
  while (true) {
    nextItemNumber += 1

    try {
      const apiResult = await axios.get(`${endpoint}/${nextItemNumber}`).then(response => response.data)

      // stop if there is an error
      if (apiResult?.item_number === undefined || apiResult?.error) {
        break
      }

      const item = {
        item_number: apiResult.item_number,
        /* ... */
      }

      await prisma.items.create({ data: item })
  }

This function is triggered by a cron job at regular interval (a cron job scheduler is provided by Vercel).

Please note that not all details of a specific NFT are static. Some properties, (like "owner") can change over time and the item can be "salvaged" (burned) to get FLUX. Check out @terracore blog to understand more about the game mechanics.
For this reason, TerracoreHUB only stores the static details and fetches everything else on demand when needed (usually in a dedicated popup for a specific item).

Step 4 - Providing an API for the Frontend

Now that everything is stored in a database, a simple serverless function can provide the API used to populate the Item Archive page on TerracoreHUB. Vercel and Prisma already provide most of the code to do handle such a simple REST API:

  const filters = {
    type: '...',
    edition: '...',
    rarity: '...',
  }

  const limit = 200
  const offset = 0
  const sort = ...
  const sortDir = 'asc'

  const items = await prisma.items
    .findMany({
      where: filters,
      orderBy: [{ [sort]: sortDir }],
      skip: offset,
      take: limit
    })
    .then((records) =>
      records.map((item) => ({
        item_number: item.item_number,
        /* ... */
      }))
    )

  return response.status(200).json(items)

Step 5 - Check out the Item Archive page

If you're curious, this is the final result: https://terracorehub.com/items

It's an "archive" page with all the NFTs minted on Terracore that can be filtered, sorted, and paginated.

Item Archive page


BTW even if you use Terracore HUB my suggestion is to still check out the official game website at https://www.terracoregame.com !!


That's all for now, see you next time 👋

Sort:  

Isn’t it similar to Supabase?

Yep, quite similar actually. I considered both and decided to test Vercel as I have already tested Supabase in the past.

This post has been supported by @Terraboost with a 70% upvote! Delagate HP to Terraboost to Earn Daily HIVE rewards for supporting the @Terracore community!

Play Terracore | Delegate HP | Join Discord

:O I didnt know we had a game like that inside of hive!