Skip to content

Latest commit

 

History

51 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Custom Resource Bars for Foundry VTT

A foundational module that allows other modules to add custom resource bars to D&D 5e character sheets, matching the native HP and Hit Dice styling.

Custom Bars Example

Features

  • Universal API - Any module can register custom resource bars
  • User-Created Bars - Players can add custom bars directly via "+" button (edit mode)
  • Native Styling - Matches D&D 5e character sheet aesthetics perfectly
  • Auto-Refresh - Bars update automatically when actor data changes
  • Click-to-Edit - Optional editable values with simple input dialog
  • Customizable - Colors, positions, visibility conditions
  • Config Buttons - Optional gear icon for advanced configuration
  • GM-Only Mode - Hide bars from players if needed

Installation

Manifest URL:

https://raw.githubusercontent.com/TinyDragonEgg/aspects-custom-bars/main/module.json

Or search for "Custom Resource Bars" in Foundry's module browser.

Usage

This module provides two ways to add custom resource bars:

  1. User-Created Bars - Players can add bars directly via the character sheet
  2. Module API - Modules can programmatically register bars with advanced features

For Players: Adding Custom Bars

  1. Open your character sheet
  2. Click the Edit button (lock icon) to enter edit mode
  3. Scroll to the resources section (below Hit Dice)
  4. Click the "+ Add Resource Bar" button
  5. Fill in the details:
    • Resource Name (e.g., "Focus Points", "Rage", "Superiority Dice")
    • Current Value
    • Maximum Value
    • Bar Color (pick your favorite!)
  6. Click Create

Your custom bar will appear immediately! You can:

  • Click the value to edit it quickly
  • Click the trash icon (edit mode) to delete the bar
  • Track any resource you want without needing a module

For Module Developers: Using the API

This module provides an API for other modules to register custom bars with advanced features. It doesn't add any bars by itself - it's a foundation for other modules to build on.

Basic Example: Ballistic Ward

// Wait for the custom bars system to be ready
Hooks.on('customBars.ready', () => {
  // Register a Ballistic Ward bar for Artillery Witch wizards
  game.customBars.registerBar({
    id: 'ballisticWard',
    name: 'Ballistic Ward',

    // Calculate current value
    getValue: (actor) => {
      return actor.getFlag('my-module', 'ward.current') || 0;
    },

    // Calculate max value
    getMax: (actor) => {
      const conMod = actor.system.abilities.con.mod;
      const wizLevel = actor.classes?.wizard?.system?.levels || 0;
      return conMod * wizLevel;
    },

    // Only show for Artillery Witch subclass
    showWhen: (actor) => {
      return actor.items.some(i =>
        i.type === 'subclass' &&
        i.name.includes('Artillery Witch')
      );
    },

    editable: true,
    barColor: '#4a90e2',
    position: 0
  });

  // Listen for value changes
  Hooks.on('customBars.barValueChange', async (actor, barId, newValue, oldValue) => {
    if (barId === 'ballisticWard') {
      await actor.setFlag('my-module', 'ward.current', newValue);
      ui.notifications.info(`Ballistic Ward updated: ${newValue}`);
    }
  });
});

API Reference

game.customBars.registerBar(config)

Registers a new custom resource bar.

Parameters:

Parameter Type Required Description
id String Yes Unique identifier
name String Yes Display name
getValue Function Yes (actor) => number - Returns current value
getMax Function Yes (actor) => number - Returns max value
showWhen Function No (actor) => boolean - Visibility condition (default: always shown)
editable Boolean No Allow click-to-edit (default: false)
barColor String No CSS color (default: '#4a90e2')
position Number No Display order, lower = earlier (default: 999)
configButton Object No {tooltip, action} - Adds config button
gmOnly Boolean No Only visible to GMs (default: false)

Returns: Bar configuration object

Example:

game.customBars.registerBar({
  id: 'arcaneWard',
  name: 'Arcane Ward',
  getValue: (actor) => actor.getFlag('dnd5e', 'arcaneWard.current') || 0,
  getMax: (actor) => (actor.classes?.wizard?.system?.levels * 2) + actor.system.abilities.int.mod,
  showWhen: (actor) => actor.items.some(i => i.name.includes('Abjuration')),
  editable: true,
  barColor: '#9b59b6',
  position: 1
});

game.customBars.unregisterBar(id)

Removes a registered bar.

Parameters:

  • id (String) - Bar identifier

Returns: Boolean - Success status

game.customBars.refreshBars(actor)

