Create Crypts and Caverns API

Create a new script called CryptsAndCaverns. This script will contain functions to help load the NFT and do the conversion so it can be passed to the Build function of the MapBuilder API.

After creating the script, you will need to add the 3 scripts that were imported previously so that the CryptsAndCaverns code has references to them.

  1. Select the CryptsAndCaverns script in My Scripts found in Project Content.
  2. Add the Base64 script as a custom property.
  3. Add the JSON script as a custom property.
  4. Add the SVGParser script as a custom property.

Edit CryptsAndCaverns Script

Open up the CryptsAndCaverns script and add the following code that will require the libraries that were added as custom properties.

local BASE64 = require(script:GetCustomProperty("Base64")) local JSON = require(script:GetCustomProperty("JSON")) local SVG_PARSER = require(script:GetCustomProperty("SVGParser"))
Code language: Lua (lua)

Create CryptsAndCaverns Table

Create a table called CryptsAndCaverns and set up the properties for the contract address and the collection count. The reason for the collection count is so that a random token ID can be retrieved to load a random map if required.

local CryptsAndCaverns = { SMART_CONTRACT_ADDRESS = "0x86f7692569914b5060ef39aab99e62ec96a6ed45", COLLECTION_COUNT = 8784 }
Code language: Lua (lua)

Create Load Function

Create a new function called Load. This function will accept an optional parameter that will either load the NFT based on the token ID passed in, or load a random NFT. The function will use the libraries that have been required to decode the data and convert it into something usable that will be returned back.

Using the Blockchain API, you can retrieve a token using the GetToken function. This function request the smart contract address, and a token ID. When passing the token ID to the GetToken function, make sure it is a String type.

After fetching the token, you need to fetch the rawMetadata and extract the first Bas64 encoded string. When decoded, it will contain a table that contains information about the NFT, but most importantly it contains another Base64 encoded string that contains the image data in SVG format. The SVG string is sent to the SVG Parser which will create a map based on the data. This is then in a compatiable format that can be converted into ASCII.

function CryptsAndCaverns.Load(tokenId) local token = Blockchain.GetToken(CryptsAndCaverns.SMART_CONTRACT_ADDRESS, tostring(tokenId or math.random(CryptsAndCaverns.COLLECTION_COUNT))) if(token ~= nil) then local metadata = token.rawMetadata local _, base64String = CoreString.Split(metadata, ",") local decodedBase64String = BASE64.decode(base64String) local objMetadata = JSON.decode(decodedBase64String) local _, SVGBase64String = CoreString.Split(objMetadata.image, ",") local rawSVG = BASE64.decode(SVGBase64String) local parser = SVG_PARSER:New(rawSVG) local mapData = parser:GetMap() local rows = parser:GetRows() local cols = parser:GetCols() local convertedMapData = CryptsAndCaverns.ConvertData(mapData, rows, cols) local convertedASCII = CryptsAndCaverns.GetConvertedASCII(convertedMapData) return convertedASCII, rows, cols else warn("Could not load token.") end return "", 0, 0 end
Code language: Lua (lua)

Create ConvertData Function

Cretae a new function called ConvertData that will be called from within the Load function. It will receive the map data from the SVG Parser, the total columns and rows. This function will go through each cell of the mapData table to make sure it is all valid. It will add random enemies spawn points and a random player spawn point to the map. This is then a valid map that will then be converted to ASCII to be used to build the 3D map in world.

function CryptsAndCaverns.ConvertData(mapData, cols, rows) local wallString = nil local converted = {} local hasSpawn = false for row = 1, #mapData do for col = 1, #mapData[row] do if mapData[row][col] ~= "-" and not wallString then wallString = mapData[row][col] break end end end local allZeroTiles = {} for row = 1, rows do table.insert(converted, {}) for col = 1, cols do local entry = mapData[row][col] if entry == wallString then converted[row][col] = "1" else local spawnEnemy = math.random(1, 100) if spawnEnemy <= 10 then converted[row][col] = "E" else local value = "0" if(not hasSpawn) then local isSpawn = math.random(30) if(isSpawn == 1) then value = "S" hasSpawn = true end end converted[row][col] = value if value == "0" then allZeroTiles[#allZeroTiles + 1] = { row, col } end end end end end if(not hasSpawn and #allZeroTiles > 0) then local spawnTile = allZeroTiles[math.random(#allZeroTiles)] converted[spawnTile[1]][spawnTile[2]] = "S" end return converted end
Code language: Lua (lua)

