Skip to main content

Unity SDK

Build Web3 games with Unity - no blockchain knowledge required.

SDK Not Yet Released

The Unity SDK is currently under development and has not been released yet. The Vidya SDK package is not available on the Unity Asset Store at this time. This documentation serves as a specification and preview of the upcoming SDK. Stay tuned for the official release!

Installation

  1. Download the latest Vidya SDK package from the Unity Asset Store
  2. Import the package into your Unity project
  3. Configure your project ID in the Vidya Settings window

Getting Started

Setup & Authentication

using Vidya.SDK;
using UnityEngine;

public class GameManager : MonoBehaviour
{
private VidyaSDK vidya;
private Player player;

async void Start()
{
// Initialize with your project ID
vidya = new VidyaSDK(new VidyaConfig
{
ProjectId = "your-project-id", // Get from dashboard.vidya.game
Environment = Environment.Production // Production | Testnet | Local
});

// Authenticate player (creates a session)
var session = await vidya.Auth.Login(new LoginOptions
{
Provider = AuthProvider.Google // Google | Discord | Email | Apple
});

// Get the authenticated player object from the session
player = Player.FromSession(session);

// Now use the player object throughout your game
var items = await vidya.Inventory.GetItems(player);
}
}

Core Configuration

var vidya = new VidyaSDK(new VidyaConfig
{
ProjectId = "your-project-id", // Required: Your Vidya project ID
Environment = Environment.Production, // Required: Production | Testnet | Local

// Optional: Advanced configuration
Chain = "polygon", // Default: "polygon"
SponsorGas = true, // Default: true - Users don't pay gas

// Optional: Custom contract addresses (rarely needed)
Contracts = new ContractConfig
{
Inventory = "0x...",
Marketplace = "0x...",
Fabricator = "0x..."
}
});

The Player Object

The Vidya SDK uses a Player object to represent users throughout the system. This provides type safety and clear permission management.

Creating Player Objects

There are only two ways to create a Player object:

1. Authenticated Player (Full Access)

// After authentication, create player from session
var player = Player.FromSession(session);

// This player can read and write
Debug.Log(player.CanWrite); // true

2. Read-Only Player (View Only)

// Create a read-only player from a wallet address
var readOnlyPlayer = Player.FromWallet("0x742d35Cc6634C0532925a3b844Bc9e7595f5b123");

// This player can only read data
Debug.Log(readOnlyPlayer.CanWrite); // false
Debug.Log(readOnlyPlayer.IsReadOnly); // true

Finding Players

When you need to interact with other players, use the lookup methods:

// Find player by username
var otherPlayer = await vidya.Player.FindByUsername("CoolGamer123");

// Find player by wallet address
var walletPlayer = await vidya.Player.FindByWallet("0x742d35Cc6634C0532925a3b844Bc9e7595f5b123");

// Find player by ENS name
var ensPlayer = await vidya.Player.FindByEns("coolplayer.eth");

// Find multiple players at once
var players = await vidya.Player.FindMultiple(new FindPlayersOptions
{
Usernames = new[] { "Player1", "Player2" },
Wallets = new[] { "0x123...", "0x456..." }
});

Authentication

Login Methods

// Social login (recommended)
var session = await vidya.Auth.Login(new LoginOptions
{
Provider = AuthProvider.Google // Google | Discord | Email | Apple
});

// Email/password authentication
var session = await vidya.Auth.Login(new LoginOptions
{
Provider = AuthProvider.Email,
Email = "player@example.com",
Password = "secure-password"
});

// Guest mode (instant play)
var session = await vidya.Auth.LoginAsGuest();

// After login, always create the player object from session
var player = Player.FromSession(session);

Session Management

// Check authentication status
if (vidya.Auth.IsAuthenticated)
{
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var profile = await vidya.Auth.GetProfile();
Debug.Log($"Welcome back, {profile.Username}!");
}

// Listen to auth events
vidya.Auth.OnLogin += (session) =>
{
var player = Player.FromSession(session);
Debug.Log($"Player logged in: {player.PlayerId}");
};

vidya.Auth.OnLogout += () =>
{
Debug.Log("Player logged out");
};

// Logout
await vidya.Auth.Logout();

Core Systems

Inventory System

All inventory operations use Player objects:

// Get current player's inventory
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var items = await vidya.Inventory.GetItems(player);

// Get another player's inventory (read-only)
var otherPlayer = await vidya.Player.FindByUsername("FriendName");
var friendItems = await vidya.Inventory.GetItems(otherPlayer);

// Get a specific item by ID
var sword = await vidya.Inventory.GetItem(player, "sword-001");

// Get a specific item by predicate
var legendaryWeapon = await vidya.Inventory.GetItem(player,
item => item.Name == "Legendary Sword" && !item.Equipped
);