Force refresh all bars for an actor.

Parameters:

  • actor (Actor) - The actor to refresh

game.customBars.updateBarValue(actor, barId, newValue)

Programmatically update a bar (triggers refresh).

Parameters:

  • actor (Actor) - The actor
  • barId (String) - Bar identifier
  • newValue (Number) - New current value

Hooks

customBars.ready

Fired when the custom bars system is initialized and ready for registration.

Hooks.on('customBars.ready', () => {
  // Register your bars here
});

customBars.barValueChange

Fired when a user edits a bar's current value.

Parameters:

  • actor (Actor) - The actor
  • barId (String) - Bar identifier
  • newValue (Number) - New value
  • oldValue (Number) - Previous value
Hooks.on('customBars.barValueChange', async (actor, barId, newValue, oldValue) => {
  if (barId === 'myBar') {
    await actor.setFlag('my-module', 'value', newValue);
  }
});

customBars.configClick

Fired when a bar's config button is clicked.

Parameters:

  • actor (Actor) - The actor
  • barId (String) - Bar identifier
  • action (String) - Action name from config
Hooks.on('customBars.configClick', (actor, barId, action) => {
  if (action === 'showWardConfig') {
    // Show configuration dialog
  }
});

Advanced Examples

Multiple Bars with Different Colors

Hooks.on('customBars.ready', () => {
  // War Resonance
  game.customBars.registerBar({
    id: 'warResonance',
    name: 'War',
    getValue: (actor) => actor.getFlag('aspects-resonance', 'aspects.war') || 0,
    getMax: () => 100,
    barColor: '#e74c3c',
    position: 10
  });

  // Life Resonance
  game.customBars.registerBar({
    id: 'lifeResonance',
    name: 'Life',
    getValue: (actor) => actor.getFlag('aspects-resonance', 'aspects.life') || 0,
    getMax: () => 100,
    barColor: '#2ecc71',
    position: 11
  });
});

With Config Button

Hooks.on('customBars.ready', () => {
  game.customBars.registerBar({
    id: 'companionBond',
    name: 'Companion Bond',
    getValue: (actor) => actor.getFlag('companions', 'bondStrength') || 0,
    getMax: () => 20,
    showWhen: (actor) => actor.getFlag('companions', 'hasCompanion'),
    editable: true,
    barColor: '#2ecc71',
    configButton: {
      tooltip: 'Manage Companion',
      action: 'showCompanionDialog'
    }
  });

  // Handle config button click
  Hooks.on('customBars.configClick', (actor, barId, action) => {
    if (action === 'showCompanionDialog') {
      new Dialog({
        title: 'Companion Management',
        content: '<p>Companion configuration here...</p>',
        buttons: { close: { label: 'Close' } }
      }).render(true);
    }
  });
});

GM-Only Bar

Hooks.on('customBars.ready', () => {
  game.customBars.registerBar({
    id: 'corruptionLevel',
    name: 'Corruption',
    getValue: (actor) => actor.getFlag('my-module', 'corruption') || 0,
    getMax: () => 10,
    barColor: '#8b0000',
    gmOnly: true  // Players can't see this
  });
});

Styling

Bars inherit native D&D 5e styling automatically. For custom styling:

/* Target specific bar */
.custom-bar[data-bar-id="ballisticWard"] .progress {
  box-shadow: 0 0 10px var(--bar-color);
}

/* Glow animation */
.custom-bar .progress[aria-valuenow]:not([aria-valuenow="0"]) {
  animation: pulse 2s infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.7; }
}

Compatibility

  • Foundry VTT: v11+
  • D&D 5e System: v3.0+
  • Character Sheets: Legacy and v2 sheets supported

Use Cases

This module is designed to support:

  • Ballistic Ward (Artillery Witch subclass)
  • Arcane Ward (Abjuration Wizard)
  • Aspectual Resonance tracking
  • Companion Bond Strength
  • Ki Points (custom tracking)
  • Rage Uses (Barbarian)
  • Any custom resource your module needs!

Development

Repository: https://github.com/TinyDragonEgg/aspects-custom-bars

Issues: https://github.com/TinyDragonEgg/aspects-custom-bars/issues

License

MIT License - See LICENSE file

Credits

Created by TinyMagus for the Aspects of Verun campaign setting.

Special thanks to the Foundry VTT and D&D 5e system developers for their excellent APIs.

About

Custom Resource Bars for Foundry VTT - Add custom resource tracking to D&D 5e character sheets

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages