Disclaimer: The content of this document is intended for Solidity developers and other interested parties. It is currently a work in progress and should not be construed as a final product or representation of any business undertaking. Decentralized smart contracts inherently involve a significant degree of risk and uncertainty, and therefore, the information provided herein should be regarded solely for educational purposes.
Start a micro-community among members of your NFT community to host your own Swamp game for the 2M+ ōLanders.
A “Host” intends to run an or recurring events in the Swamp for the NFT communities that are there.
This document details the valuable process of hosting and creating events at a technical level with several examples.
The createEvent
function in the provided Solidity code is designed for NFT communities to create and manage events within a decentralized application. This functionality can be particularly useful for NFT communities that want to host events, competitions, or other types of gatherings where participants can engage in various activities and earn rewards.
Function Parameters (Solidity)
function createEvent(
string memory name,
uint256 startBlock,
uint256 endBlock,
uint256 xStart,
uint256 xEnd,
uint256 yStart,
uint256 yEnd,
uint256 probability,
uint256 powerReward,
uint256 supply,
address ercReward,
address tokenGate
) public
name
: A string representing the name of the event.
startBlock
: A uint256 representing the starting block number for the event.
endBlock
: A uint256 representing the ending block number for the event.
xStart
, xEnd
, yStart
, and yEnd
: uint256 values representing the coordinates of the event's location within a grid.
probability
: A uint256 value representing the probability of a successful action within the event.
powerReward
: A uint256 value representing the power reward for participants in the event.
supply
: A uint256 value representing the total supply of rewards for the event.
ercReward
: An address representing the ERC20 token used as a reward for the event.
tokenGate
: An address representing a gatekeeping mechanism that controls access to the event.
Imagine an NFT community that focuses on virtual boat racing. The community's organizer wants to create an event called "BoatRace2023" with specific coordinates, a probability of 50%, a power reward of 100, a total supply of 1000 rewards, and an ERC20 token for rewards. The organizer would call the createEvent
function with the following parameters:
createEvent(
"BoatRace2023",
1000000,
1005000,
0,
999,
0,
999,
50,
100,
1000,
0x1234567890123456789012345678901234567890,
0x0987654321098765432109876543210987654321 // their required NFT contract.
);
This would create an event called "BoatRace2023" starting at block 1000000 and ending at block 1005000, with coordinates ranging from (0, 0) to (999, 999), a probability of 50%, a power reward of 100, a total supply of 1000 rewards, and using the specified ERC20 token as rewards. The event is gated by the specified token gate contract. Now, only members who also own their BoatRace NFT can participate in the event and you could use things like the eventPowerScore
to power the limit.
Suppose there is an artist who wants to create an event using this contract, where participants will have a chance to win a limited edition NFT. They would follow these steps:
Deploy their version of the ERC1155-E smart contract, which includes the “reward” function required to incentives players.
Call the createEvent
function to create an event with the desired parameters. This creates an event called "Limited Edition NFT Event" that starts in 1000 blocks, ends in 5000 blocks, and targets squares within x: 100-200 and y: 100-200. Participants have a 10% chance of winning a reward, and the power reward is 50. There are only ten rewards available, and the event is associated with a reward contract and a token gate contract.
createEvent(
"Limited Edition NFT Event",
block.number + 1000,
block.number + 5000,
100,
200,
100,
200,
10,
50,
10,
addressOfRewardContract, // Address of the contract that will handle NFT rewards
addressOfTokenGate // Address of a contract that will serve as a token gate for entry
);
Any NFT community can participate in the event by owning a boat or joining a swamp boat using the joinSwampBoat
function. They can perform actions like "fishing" or "farting" to increase their boat's power score.
Once the event is active, users can move their boats within the grid to reach the target square.
If a user reaches the target square, they have a 10% chance of receiving one of the limited edition NFTs as a reward.
The artist can create other events with different rewards, probabilities, and conditions. They could also use the SwampBoat smart contract to create an event where users are awarded other tokens, like ERC20 or ERC1155 tokens, for participating in the game or reaching specific squares on the grid.
And that’s it your event will show up on the global feed at the https://swamp.overline.network.
PowerEvent is a game where players own digital assets, represented by Non-Fungible Tokens (NFTs), which have an associated "Power Score." The Power Score determines the strength of the NFT within the game. The game consists of events, during which NFTs compete against each other based on their Power Scores. The NFTs are tied to match Swamp Boat NFT tokenIDs, essentially meaning you can never get your PowerEvent NFT back for your matching Swamp Boat if it is lost. Here's a high-level overview of how the PowerEvent game works:
NFT Creation and Ownership: Players acquire unique digital assets, such as characters or items, in the form of NFTs. Each NFT has an associated Power Score, which is a numerical value representing its strength in the game.
Game Events: The game organizes events where players can participate using their NFTs. These events can be battles, races, or any other form of competition where NFTs can face off against each other.
Power Score Comparison: During an event, the Power Scores of participating NFTs are compared to determine the outcome. The higher the Power Score, the more likely an NFT is to win the event.
Event Outcome: Based on the comparison of Power Scores, winners and losers are determined for each event. Winners may be rewarded with in-game prizes, increased Power Scores, or other benefits.
Power Score Adjustments: The Power Score of an NFT can change over time due to various factors such as winning or losing events, upgrades, or other game mechanics. Players can strategize to increase the Power Scores of their NFTs to improve their chances of winning future events.
Burning Mechanism: In some cases, if an NFT's Power Score falls below a certain threshold or if it loses a particular event, it might be "burned," meaning it's removed from the game permanently. This mechanic adds an element of risk and strategy to the game, as players must weigh the potential rewards against the risk of losing their NFTs.
To create PowerEvent
, we'll create an interface for the Swamp
contract, and then use that interface in a PowerEvent
contract to interact with the Swamp
contract.
Create a new interface called ISwamp
:
pragma solidity ^0.8.9;
interface ISwamp {
function burn(uint256 tokenId) external;
function burn(uint256 tokenId) external;
}
Create a new contract called PowerEvent
that interacts with the Swamp
contract through the ISwamp
interface:
pragma solidity ^0.8.9;
interface ISwamp {
function ownerOf(uint256 tokenId) external view returns (address);
function burn(uint256 tokenId) external;
function cup_title(bytes32 cup) external returns (string){
return cups[cup].title
}
}
contract PowerEvent {
ISwamp public swampContract;
mapping(uint256 => mapping(uint256 => uint256)) public eventPowerScore;
event NFTBurned(uint256 nftTokenId, address indexed owner, uint256 eventPowerScore);
constructor(address _swampContract) {
swampContract = ISwamp(_swampContract);
}
function checkPowerScore(uint256 eventId, uint256 boatId) public {
uint256 eventPowerThreshold = swampContract.eventPowerRegister[eventId][boardId];
uint256 currentPowerScore = eventPowerScore[eventId][nftTokenId];
if (currentPowerScore < eventPowerThreshold) {
_burnNFT(nftTokenId);
emit NFTBurned(nftTokenId, swampContract.ownerOf(nftTokenId), currentPowerScore);
}
}
function _burnNFT(uint256 nftTokenId) internal {
swampContract.burn(nftTokenId);
// Perform additional cleanup if necessary, e.g., remove the NFT from mappings.
}
}
In this example, the PowerEvent
contract interacts with the Swamp
contract through the ISwamp
interface. This enables the contract to call the ownerOf
and burn
functions from the Swamp
contract, without having to inherit from it directly.
Note: this example requires the Swamp
contract to be given full approval for the management of the Boat which is a separate call the user would have to make.
The Swamp introduces a break through method to conserve gas costs when driving the boat, fishing or farting. Creating leaderboards or mini-games related to the accrual of these elements have significant advantages and could be sold to members of the community looking to play more in the Swamp. Furthermore, the game can be played simply be sending Ethereum (in units of WEI) to the Swamp Contract.
The SwampBoat contract's move function reads Wei amounts sent to the contract to perform actions such as moving the boat, fishing, and farting, which saves gas costs compared to executing these actions through separate function calls.
The contract has a receive
function which is executed when Ether is sent to the contract without data. It requires that the sent Ether value (msg.value) is greater than 0. It then calculates the nftTokenId
and action using the msg.value:
action
is calculated by taking the modulo of msg.value by 10.
nftTokenId
is calculated by subtracting the action from msg.value.
The contract then checks if the given nftTokenId
exists and if the sender is either the owner of the NFT or holds the matching ERC1155 token.
Based on the action
value, the contract determines which action to perform:
If action
is between 1 and 8, the move
function is called with the nftTokenId
and the direction as arguments.
If action
is 9, the fish
function is called with the nftTokenId
as the argument.
If action
is 0, the fart
function is called with the nftTokenId
as the argument.
By encoding the action and NFT token ID within the Ether value sent to the contract, the move function can save on gas costs as it eliminates the need for separate function calls for each action. This method is efficient for simple actions that don't require additional input parameters, and it leverages the already-required Ether transfer to encode the necessary information.
Built in to the Swamp Event is a URI which adopts the standard ERC721 URI standard to add complex media, scores, and social functions to your event.
Since the URI can be changed at end time even retroactively we expect two major use cases:
Dynamic content updates: Your game can use the setEventURI
function to periodically update the URI for an event with new content, such as new levels, challenges, or game modes. This would keep the game fresh and exciting for players and encourage them to return regularly to see what's new.
Cross-game collaboration: Your game could collaborate with other Swamp games or platforms by connecting to their event URIs. This would enable players to participate in special cross-game events or challenges, with the possibility of earning unique rewards or NFTs that can be used in both games.
The EventCoordinates
struct is a data structure used to store the spatial and temporal properties of an event occurring within the SwampBoat smart contract. This struct holds the following attributes:
startBlock
: The block number at which the event begins.
endBlock
: The block number at which the event ends.
xStart
: The starting x-coordinate of the event area.
xEnd
: The ending x-coordinate of the event area.
yStart
: The starting y-coordinate of the event area.
yEnd
: The ending y-coordinate of the event area.
The EventCoordinates
struct is used to define the boundaries of an event, both in terms of time (block numbers) and space (x and y coordinates). This information is crucial for determining if a boat is within the event area during the event duration. By checking whether a boat's current x and y coordinates fall within the xStart to xEnd range and yStart to yEnd range, it's possible to verify its presence within the event area.
Boats move through the swamp by utilizing functions such as eatMushroom
. This function assigns new random x and y coordinates to the boat within the defined grid size. The _randomPosition
function is used to generate a random number within the grid size using the boat's tokenId and the current block timestamp as input parameters. The movement is not directly related to the EventCoordinates struct, but it affects the boat's position, which is then checked against the event boundaries to determine if it is participating in an event.
For more information follow the Twitter @overlinenetwork.