// Find all consumables
var consumables = await vidya.Inventory.FindItems(player,
item => item.Slot == ItemSlot.Consumable
);

// Transfer an item using the item's method
var recipient = await vidya.Player.FindByWallet("0x456...");
if (sword != null)
{
await sword.Transfer(recipient, 1);
}

// Batch transfer (still on inventory module)
var potion = await vidya.Inventory.GetItem(player, item => item.Name == "Health Potion");
await vidya.Inventory.TransferBatch(new TransferBatchOptions
{
To = recipient,
Items = new[]
{
new TransferItem { Item = sword, Quantity = 1 },
new TransferItem { Item = potion, Quantity = 5 }
}
});

// Equipment management using item methods
var weapon = await vidya.Inventory.GetItem(player, item =>
item.Slot == ItemSlot.Weapon && !item.Equipped
);
if (weapon != null)
{
await weapon.Equip();
// Later...
await weapon.Unequip();
}

// Consume an item
var healthPotion = await vidya.Inventory.GetMyItem(item =>
item.Name == "Health Potion" && item.Quantity > 0
);
if (healthPotion != null)
{
await healthPotion.Consume(1);
}

// List an item on marketplace
var rareItem = await vidya.Inventory.GetMyItem("rare-sword-001");
if (rareItem != null)
{
var listing = await rareItem.List(50, 1, 7); // price, quantity, duration
}

// Get equipped items
var equipped = await vidya.Inventory.GetEquippedItems(player);

Marketplace System

// Browse marketplace
var listings = await vidya.Marketplace.GetListings(new MarketplaceFilter
{
Category = "weapons",
MinPrice = 10,
MaxPrice = 100,
Sort = SortOrder.PriceAsc,
Limit = 20
});

// Filter by specific seller
var seller = await vidya.Player.FindByUsername("MerchantKing");
var sellerListings = await vidya.Marketplace.GetListings(new MarketplaceFilter
{
Seller = seller,
Category = "rare-items"
});

// Buy items (requires authentication)
var listings = await vidya.Marketplace.GetListings();
var swordListing = listings.FirstOrDefault(l => l.Item.Name == "Rare Sword");

var purchase = await vidya.Marketplace.BuyItem(new BuyItemOptions
{
Listing = swordListing,
Quantity = 2
});

// Create listing using item method
var itemToSell = await vidya.Inventory.GetMyItem(item =>
item.Name == "Rare Sword" && item.Tradeable && !item.Equipped
);

if (itemToSell != null)
{
var listing = await itemToSell.List(50, 1, 7); // price, quantity, duration
}

// Or use marketplace module directly
var listing = await vidya.Marketplace.CreateListing(new CreateListingOptions
{
Item = itemToSell,
Price = 50, // USD
Quantity = 1,
Duration = 7 // Days
});

// Get player stats
var myStats = await vidya.Marketplace.GetStats(player);

Crafting System

// Get craftable recipes for current player
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var recipes = await vidya.Crafting.GetCraftableRecipes(player);

// Get available recipes
var recipes = await vidya.Crafting.GetCraftableRecipes(player);
var swordRecipe = recipes.FirstOrDefault(r => r.Name == "Epic Sword");

// Check requirements
var canCraft = await vidya.Crafting.CheckRequirements(player, swordRecipe);
if (!canCraft.Success)
{
// Get missing items
foreach (var missing in canCraft.Missing)
{
Debug.Log($"Need {missing.Required - missing.Have} more {missing.Item.Name}");
}
}

// Check if you have materials using item methods
var ironOre = await vidya.Inventory.GetMyItem("iron-ore-001");
if (ironOre != null && ironOre.CanCraftWith(swordRecipe))
{
Debug.Log("You have iron ore for this recipe!");
}

// Craft item
var result = await vidya.Crafting.CraftItem(new CraftOptions
{
Player = player,
Recipe = swordRecipe
});

// Batch crafting
var potionRecipe = recipes.FirstOrDefault(r => r.Name == "Health Potion");
var manaRecipe = recipes.FirstOrDefault(r => r.Name == "Mana Potion");

var results = await vidya.Crafting.CraftBatch(player, new[]
{
new BatchCraftItem { Recipe = potionRecipe, Quantity = 10 },
new BatchCraftItem { Recipe = manaRecipe, Quantity = 5 }
});

// Get crafting history
var history = await vidya.Crafting.GetHistory(player);

Gacha System

// Get available gacha boxes
var boxes = await vidya.Gacha.GetBoxes();
var premiumBox = boxes.FirstOrDefault(box => box.Name == "Premium Box");

// Open loot box
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var reward = await vidya.Gacha.OpenBox(new OpenBoxOptions
{
Player = player,
Box = premiumBox
});

// Multi-pull
var rewards = await vidya.Gacha.OpenMultiple(new OpenMultipleOptions
{
Player = player,
Box = premiumBox,
Count = 10
});

