View as Markdown

Auctions

Read more about the Auctions system in Hiro here .

Initializing the auctions system #

The auctions system relies on the Nakama System and an ILogger, both must be passed in as dependencies via the constructor.

1
2
var auctionsSystem = new AuctionsSystem(logger, nakamaSystem);
systems.Add(auctionsSystem);

Subscribing to changes in the auctions system #

You can listen for changes in the auctions system so that you can respond appropriately, such as updating the UI, by implementing the IObserver pattern, or use the SystemObserver<T> type which handles it for you.

1
2
3
4
5
var disposer = SystemObserver<AuctionsSystem>.Create(auctionsSystem, system => {
    Instance.Logger.Info($"System updated.");

    // Update UI elements etc as necessary here...
});

Refreshing the auctions system #

To ensure the auctions system has the latest information from Nakama you can refresh it.

1
await auctionsSystem.RefreshAsync();

Creating a New Auction #

To create a new auction, use the CreateAsync function.

1
2
3
4
5
6
var itemInstanceIds = new List<string> { "item_instance_001", "item_instance_002" };
string auctionId = "template_auction_001";
string conditionId = "condition_001";

var auction = await auctionsSystem.CreateAsync(auctionId, conditionId, itemInstanceIds);
Debug.Log($"Auction created with ID: {auction.Id}, Start Time: {auction.StartTimeSecDecoded}");

Restricting an auction to specific players #

CreateAsync also accepts an optional allowedUserIds parameter. When you pass a non-empty list of player IDs, the auction is only visible to and biddable by those players, letting you build restricted auctions such as guild sales, friends-only listings, or one-to-one trades on top of the auction system.

1
2
3
4
5
6
7
8
var itemInstanceIds = new List<string> { "item_instance_001", "item_instance_002" };
string auctionId = "template_auction_001";
string conditionId = "condition_001";
var allowedUserIds = new List<string> { "friend_user_id_001" };

var auction = await auctionsSystem.CreateAsync(auctionId, conditionId, itemInstanceIds,
    allowedUserIds: allowedUserIds);
Debug.Log($"Directed auction created with ID: {auction.Id}, allowed users: {string.Join(",", auction.AllowedUserIds)}");

The resulting Auction object exposes the whitelist back to you as Auction.AllowedUserIds, and an Auction.ImmediateBuyout flag that tells you whether a bid meeting the buyout price will immediately complete the auction. This flag is copied from the AuctionTemplateCondition.ImmediateBuyout setting on the auction template used to create it.

Placing a Bid on an Auction #

You can place a bid on an auction using the BidAsync function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
var currencies = new Dictionary<string, long>
{
    { "gold", 1000 }
};

string auctionId = "auction_instance_123";
string version = "1.0";

var auction = await auctionsSystem.BidAsync(auctionId, version, currencies);
Debug.Log($"Bid placed on auction {auction.Id}. Current bid: {auction.BidDecoded}");

Bidding with items #

BidAsync also accepts an optional bidInstanceIds parameter, a list of inventory item instance IDs the bidder escrows as part of the bid. currencies is now optional too, so you can bid with items alone, currency alone, or a combination of both. This is what powers item-for-item trades between players on directed auctions.

1
2
3
4
5
6
string auctionId = "auction_instance_123";
string version = "1.0";
var bidInstanceIds = new List<string> { "item_instance_010" };

var auction = await auctionsSystem.BidAsync(auctionId, version, bidInstanceIds: bidInstanceIds);
Debug.Log($"Item bid placed on auction {auction.Id}. Current bid: {auction.BidDecoded}");

The same currencies and bidInstanceIds parameters are available on the socket variant of BidAsync(ISocket socket, ...).

Canceling an Auction #

If an auction needs to be canceled before it ends, the CancelAsync method can be used.

1
2
3
4
string auctionId = "auction_instance_123";

var canceledAuction = await auctionsSystem.CancelAsync(auctionId);
Debug.Log($"Auction {canceledAuction.Auction.Id} has been canceled.");

Claiming a Winning Bid #

Once an auction has ended, the winning bidder can claim their item using ClaimBidAsync.

1
2
3
4
string auctionId = "auction_instance_123";

var claimBid = await auctionsSystem.ClaimBidAsync(auctionId);
Debug.Log($"Claimed item from auction {claimBid.Auction.Id}. Winning bid: {claimBid.BidAmount}");

Claiming a created auction #

Once an auction has ended, the seller can claim its outcome using ClaimCreatedAsync.

1
2
3
4
string auctionId = "auction_instance_123";

var claimCreated = await auctionsSystem.ClaimCreatedAsync(auctionId);
Debug.Log($"Claimed created auction {claimCreated.Auction.Id}.");

If the winning bidder escrowed items instead of, or alongside, currency, those items are returned to the seller through AuctionClaimCreated.ReceivedItems when the auction completes successfully. AuctionClaimCreated.ReturnedItems still holds the seller’s own listed items if the auction failed instead.

Listing Available Auctions #

You can list the currently available auctions using the ListAsync function.

1
2
3
4
5
6
7
8
9
string query = "active";
var sortCriteria = new List<string> { "end_time" };
int limit = 10;

var auctionList = await auctionsSystem.ListAsync(query, sortCriteria, limit);
foreach (var auction in auctionList.Auctions)
{
    Debug.Log($"Auction ID: {auction.Id}, Current Bid: {auction.BidDecoded}");
}

Listing auctions directed at you #

ListAsync also accepts an optional allowedOnly parameter. When true, the results only include directed auctions where you’re on the allowedUserIds whitelist. When false or omitted, the results only include public auctions instead, so the two sets never overlap: call ListAsync twice, once with allowedOnly: true and once without it, if you need both directed and public auctions.

1
2
3
4
5
6
7
8
9
string query = "active";
var sortCriteria = new List<string> { "end_time" };
int limit = 10;

var directedAuctions = await auctionsSystem.ListAsync(query, sortCriteria, limit, allowedOnly: true);
foreach (var auction in directedAuctions.Auctions)
{
    Debug.Log($"Directed auction ID: {auction.Id}, Current Bid: {auction.BidDecoded}");
}

This maps to the AuctionListRequest.AllowedOnly field sent to the server.