Skip to main content
The project's repository is archived as part of the GitHub Archive Program. RogueLibs' code and the documentation will no longer be updated.

Creating a Custom Trait

RogueLibs provides classes and methods to create custom traits, and an interface to make traits updateable. Just like items, custom traits derive from a hook class, CustomTrait, and their functionality can be expanded with interfaces: ITraitUpdateable, just one in this case. If you want the trait to have some kind of a passive effect, then you might need to patch that in yourself.

CustomTrait class

To make a custom trait, you need to create a class deriving from CustomTrait:

MyCustomTrait.cs
public class MyCustomTrait : CustomTrait
{
/* ... */
}

There are 2 methods that you need to implement:

MyCustomTrait.cs
public class MyCustomTrait : CustomTrait
{
public override void OnAdded() { /* ... */ }
public override void OnRemoved() { /* ... */ }
}

OnAdded is called when the trait is added to a character, and OnRemoved is called when it's removed from a character.

Updating

You can make your trait updateable by implementing the ITraitUpdateable interface:

MyCustomTrait.cs
public class MyCustomTrait : CustomTrait, ITraitUpdateable
{
public void OnUpdated(TraitUpdatedArgs e) { /* ... */ }
}

OnUpdated works like Unity's Update, but with a settable interval (default is 1 second):

    public void OnUpdated(TraitUpdatedArgs e)
{
e.UpdateDelay = 0.5f; // 2 updates per second
/* ... */
}

Initialization

Just call the CreateCustomTrait method with your trait's type as a parameter:

MyCustomTrait.cs
public class MyCustomTrait : CustomTrait
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomTrait<MyCustomTrait>();
}
}
note

See more about the RLSetup attribute here.

You can set your trait's name and description using WithName and WithDescription methods:

MyCustomTrait.cs
public class MyCustomTrait : CustomTrait
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomTrait<MyCustomTrait>()
.WithName(new CustomNameInfo("My Custom Trait"))
.WithDescription(new CustomNameInfo("My Custom Trait is very cool and does a lot of great stuff"));
}
}

You can do the same with sprites and unlocks:

MyCustomTrait.cs
public class MyCustomTrait : CustomTrait
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomTrait<MyCustomTrait>()
.WithName(new CustomNameInfo("My Custom Trait"))
.WithDescription(new CustomNameInfo("My Custom Trait is very cool and does a lot of great stuff"))
// the sprite will be displayed only in the menus (optional)
.WithSprite(Properties.Resources.MyCustomTrait)
.WithUnlock(new TraitUnlock { UnlockCost = 10, CharacterCreationCost = 5 });
}
}
info

See Custom Names, Custom Sprites for more info.

Unlock Properties

You can use the following properties when initializing TraitUnlocks:

PropertyDefaultDescription
UnlockCost0Unlock cost of the trait, in nuggets. If set to 0, it will unlock automatically, once all prerequisites are unlocked.
CharacterCreationCost1Cost of the trait in Character Creation, in points.
IsAvailabletrueDetermines whether the trait is available in the Traits menu and on level-ups. If the trait is negative, set it to false.
IsAvailableInCCtrueDetermines whether the trait is available in the Character Creation menu.
CancellationsDetermines what traits cannot co-exist with this trait.
PrerequisitesDetermines what unlocks must be unlocked in order to unlock this trait.
RecommendationsJust shows these unlocks in a separate Recommendations paragraph in the menus.

Other properties should not be used during initialization.

Examples

using System;

namespace RogueLibsCore.Test
{
public class Smoker : CustomTrait, ITraitUpdateable
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomTrait<Smoker>()
.WithName(new CustomNameInfo("Smoker"))
.WithDescription(new CustomNameInfo("Randomly cough, alerting enemies"))
.WithUnlock(new TraitUnlock { CharacterCreationCost = -4 });

RogueLibs.CreateCustomName("Smoker_Cough1", NameTypes.Dialogue, new CustomNameInfo("*Cough*"));
RogueLibs.CreateCustomName("Smoker_Cough2", NameTypes.Dialogue, new CustomNameInfo("*Cough* *CouGH*"));
RogueLibs.CreateCustomName("Smoker_Cough3", NameTypes.Dialogue, new CustomNameInfo("*coUGH* *COUgh*"));
}

public override void OnAdded() { }
public override void OnRemoved() { }
public void OnUpdated(TraitUpdatedArgs e)
{
e.UpdateDelay = 5f;

int rnd = new Random().Next(0, 5);
if (rnd == 0)
{
rnd = new Random().Next(3) + 1;
Owner.SayDialogue($"Smoker_Cough{rnd}");
gc.audioHandler.Play(Owner, VanillaAudio.AgentAnnoyed);

Noise noise = gc.spawnerMain.SpawnNoise(Owner.tr.position, 1f, Owner, "Attract", Owner);
noise.distraction = true;
}
}
}
}

The project's repository is archived as part of the GitHub Archive Program. RogueLibs' code and the documentation will no longer be updated.