// Check pity status
var pity = await vidya.Gacha.GetPityStatus(player, premiumBox);
Debug.Log($"{pity.CurrentCount}/{pity.Guaranteed} until guaranteed rare");

Leaderboards

// Submit score
await vidya.Leaderboard.SubmitScore(new SubmitScoreOptions
{
LeaderboardId = "weekly-score",
Score = 15000,
Metadata = new Dictionary<string, object>
{
{ "level", 45 },
{ "character", "warrior" }
}
});

// Get leaderboard
var leaderboard = await vidya.Leaderboard.GetLeaderboard("weekly-score", new LeaderboardOptions
{
Type = LeaderboardType.Weekly,
Limit = 100
});

// Get player rank
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var rank = await vidya.Leaderboard.GetPlayerRank("weekly-score", player);
Debug.Log($"Rank: {rank.Rank} of {rank.TotalPlayers}");

// Friends leaderboard
var friendsScores = await vidya.Leaderboard.GetFriendsLeaderboard("weekly-score");

// Nearby players
var nearby = await vidya.Leaderboard.GetNearbyPlayers("weekly-score", player, 5);

Social System

// Get social profile
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var profile = await vidya.Social.GetProfile(player);

// Send friend request
var newFriend = await vidya.Player.FindByUsername("CoolPlayer");
await vidya.Social.SendFriendRequest(newFriend, "Let's team up!");

// Accept friend request
var pendingRequests = await vidya.Social.GetPendingFriendRequests();
if (pendingRequests.Any())
{
await vidya.Social.AcceptFriendRequest(pendingRequests[0].From);
}

// Create guild
var guild = await vidya.Social.CreateGuild(new CreateGuildOptions
{
Name = "Elite Warriors",
Tag = "ELITE",
Description = "Top players only",
MaxMembers = 100
});

// Invite to guild
var member = await vidya.Player.FindByWallet("0x789...");
await vidya.Social.InviteToGuild(guild.Id, member);

AI NPCs

// Spawn NPC
var npc = await vidya.NPC.SpawnNPC(new SpawnNPCOptions
{
DefinitionId = "merchant-001",
Location = new Vector3(100, 0, 50)
});

// Interact with NPC
var dialogue = await vidya.NPC.Interact(new InteractOptions
{
NpcId = npc.Definition.Id,
Action = "talk"
});

// Trade with NPC
var wolfPelt = await vidya.Inventory.GetMyItem(item =>
item.Name == "Wolf Pelt" && item.Quantity >= 10
);
var healthPotion = npc.Inventory.FirstOrDefault(item => item.Name == "Health Potion");

if (wolfPelt != null && healthPotion != null)
{
var tradeResult = await vidya.NPC.Trade(new TradeOptions
{
Npc = npc,
Buying = new[] { new TradeItem { Item = healthPotion, Quantity = 5 } },
Selling = new[] { new TradeItem { Item = wolfPelt, Quantity = 10 } }
});
}

// Give gift to improve relationship
var rareGem = await vidya.Inventory.GetMyItem("rare-gem-001");
if (rareGem != null)
{
await vidya.NPC.GiveGift(npc, rareGem, 1);
}

// Check relationship
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var relationship = await vidya.NPC.GetRelationship(npc.Definition.Id, player);

Currency System

// Get balances
var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var balances = await vidya.Currency.GetBalances(player);

// Transfer currency to another player
var recipient = await vidya.Player.FindByUsername("TeamMate");
await vidya.Currency.Transfer(new TransferOptions
{
From = player,
To = recipient,
Currency = "gold",
Amount = 100
});

// Grant rewards (requires permissions)
await vidya.Currency.Grant(player, new CurrencyAmount
{
Gold = 500,
Gems = 10
});

// Spend currency
await vidya.Currency.Spend(player, new SpendOptions
{
Currency = "gems",
Amount = 20,
Reason = "speed-boost-purchase"
});

Advanced Features

Batch Operations

Execute multiple operations efficiently:

var session = vidya.Auth.GetSession();
var player = Player.FromSession(session);
var friend = await vidya.Player.FindByWallet("0x456...");

// Create batch
var batch = vidya.CreateBatch();

// Use the new GetItem method
var sword = await vidya.Inventory.GetMyItem(item =>
item.Name == "Legendary Sword" && item.Tradeable
);

if (sword != null)
{
// Use item method for transfer
batch.Add(sword.Transfer(friend, 1));
}

batch.Add(vidya.Currency.Transfer(new TransferOptions
{
From = player,
To = friend,
Currency = "gold",
Amount = 1000
}));

// Execute all at once
var results = await batch.Execute();

Error Handling

