All Docs Documentation Version: Base (Free) Influence System Ultimate
Simple Attribute Forge Ultimate

Character Template System

Define starting attribute configurations for character classes in your RPG.

Overview

The Character Template System allows you to define distinct starting configurations for different character classes (Warrior, Mage, Rogue, etc.). Each template specifies which attributes to override from their default values.

Visual Wizard

4-step wizard for creating character classes with per-attribute overrides.

Code Generation

Generates enum, manager, helper, and validator classes automatically.

ScriptableObject Assets

Each template is a .asset file that can be edited in the Inspector.

Vital Attribute Filtering

Automatically identifies derived attributes (Vital type) that shouldn't be manually overridden.

Integration: Character Templates set base attribute values. The Influence System then calculates derived stats, and the Modifier System applies temporary effects on top.

Core Classes

SimpleCharacterTemplateData

ScriptableObject that stores template configuration. Created via the wizard, not manually.

Properties
PropertyTypeDescription
systemNamestringName of the template system
templateNamestringDisplay name for the template
descriptionstringHuman-readable description
templateIconSpriteOptional icon for UI display
baseAttributeOverridesList<AttributeValueOverride>Attribute value overrides

SimpleCharacterClass

Individual character class configuration used in the wizard.

Properties
PropertyTypeDescription
ClassNamestringName of the class (e.g., "Warrior")
DescriptionstringClass description
ClassIconSpriteOptional class icon
BaseAttributeOverridesList<AttributeValueOverride>Starting attribute values

AttributeValueOverride

Individual attribute override configuration.

Properties
PropertyTypeDescription
AttributeNamestringName of the attribute to override
OverrideValuefloatValue to set
UseOverrideboolWhether to apply this override

Using the Template Wizard

1 Open the Wizard
Go to Window > Simple Attribute Forge > Character Template Wizard
2 Step 1: Select Attribute Data
3 Step 2: Define Character Classes
4 Step 3: Configure Generation Settings
5 Step 4: Generate Code

Generated Code

The wizard generates four files, each serving a different purpose:

Enum

Type-safe identifiers for each character class. Useful for code readability and IntelliSense.

// Generated: SoulslikeCharacterTemplateEnum.cs public enum SoulslikeCharacterTemplateEnum { AshKnight, BlightRogue, BloodHerald, BoneArcher, DuskPriest, EmberSeer, GraveWarden, HollowPilgrim, HollowScholar, IronWanderer, Oathbreaker, PaleWitch, VeilDancer }

Helper (Static Utility Class)

Static methods for applying templates from anywhere in your code. This is the primary API for template operations.

// Get all available templates in the project List<SimpleCharacterTemplateData> templates = SoulslikeCharacterTemplatesHelper.GetAllTemplates(); // Find a specific template by name SimpleCharacterTemplateData template = SoulslikeCharacterTemplatesHelper.FindTemplateByName("Ash Knight"); // Apply template to a GameObject with an attribute system SoulslikeCharacterTemplatesHelper.ApplyTemplateToGameObject(playerGameObject, template); // Apply template to multiple GameObjects at once SoulslikeCharacterTemplatesHelper.ApplyTemplateToGameObjects(enemyArray, template); // Get an attribute value from a template (returns default 10 if not overridden) float strength = SoulslikeCharacterTemplatesHelper.GetAttributeValue(template, "Strength"); // Check if template is compatible with an attribute system bool compatible = SoulslikeCharacterTemplatesHelper.IsTemplateCompatible(template, attributeSource); // Compare two templates and get attribute differences Dictionary<string, float> diff = SoulslikeCharacterTemplatesHelper.GetAttributeDifferences(templateA, templateB); // Get total attribute points used by a template float totalPoints = SoulslikeCharacterTemplatesHelper.GetTotalAttributePoints(template); // Switch templates while optionally preserving non-overridden values SoulslikeCharacterTemplatesHelper.SwitchTemplate(playerGameObject, newTemplate, preserveCurrentValues: true);

Manager (MonoBehaviour Component)

Optional component you attach to a GameObject. Provides Inspector configuration, auto-discovery, and convenient instance methods for that specific GameObject.

When to use the Manager: Attach it to your player or NPC prefabs when you want Inspector-configurable template management, auto-apply on Start, or runtime template switching buttons in the editor.
// The Manager is a MonoBehaviour - attach it to a GameObject in the Inspector // or add it via code: var manager = player.AddComponent<SoulslikeCharacterTemplateManager>(); // Apply a template to THIS GameObject (uses Helper internally) manager.ApplyTemplate(template); // Apply template by name manager.ApplyTemplate("Ash Knight"); // Get template by name from the manager's available templates list SimpleCharacterTemplateData t = manager.GetTemplateByName("Ash Knight"); // Get the template that best matches current attribute values SimpleCharacterTemplateData current = manager.GetCurrentTemplate(); // Switch to a new template manager.SwitchTemplate(newTemplate, preserveCurrentValues: true); // Validate template compatibility bool valid = manager.ValidateTemplate(template);

Manager Inspector Features:

Validator (Static Validation Utilities)

