Hoe maak je een spelinventarissysteem waar spelers plezier aan beleven?
Een betrouwbaar inventarissysteem voor games geeft spelers duidelijke controle over wat ze verzamelen, dragen, uitrusten en gebruiken. Bouw het systeem in lagen op: definieer regels voor items en capaciteit, houd itemgegevens gescheiden van de stapels die de speler bezit, laat elke inventarisactie via één gevalideerd model lopen, verbind de interface met dat model en sla alleen de gegevens op die nodig zijn om de status van een speler te herstellen. Deze aanpak werkt in Unity, Godot en andere game-engines.
Het doel is niet om voorraadbeheer ingewikkeld te maken. Een goed voorraadsysteem maakt nuttige keuzes gemakkelijk te begrijpen: spelers kunnen zien wat een voorwerp doet, weten waarom een voorwerp niet past en voorwerpen verplaatsen of gebruiken zonder met de besturing te hoeven worstelen.
1. Bepaal wat de inventaris moet doen.
Schrijf de regels op voordat je het raster bouwt. Het juiste ontwerp hangt af van je spel: een survivalspel gebruikt mogelijk gewicht en beperkte ruimte, terwijl een klassieke RPG een ruime lijst met categorieën kan gebruiken.
- Capaciteit: Kies een vast aantal vakken, een gewichtslimiet of beide. Definieer wat er gebeurt als een pick-up de capaciteit overschrijdt.
- Stapelen: Stel een maximale stapelgrootte in voor elk item. Bepaal of items met verschillende duurzaamheid, modificaties of eigendom kunnen worden samengevoegd.
- Gedrag van items: Verbruiksartikelen, uitrusting, quest-objecten, knutselmaterialen en valuta worden apart behandeld, omdat de regels hiervoor verschillen.
- Speleracties: Geef een lijst van de acties die je bij de start nodig hebt: oppakken, verplaatsen, splitsen, samenvoegen, uitrusten, gebruiken, laten vallen, verkopen of sorteren.
- Doelapparaten: Plan de invoer en lay-out voor muis, controller, touchscreen of de combinatie die je game ondersteunt.
Houd de eerste versie klein. Een bruikbaar prototype kan beginnen met een korte itemcatalogus, een vast aantal slots, stapelen en een duidelijke reactie bij een volle inventaris. Voeg gewicht, handel, duurzaamheid of crafting pas toe wanneer het spel die systemen nodig heeft.
2. Scheid artikeldefinities van eigendomsde artikelen.
Kopieer niet alle iteminformatie naar elk spelersslot. Sla gedeelde ontwerpgegevens één keer op en laat elk inventarisitem er vervolgens naar verwijzen met een vaste ID.
| Gegevens | Typische velden | Doel |
| Artikeldefinitie | ID, weergavenaam, pictogram, categorie, maximale stapelgrootte, basisstatistieken | Beschrijft wat het voorwerp in het spel is. |
| Item stapel | Definitie-ID, aantal | Houdt bij hoeveel exemplaren van een stapelbaar voorwerp een speler bezit. |
| Unieke item-instantie | Instantie-ID, definitie-ID, duurzaamheid, gegenereerde statistieken | Slaat eigenschappen op die verschillen per wapen of uitrusting. |
| Inventarisvak | Slotindex en een lege of bezette toestand | Geeft aan waar het item verschijnt en ondersteunt regels voor vaste slots. |
Gebruik een array of lijst wanneer de volgorde van items in de slots belangrijk is. Een dictionary met item-ID's als sleutels kan het opzoeken of tellen versnellen, maar vervangt de geordende verzameling van items in de slots niet wanneer spelers items tussen specifieke slots kunnen verplaatsen. Behoud de opzoekstructuur alleen als profilering of de spellogica dit vereist.
In Unity kunnen ScriptableObject-assets gedeelde itemdefinities bevatten. Unity-documenten geven aan dat geïmplementeerde builds gegevens uit die assets kunnen gebruiken, maar ScriptableObjects zijn geen mechanisme om runtime-wijzigingen van de speler op te slaan. Houd in Godot de door de maker gemaakte definities en de veranderende inventarisstatus van de speler ook als aparte zaken.
3. Voer inventarisacties op één centrale plek uit.
Maak een inventarismodel met een kleine openbare API, zoals try_add, try_move, try_split, try_use, en try_equip. De gebruikersinterface moet een actie vereisen; het mag niet direct hoeveelheden of inhoud van vakken wijzigen. Dit voorkomt dat gameplay, opgeslagen spelvoortgang en interface-updates conflicterende regels ontwikkelen.
Beheer stapelen en overloop.
Wanneer een item wordt toegevoegd, vul dan eerst de bestaande stapels die daarmee compatibel zijn, en plaats de rest vervolgens in lege vakjes. Retourneer eventuele overgebleven items zodat de beller een volle inventaris kan melden of de niet-opgehaalde items in de wereld kan achterlaten.
function try_add(item_id, amount):
if amount <= 0 or item_id is unknown:
return amount
remaining = amount
definition = item_catalog[item_id]
if definition.max_stack > 1:
for slot in slots:
if slot holds a compatible stack of item_id:
moved = min(remaining, definition.max_stack - slot.quantity)
slot.quantity += moved
remaining -= moved
if remaining == 0:
notify_inventory_changed()
return 0
for slot in slots:
if slot is empty:
moved = min(remaining, definition.max_stack)
slot = make_stack_or_item_instance(item_id, moved)
remaining -= moved
if remaining == 0:
break
notify_inventory_changed()
return remaining
Dit is pseudocode, geen code die direct in een game-engine gebruikt kan worden: pas de verzameling, signalen en het aanmaken van item-instanties aan je eigen engine aan. Voor uitrusting met unieke duurzaamheid of statistieken, maak aparte instanties aan en voeg deze niet samen, tenzij de game expliciet definieert hoe die eigenschappen gecombineerd worden.
Maak je zetten voorspelbaar.
Controleer vóór het verplaatsen, samenvoegen of wisselen of beide slotindexen bestaan en of de bestemming het item accepteert. Weiger ongeldige acties zonder de inventaris te wijzigen. Verplaats bij een gedeeltelijke samenvoeging alleen de beschikbare hoeveelheid en laat de rest op de oorspronkelijke plaats staan. Werk het model bij zodra de bewerking is geslaagd en breng de gebruikersinterface hiervan op de hoogte.
4. Ontwikkel een inventaris-UI die is gebaseerd op de beslissingen van de speler.
Een raster is bekend, maar nuttige feedback is belangrijker dan decoratie. Elk vakje moet een pictogram, een leesbare hoeveelheid voor stapels en een duidelijke status (geselecteerd of niet beschikbaar) weergeven. Een detailvenster kan de itemnaam, beschrijving, relevante statistieken en beschikbare acties tonen.
- Gebruik categoriefilters of tabbladen wanneer de collectie moeilijk te overzien is.
- Leg uit waarom een bepaalde handeling niet kan plaatsvinden, bijvoorbeeld met de melding "Niet genoeg ruimte" of "Dit item kan hier niet worden geplaatst".
- Ondersteuning voor controllerfocus en toetsenbordnavigatie naast muisinvoer waar relevant.
- Maak slepen en neerzetten optioneel als gebruikers met touchscreen of controller een eenvoudigere selectie- en bevestigingsmethode nodig hebben.
- Gebruik ingetogen animatie en geluid om het oppakken van voertuigen, samenvoegingen en het wisselen van materieel te bevestigen zonder herhaalde acties te vertragen.
Koppel zichtbare slots aan het inventarismodel en vernieuw de betreffende rijen wanneer de gegevens wijzigen. Het huidige ListView-voorbeeld van Unity's UI Toolkit laat zien hoe lijstgegevens worden gekoppeld, terwijl de ListView-handleiding collectievirtualisatie en hergebruikte visuele elementen beschrijft. Bij een zeer grote collectie kan virtualisatie voorkomen dat er voor elk item dat niet op het scherm staat een apart UI-element wordt aangemaakt.
5. Sla de spelersstatus veilig op.
Sla de inventarisstatus van de speler op, niet een kopie van elke door de auteur gedefinieerde item. Een opgeslagen item kan een schemaversie bevatten en, voor elk bezet slot, de item-ID, de hoeveelheid, de slotindex en alle unieke instantiegegevens die de speler bezit.
Bij het laden moet de versie worden gevalideerd, moet worden gecontroleerd of elk item-ID nog bestaat, moeten niet-positieve aantallen worden afgewezen, moeten waarden worden beperkt tot wettelijke limieten en moeten verwijderde items worden afgehandeld met een migratieregel of een veilige terugvaloptie. Test het laden na een cataloguswijziging, evenals het opslaan en laden tijdens normaal spel.
JSON is handig voor een klein prototype omdat het leesbaar is voor mensen, maar het vereist expliciete conversie voor spelspecifieke gegevenstypen en kan groter zijn dan binaire formaten. De handleiding voor het opslaan van spellen in Godot behandelt JSON en de beperkingen ervan; gebruik het user://voor persistente gebruikersgegevens in geëxporteerde Godot-projecten, zoals uitgelegd in de documentatie over bestandspaden .
6. Bescherm inventariswijzigingen in multiplayer
Bij een online game kan de client een actie aanvragen, maar een vertrouwde server moet beslissen of een cruciale wijziging voor de gameplay geldig is. Controleer het eigendom, de hoeveelheid, de capaciteit, de verhandelbaarheid en de relevante spelstatus op de server voordat de update wordt geaccepteerd. Accepteer de bewering van een client dat deze een item heeft verkregen of een transactie heeft voltooid niet zonder verificatie. De officiële multiplayer-documentatie van Godot raadt aan om clientinvoer als onbetrouwbaar te beschouwen en cruciale spelstatus te valideren.
7. Test de gevallen die de voorraadniveaus verstoren.
Voordat je de regels definitief vastlegt, test je ze eerst met een kleine catalogus en een bijna volledige inventaris. Neem de volgende gevallen mee:
- Voeg één item toe en voeg er vervolgens genoeg toe om een bestaande stapel precies te vullen.
- Voeg meer stapels toe dan er in één stapel passen en controleer of de resterende stapels lege vakjes gebruiken.
- Probeer items toe te voegen wanneer alle vakjes bezet zijn en controleer of de overgebleven items bewaard blijven.
- Verplaats, verwissel, splits en voeg items samen op de eerste en laatste positie-index.
- Poging om incompatibele unieke items samen te voegen en een ongeldig item uit te rusten.
- Sla het spel op, laad het opnieuw en laad vervolgens een opgeslagen spel met een onbekende of verouderde item-ID.
- Herhaal veelgebruikte acties met de muis, controller of touchscreen-input van je game.
Profileer de database voordat u objectpooling of andere prestatiecomplexiteit toevoegt. Voor de meeste kleine databases zijn duidelijke gegevenseigendom en correct updategedrag belangrijker dan vroegtijdige optimalisatie. Als een grote, scrollende database meetbare UI-kosten met zich meebrengt, gebruik dan de lijstvirtualisatietools van de database-engine en profileer de database opnieuw.
Wat maakt een voorraadbeheersysteem bevredigend?
Spelers vinden inventarisbeheer prettig wanneer het systeem hun tijd respecteert: items zijn gemakkelijk te identificeren, veelvoorkomende acties vereisen weinig invoer, mislukte acties worden uitgelegd en het oppakken van items geeft onmiddellijk feedback. Begin met deze basisprincipes en voeg sorteren, crafting-links, duurzaamheid, winkels of ruilen alleen toe wanneer ze de kern van de game ondersteunen. Zo creëer je een inventarissysteem dat betrouwbaar aanvoelt en spelers meer ruimte geeft om zich op het avontuur te concentreren.