try
{
var listings = await vidya.Marketplace.GetListings();
var listing = listings[0];
await vidya.Marketplace.BuyItem(new BuyItemOptions { Listing = listing, Quantity = 1 });
}
catch (VidyaException ex) when (ex.Code == ErrorCode.InsufficientBalance)
{
Debug.LogError(ex.Message);
}
catch (VidyaException ex) when (ex.Code == ErrorCode.PlayerNotAuthenticated)
{
await vidya.Auth.Login(new LoginOptions { Provider = AuthProvider.Google });
}
catch (VidyaException ex) when (ex.Code == ErrorCode.ReadOnlyPlayer)
{
Debug.Log("Please sign in to perform this action");
}
catch (Exception ex)
{
Debug.LogError($"Unexpected error: {ex.Message}");
}

Event System

// Module events
vidya.Inventory.OnItemReceived += (e) =>
{
Debug.Log($"{e.Player.PlayerId} received {e.Item.Name}");
};

vidya.Marketplace.OnItemPurchased += (e) =>
{
Debug.Log($"Purchase complete: {e.Listing.Item.Name}");
};

// Global events
vidya.OnTransaction += (tx) =>
{
Debug.Log($"Transaction {tx.Id}: {tx.Status}");
};

Complete Example

using Vidya.SDK;
using UnityEngine;
using System.Threading.Tasks;
using System.Linq;

public class GameClient : MonoBehaviour
{
private VidyaSDK vidya;
private Player player;

async void Start()
{
await Initialize();
}

private async Task Initialize()
{
// Initialize SDK
vidya = new VidyaSDK(new VidyaConfig
{
ProjectId = "your-project-id",
Environment = Environment.Production
});

// Authenticate
var session = await vidya.Auth.Login(new LoginOptions { Provider = AuthProvider.Discord });
player = Player.FromSession(session);

// Setup event listeners
SetupEventListeners();
}

public async Task SendGiftToFriend(string friendUsername, string itemName)
{
// Find friend
var friend = await vidya.Player.FindByUsername(friendUsername);

// Find item using predicate
var item = await vidya.Inventory.GetMyItem(
i => i.Name == itemName && i.Tradeable && i.Quantity > 0
);

if (item == null)
{
throw new System.Exception($"Tradeable item '{itemName}' not found in inventory");
}

// Transfer using item method
await item.Transfer(friend, 1);

// Send friend request if not already friends
var friends = await vidya.Social.GetFriends();
var isFriend = friends.Any(f => f.Player.PlayerId == friend.PlayerId);

if (!isFriend)
{
await vidya.Social.SendFriendRequest(friend, "Thanks for playing!");
}
}

public async Task ParticipateInGuildEvent(string guildId)
{
// Contribute to guild
await vidya.Social.ContributeToGuild(guildId, new GuildContribution
{
Currency = "gold",
Amount = 100
});

// Update leaderboard
await vidya.Leaderboard.SubmitScore(new SubmitScoreOptions
{
LeaderboardId = "guild-contribution",
Score = 100,
Metadata = new Dictionary<string, object> { { "guildId", guildId } }
});
}

private void SetupEventListeners()
{
vidya.Inventory.OnItemReceived += (e) =>
{
if (e.Player.PlayerId == player.PlayerId)
{
ShowNotification($"Received {e.Item.Name}!");
}
};

vidya.Social.OnFriendRequestReceived += (e) =>
{
ShowNotification($"Friend request from {e.From.PlayerId}");
};
}

private void ShowNotification(string message)
{
Debug.Log($"[Notification] {message}");
// Show UI notification
}
}

API Reference

For detailed API documentation, see the SDK documentation.

Unity-Specific Features

Prefabs and UI

The SDK includes ready-to-use prefabs:

  • Authentication Panel (social logins)
  • Inventory Display Grid
  • Marketplace Browser
  • Crafting Station UI
  • Leaderboard Display
  • Social/Friends List
  • NPC Interaction Dialog

Coroutine Support

All async operations work with Unity coroutines:

IEnumerator LoadInventory()
{
var task = vidya.Inventory.GetItems(player);
yield return new WaitUntil(() => task.IsCompleted);

if (task.IsCompletedSuccessfully)
{
var items = task.Result;
// Update UI
}
}

Mobile Optimization

// Configure for mobile
vidya.ConfigureMobile(new MobileConfig
{
AutoManageSession = true,
BiometricAuth = true,
LowBandwidthMode = true
});

C# Support

The SDK is written in C# and provides full IntelliSense support. Your IDE will provide intelligent code completion and type checking for all SDK methods.

using Vidya.SDK;
using Vidya.SDK.Types;

// All types are available for your use
void ProcessItem(Item item)
{
Debug.Log($"{item.Name}: {item.Quantity}x");
}

// Type-safe event handling
vidya.Inventory.OnItemReceived += (ItemReceivedEvent e) =>
{
ProcessItem(e.Item);
};