Runtime validation to check template compatibility with attribute systems.

// Validate a single template against an attribute source List<string> errors; bool isValid = SoulslikeCharacterTemplatesValidator.ValidateTemplate( template, attributeSource, // ISimpleAttributeDataSource out errors ); if (!isValid) { foreach (var error in errors) Debug.LogError(error); } // Validate all templates in a list bool allValid = SoulslikeCharacterTemplatesValidator.ValidateAllTemplates( templateList, attributeSource );

Two Approaches: Helper vs Manager

You can use either approach depending on your needs:

Static Helper Approach

Best for: Code-driven template application, systems where you control when templates are applied.

// Apply from anywhere in code var template = SoulslikeCharacterTemplatesHelper .FindTemplateByName("Ash Knight"); SoulslikeCharacterTemplatesHelper .ApplyTemplateToGameObject(player, template);

Manager Component Approach

Best for: Inspector-based setup, auto-apply on Start, runtime testing in editor.

// Attach manager to player prefab // Configure in Inspector: // - Set default template // - Enable auto-apply on Start // - Done! No code needed.
Note: The Manager uses the Helper internally. Both approaches achieve the same result - choose based on your workflow preference.

Example: Soulslike Character Classes

The Ultimate demo includes 13 pre-built Soulslike-style character templates:

Included Templates
TemplateFocusKey Attributes
Ash KnightBalanced meleeSTR, END, VIG
Blight RoguePoison & stealthDEX, LCK, ARC
Blood HeraldBlood magicARC, VIG, END
Bone ArcherRanged combatDEX, STR, END
Dusk PriestFaith healingFAI, ATT, VIG
Ember SeerFire sorceryINT, ATT, DEX
Grave WardenTank & defenseVIG, END, STR
Hollow PilgrimStarting classBalanced
Hollow ScholarPure casterINT, ATT, FAI
Iron WandererHeavy meleeSTR, VIG, END
OathbreakerDark knightSTR, FAI, VIG
Pale WitchMoon sorceryINT, ARC, ATT
Veil DancerAgile fighterDEX, END, LCK

Complete Integration Example

Character Creation Screen

using UnityEngine; using UnityEngine.UI; using SimpleAttributeForge; using SimpleAttributeForge.CharacterTemplate; using Soulslike.CharacterTemplates; public class CharacterCreationUI : MonoBehaviour { [SerializeField] private Transform classButtonContainer; [SerializeField] private GameObject classButtonPrefab; [SerializeField] private GameObject playerObject; void Start() { PopulateClassButtons(); } void PopulateClassButtons() { // Get all available templates using the static Helper var templates = SoulslikeCharacterTemplatesHelper.GetAllTemplates(); foreach (var template in templates) { var button = Instantiate(classButtonPrefab, classButtonContainer); // Setup button text button.GetComponentInChildren<Text>().text = template.templateName; // Capture template in closure and add click handler var capturedTemplate = template; button.GetComponent<Button>().onClick.AddListener(() => SelectClass(capturedTemplate) ); } } void SelectClass(SimpleCharacterTemplateData template) { // Apply the template to player GameObject bool success = SoulslikeCharacterTemplatesHelper.ApplyTemplateToGameObject( playerObject, template ); if (success) { Debug.Log($"Selected class: {template.templateName}"); // The Influence System will automatically recalculate derived stats // (Health from Vigor, Stamina from Endurance, etc.) } } }

Using Template Manager on Player Prefab

using UnityEngine; using SimpleAttributeForge.CharacterTemplate; using Soulslike.CharacterTemplates; public class PlayerSetup : MonoBehaviour { // Reference to the manager component on this GameObject private SoulslikeCharacterTemplateManager templateManager; void Awake() { templateManager = GetComponent<SoulslikeCharacterTemplateManager>(); } // Called from UI when player selects a class public void OnClassSelected(string className) { templateManager.ApplyTemplate(className); } // Called when player wants to respec public void OnRespec(SimpleCharacterTemplateData newTemplate) { // Switch template while keeping any leveled-up attributes templateManager.SwitchTemplate(newTemplate, preserveCurrentValues: true); } }

Vital Attribute Filtering

The wizard automatically identifies "Vital" type attributes (Health, Stamina, Mana, etc.) and marks them as derived. These attributes shouldn't be directly overridden because they're calculated by the Influence System.

Best Practice: Override base stats (Vigor, Strength, Intelligence) and let the Influence System calculate derived stats (Health, Damage, Defense).
Attribute Types
TypeOverride?Examples
BasicYesStrength, Dexterity, Intelligence
ResourceYesLevel, Souls, Humanity
VitalNo (Derived)Health, Stamina, Mana, Focus
PercentageDependsEquipment Load (may be derived)

Best Practices

Use Meaningful Names

Class names should be evocative: "Ash Knight", "Pale Witch", not "Class1", "Class2".

Balance Starting Stats

Keep total stat points similar across classes. Different distributions, similar power levels.

Write Good Descriptions

Help players understand each class's playstyle: "Agile fighter specializing in dodging and quick strikes."

Use Icons for UI

Set template icons for character selection screens. Makes the UI more professional.