InventoryFramework.GodotAdapter
1.0.8
dotnet add package InventoryFramework.GodotAdapter --version 1.0.8
NuGet\Install-Package InventoryFramework.GodotAdapter -Version 1.0.8
<PackageReference Include="InventoryFramework.GodotAdapter" Version="1.0.8" />
<PackageVersion Include="InventoryFramework.GodotAdapter" Version="1.0.8" />
<PackageReference Include="InventoryFramework.GodotAdapter" />
paket add InventoryFramework.GodotAdapter --version 1.0.8
#r "nuget: InventoryFramework.GodotAdapter, 1.0.8"
#:package InventoryFramework.GodotAdapter@1.0.8
#addin nuget:?package=InventoryFramework.GodotAdapter&version=1.0.8
#tool nuget:?package=InventoryFramework.GodotAdapter&version=1.0.8
InventoryFramework.GodotAdapter
Godot 4 integration for InventoryFramework: a server-authoritative inventory and crafting backend. Wraps the gRPC SDK in a Node-friendly facade.
Requirements
- Godot 4.x with .NET enabled
- A running InventoryFramework server
Installation
dotnet add package InventoryFramework.GodotAdapter
Or copy the DLLs from dist/godot/ into res://addons/InventoryFramework/.
Autoload setup
Create a script and register it as an Autoload in Project > Project Settings > Autoload:
using Godot;
using InventoryFramework.GodotAdapter.Models;
using InventoryFramework.GodotAdapter.Services;
public partial class InventoryManager : Node
{
public GodotInventoryFacade Facade { get; private set; }
public override async void _Ready()
{
Facade = new GodotInventoryFacade(new GodotInventoryConfiguration
{
ServerAddress = "https://your-server:7289",
ActorId = OS.GetUniqueId(),
ApiKey = "sk-game-your-key"
});
var result = await Facade.ConnectAsync();
if (!result.Succeeded)
{
GD.PrintErr($"Connect failed: {result.ErrorMessage}");
return;
}
await Facade.CreateDefaultInventoryAsync();
await Facade.RefreshAsync();
}
protected override void Dispose(bool disposing)
{
Facade?.Dispose();
base.Dispose(disposing);
}
}
Reading inventory state
var manager = GetNode<InventoryManager>("/root/InventoryManager");
var snapshot = manager.Facade.CurrentSnapshot; // last fetched, no network call
// or: var snapshot = await manager.Facade.RefreshAsync();
foreach (var container in snapshot.Containers)
{
GD.Print($"Container: {container.ContainerId}");
foreach (var slot in container.Slots.Where(s => !s.IsEmpty))
{
GD.Print($" {slot.ItemDefinitionId} x{slot.Quantity}");
foreach (var affix in slot.Affixes)
GD.Print($" {affix.AffixDefinitionId}: {affix.Value}");
}
}
Item operations
var facade = GetNode<InventoryManager>("/root/InventoryManager").Facade;
// Grant items (admin)
await facade.GrantItemsAsync(containerId, "wood", quantity: 10);
// Transfer a slot between containers
await facade.TransferItemsAsync(sourceContainerId, slotIndex: 0, targetContainerId, quantity: 5);
// One-button quick-store (backpack to chest, skips locked slots)
await facade.QuickStoreToTargetContainerAsync(sourceContainerId, targetContainerId);
// Lock a slot; protected from quick-store and auto-sort. Manual moves still work.
await facade.LockSlotAsync(containerId, slotIndex: 2, lockSlot: true);
// Split a stack into two slots
var split = await facade.SplitStackAsync(containerId, sourceSlotIndex: 0, amount: 5);
GD.Print($"Split landed in slot {split.DestinationSlotIndex}");
// Drop items; returns item id and quantity to spawn a world pickup
var drop = await facade.DropItemsAsync(containerId, slotIndex: 0, amount: 3);
if (drop.Succeeded) SpawnPickupNode(drop.DroppedItemDefinitionId, drop.DroppedQuantity);
// Sort all unlocked slots
// sortMode: 0 = ByNameAscending, 1 = ByWeightDescending, 2 = ByTagThenName
await facade.SortContainerAsync(containerId, sortMode: 0);
Item affixes (per-instance modifiers)
Affixes are rolled modifiers on individual item stacks: fire damage, crit chance, move speed, etc. Define them in Data/Affixes/affixes.json on the server:
// Grant a sword with specific affix values (admin)
await facade.GrantItemsAsync(containerId, "sword", quantity: 1, affixes: new[]
{
new ItemAffixRequest { AffixDefinitionId = "fire_damage", Value = 38.5f },
new ItemAffixRequest { AffixDefinitionId = "crit_chance", Value = 12.0f }
});
// Affixes are included in every snapshot
var snapshot = await facade.RefreshAsync();
foreach (var slot in snapshot.Containers[0].Slots.Where(s => !s.IsEmpty))
foreach (var affix in slot.Affixes)
GD.Print($"{slot.ItemDefinitionId} | {affix.AffixDefinitionId}: {affix.Value}");
Crafting
// Preview before committing
var preview = await facade.PreviewCraftItemsAsync(
"plank_recipe", sourceContainerId, targetContainerId,
count: 2, station: "workbench");
GD.Print($"Can craft: {preview.CanCraftRequestedCount} Max: {preview.MaxCraftableCount}");
if (preview.CanCraftRequestedCount)
await facade.CraftItemsAsync(
"plank_recipe", sourceContainerId, targetContainerId,
count: 2, allowPartial: false, station: "workbench");
// List available recipes for current inventory
var available = await facade.GetAvailableRecipesAsync(sourceContainerId);
foreach (var recipe in available.Recipes)
GD.Print($"{recipe.DisplayName} ({recipe.CraftingCategory})");
Player progression
await facade.UnlockRecipeKeyAsync("tier2_weapons");
var progression = await facade.GetPlayerProgressionAsync();
foreach (var key in progression.UnlockedKeys)
GD.Print($"Unlocked: {key}");
Session controller
For UI screens that need live state and connection tracking:
var controller = new GodotInventorySessionController(facade);
await controller.StartSessionAsync();
// controller.State.Snapshot = current inventory
// controller.State.IsConnected = connection status
// controller.State.ErrorMessage = last error if any
Error handling
Every operation returns a result with Succeeded and ErrorMessage:
var result = await facade.TransferItemsAsync(sourceId, slotIndex: 0, targetId, quantity: 5);
if (!result.Succeeded)
GD.PrintErr($"Transfer failed: {result.ErrorMessage}");
Full documentation: Godot Integration Guide
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.1 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.1
- InventoryFramework.SDK (>= 1.0.8)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.