Create GetConvertedASCII Function

Create a new function called GetConvertedASCII that will turn the map data into a valid ASCII string that can then be sent to the MapBuilder script to build the map.

function CryptsAndCaverns.GetConvertedASCII(converted) local str = "" for r = 1, #converted do for c = 1, #converted[r] do str = str .. string.sub(tostring(converted[r][c]), 1, 1) .. "" end str = str .. "\n" end return str end
Code language: Lua (lua)

Return CryptsAndCaverns

Whenever you created a Lua library/API you need to return something back so that scripts which require the library/api can use the functions within it. In this case you want to return the CryptsAndCaverns table and the end of the script.

return CryptsAndCaverns
Code language: Lua (lua)

The CryptsAndCaverns Script

local BASE64 = require(script:GetCustomProperty("Base64")) local JSON = require(script:GetCustomProperty("JSON")) local SVG_PARSER = require(script:GetCustomProperty("SVGParser")) local CryptsAndCaverns = { SMART_CONTRACT_ADDRESS = "0x86f7692569914b5060ef39aab99e62ec96a6ed45", COLLECTION_COUNT = 8784 } function CryptsAndCaverns.Load(tokenId) local token = Blockchain.GetToken(CryptsAndCaverns.SMART_CONTRACT_ADDRESS, tostring(tokenId or math.random(CryptsAndCaverns.COLLECTION_COUNT))) if(token ~= nil) then local metadata = token.rawMetadata local _, base64String = CoreString.Split(metadata, ",") local decodedBase64String = BASE64.decode(base64String) local objMetadata = JSON.decode(decodedBase64String) local _, SVGBase64String = CoreString.Split(objMetadata.image, ",") local rawSVG = BASE64.decode(SVGBase64String) local parser = SVG_PARSER:New(rawSVG) local mapData = parser:GetMap() local rows = parser:GetRows() local cols = parser:GetCols() local convertedMapData = CryptsAndCaverns.ConvertData(mapData, rows, cols) local convertedASCII = CryptsAndCaverns.GetConvertedASCII(convertedMapData) return convertedASCII, rows, cols else warn("Could not load token.") end return "", 0, 0 end function CryptsAndCaverns.ConvertData(mapData, cols, rows) local wallString = nil local converted = {} local hasSpawn = false for row = 1, #mapData do for col = 1, #mapData[row] do if mapData[row][col] ~= "-" and not wallString then wallString = mapData[row][col] break end end end local allZeroTiles = {} for row = 1, rows do table.insert(converted, {}) for col = 1, cols do local entry = mapData[row][col] if entry == wallString then converted[row][col] = "1" else local spawnEnemy = math.random(1, 100) if spawnEnemy <= 10 then converted[row][col] = "E" else local value = "0" if(not hasSpawn) then local isSpawn = math.random(30) if(isSpawn == 1) then value = "S" hasSpawn = true end end converted[row][col] = value if value == "0" then allZeroTiles[#allZeroTiles + 1] = { row, col } end end end end end if(not hasSpawn and #allZeroTiles > 0) then local spawnTile = allZeroTiles[math.random(#allZeroTiles)] converted[spawnTile[1]][spawnTile[2]] = "S" end return converted end function CryptsAndCaverns.GetConvertedASCII(converted) local str = "" for r = 1, #converted do for c = 1, #converted[r] do str = str .. string.sub(tostring(converted[r][c]), 1, 1) .. "" end str = str .. "\n" end return str end return CryptsAndCaverns
Code language: Lua (lua)
Scroll to Top