Create NFT Loader API

In this topic you will create an API that will handle the loading of an NFT and spawn the correct templates for the NFT loaded based on the attributes you set.

An API (Application Programming Interface) will contain the bulk of the code that would usually be duplicated across files. This allows you to have a set of functions that are shared between your scripts. This makes maintaining the code and applying bug fixes a lot more manageable and quicker.

Create NFTAxeLoader Script

Create a new script called NFTAxeLoader.

  1. In Project Content, click on the NFTAxeLoader script, then find the Blades data table and drop it onto the script as a custom property.
  2. In Project Content, click on the NFTAxeLoader script, then find the Handles data table and drop it onto the script as a custom property.

Edit NFTAxeLoader Script

Open up the NFTAxeLoader script and add the following variables for the custom property references and the API table. The variable NFTAxeLoader is the API that will encapsulate all of the properties and functions that can be used by other scripts when the API is required.

local BLADES = require(script:GetCustomProperty("Blades"))
local HANDLES = require(script:GetCustomProperty("Handles"))

local NFTAxeLoader = {}
Code language: Lua (lua)

Create ColorMeshes Function

Create a function called ColorMeshes. This function will go through all the static meshes of the blade and handle for the Axe, and set the color of each material slot. Since the loader will be using a seed that is pulled from the NFT attributes, then when picking a random color, it will pick the one that was used when generating the Axe. If you need to ignore a static mesh, you can add the Ignore property to it.

function NFTAxeLoader.ColorMeshes(item, seed)
	local meshes = item:FindDescendantsByType("StaticMesh")
	local ColorRNG = RandomStream.New(seed)

	for m, mesh in ipairs(meshes) do
		if mesh:GetCustomProperty("Ignore") == nil or not mesh:GetCustomProperty("Ignore") then
			local material_slots = mesh:GetMaterialSlots()

			for s, slot in ipairs(material_slots) do
				slot:SetColor(Color.New(ColorRNG:GetNumber(), ColorRNG:GetNumber(), ColorRNG:GetNumber()))
			end
		end
	end
end
Code language: Lua (lua)

Create Load Function

Create a Load function. This function receives a token ID and contract address that will be used to fetch a specific NFT.

When calling GetToken, the script will yield until the function returns, meaning that the script will pause until the function returns. Notice that the GetToken function returns 3 values. This is so that we can check to make sure the return status of the GetToken function was a success. We can do that by comparing the value stored in status against the enum BlockchainTokenResultCode.SUCCESS.

An important part of this function is reading the attributes of the NFT. The attributes are like the DNA of the NFT, it tells us how it should be made. In this case, it contains 3 attributes that we can check for when we loop over all of them. For each match of the attribute, we spawn either an asset or color the meshes. Notice that the coloring of the meshes is done last in the group to make sure there are meshes to look for.

function NFTAxeLoader.load(player, tokenID, contractAddress, parentGroup)
	local token, status, errorMsg = Blockchain.GetToken(contractAddress, tokenID)

	if status == BlockchainTokenResultCode.SUCCESS then
		local attributes = token:GetAttributes()
		
		for index, child in ipairs(parentGroup:GetChildren()) do
			child:Destroy()
		end
		
		for index, attribute in ipairs(attributes) do
			if attribute.name == "Blade" then
				World.SpawnAsset(BLADES[tonumber(attribute:GetValue())].Template, { parent = parentGroup, networkContext = NetworkContextType.NETWORKED })
			end

			if attribute.name == "Handle" then
				World.SpawnAsset(HANDLES[tonumber(attribute:GetValue())].Template, { parent = parentGroup, networkContext = NetworkContextType.NETWORKED })
			end

			if attribute.name == "Seed" then
				NFTAxeLoader.ColorMeshes(parentGroup, attribute:GetValue())
			end
		end
	else
		print(errorMsg)
	end
end
Code language: Lua (lua)

Return the API

The script needs to return something. In this case, we return the NFTAxeLoader table so that any script requiring this API will have access to all the functions.

return NFTAxeLoader
Code language: Lua (lua)

The NTFAxeLoader Script

local BLADES = require(script:GetCustomProperty("Blades"))
local HANDLES = require(script:GetCustomProperty("Handles"))

local NFTAxeLoader = {}

function NFTAxeLoader.ColorMeshes(item, seed)
	local meshes = item:FindDescendantsByType("StaticMesh")
	local ColorRNG = RandomStream.New(seed)

	for m, mesh in ipairs(meshes) do
		if mesh:GetCustomProperty("Ignore") == nil or not mesh:GetCustomProperty("Ignore") then
			local material_slots = mesh:GetMaterialSlots()

			for s, slot in ipairs(material_slots) do
				slot:SetColor(Color.New(ColorRNG:GetNumber(), ColorRNG:GetNumber(), ColorRNG:GetNumber()))
			end
		end
	end
end

function NFTAxeLoader.load(player, tokenID, contractAddress, parentGroup)
	local token, status, errorMsg = Blockchain.GetToken(contractAddress, tokenID)

	if status == BlockchainTokenResultCode.SUCCESS then
		local attributes = token:GetAttributes()
		
		for index, child in ipairs(parentGroup:GetChildren()) do
			child:Destroy()
		end
		
		for index, attribute in ipairs(attributes) do
			if attribute.name == "Blade" then
				World.SpawnAsset(BLADES[tonumber(attribute:GetValue())].Template, { parent = parentGroup, networkContext = NetworkContextType.NETWORKED })
			end

			if attribute.name == "Handle" then
				World.SpawnAsset(HANDLES[tonumber(attribute:GetValue())].Template, { parent = parentGroup, networkContext = NetworkContextType.NETWORKED })
			end

			if attribute.name == "Seed" then
				NFTAxeLoader.ColorMeshes(parentGroup, attribute:GetValue())
			end
		end
	else
		print(errorMsg)
	end
end

return NFTAxeLoader
Code language: Lua (lua)
Scroll to Top