This guide walks you through creating your first custom item using CustomItems LabAPI. You’ll learn the basic structure of a custom item and how to register it with the framework.
Let’s create a simple custom item: a speed boost syringe that increases the player’s movement speed when used.
1
Create a new class
In your plugin project, create a new class that inherits from CustomItem:
using CustomItems.API;using LabApi.Events.Arguments.PlayerEvents;using LabApi.Features.Wrappers;using MEC;using System.Collections.Generic;namespace YourPlugin.CustomItems{ public class SpeedBoostSyringe : CustomItem { // Implementation goes here }}
2
Define basic properties
Implement the required properties that define your item:
public override string Name => "Speed Boost Syringe";public override string Description => "Temporarily increases movement speed.";public override ItemType Type => ItemType.Adrenaline;public override float Weight => 1.0f;
These properties determine how the item appears and behaves in the game. The Type property sets the base item model (in this case, an adrenaline syringe).
3
Implement registration callbacks
Add the required registration methods. These are called when your item is registered or unregistered:
public override void OnRegistered(){ // Called when the item is registered // Subscribe to events or initialize resources here}public override void OnUnregistered(){ // Called when the item is unregistered // Unsubscribe from events or clean up resources here}
4
Add item behavior
Override the OnUsing method to define what happens when a player uses the item:
public override void OnUsing(PlayerUsingItemEventArgs ev){ // Apply speed boost effect const float duration = 10f; const float speedMultiplier = 1.3f; // Start the speed boost coroutine Timing.RunCoroutine(ApplySpeedBoost(ev.Player, duration, speedMultiplier)); // Remove the item from the player's inventory ev.Player.RemoveItem(ev.UsableItem);}private IEnumerator<float> ApplySpeedBoost(Player player, float duration, float multiplier){ // Store the original speed float originalSpeed = player.MovementSpeed; // Apply the speed boost player.MovementSpeed *= multiplier; // Wait for the duration yield return Timing.WaitForSeconds(duration); // Restore original speed if (player.IsAlive) player.MovementSpeed = originalSpeed;}
Once you’ve created your custom item class, you need to register it with the framework. In your plugin’s Enable method:
using CustomItems.API;public override void Enable(){ // Register a single item var speedBoost = new SpeedBoostSyringe(); CustomItems.Register(speedBoost);}
The RegisterAll() method automatically finds and registers all classes in your assembly that inherit from CustomItem. This is the recommended approach for plugins with multiple custom items.
Don’t forget to unregister your items in the Disable method:
public override void Disable(){ CustomItems.UnregisterAll();}
You can give custom items to players using the TryGive method:
// Get the item ID by nameushort itemId = CustomItems.GetIdByName("Speed Boost Syringe");// Give the item to a playerif (CustomItems.TryGive(itemId, player, out Item item)){ Log.Info($"Gave Speed Boost Syringe to {player.Nickname}");}
You can also spawn items in the world:
// Spawn an item at a specific positionif (CustomItems.TrySpawn(itemId, position, out Pickup pickup)){ Log.Info($"Spawned Speed Boost Syringe at {position}");}
Let’s look at a more advanced example from the included EMP Grenade that uses event subscriptions:
Example: EMP Grenade
using CustomItems.API;using CustomItems.Core;using LabApi.Events.Arguments.ServerEvents;using LabApi.Events.Handlers;using LabApi.Features.Wrappers;using MEC;using Mirror;namespace CustomItems.API.Example{ public class EMPGrenade : CustomItem { public override string Name => "EMP Grenade"; public override string Description => "Locks doors and disables lights in current room."; public override ItemType Type => ItemType.GrenadeHE; public override void OnRegistered() { // Subscribe to the explosion event ServerEvents.ProjectileExploding += OnExplosion; } public override void OnUnregistered() { // Unsubscribe from the explosion event ServerEvents.ProjectileExploding -= OnExplosion; } private void OnExplosion(ProjectileExplodingEventArgs ev) { // Check if this is our custom item if (!Check(ev.TimedGrenade)) return; // Cancel the normal explosion ev.IsAllowed = false; Log.Debug($"EMP Grenade exploded at {ev.TimedGrenade.Position}"); Room room = ev.TimedGrenade.Room; // Flicker lights for 10 seconds room.LightController.FlickerLights(10); // Lock all doors in the room foreach (var door in room.Doors) { if (door.IsLocked) continue; door.IsLocked = true; // Unlock after 10 seconds Timing.CallDelayed(10f, () => { door.IsLocked = false; }); } // Destroy the grenade object NetworkServer.Destroy(ev.TimedGrenade.GameObject); } }}
This example demonstrates:
Subscribing to game events in OnRegistered() (CustomItems-LabAPI/API/Example/EMPGrenade.cs:18-21)
Using the Check() method to verify if an item is your custom item (CustomItems-LabAPI/API/Example/EMPGrenade.cs:30)
Manipulating game objects like rooms, lights, and doors (CustomItems-LabAPI/API/Example/EMPGrenade.cs:36-47)
Proper cleanup in OnUnregistered() (CustomItems-LabAPI/API/Example/EMPGrenade.cs:23-26)