Skip to content

Comments

Nimble Combat System (NCS)#313

Draft
7D7D wants to merge 24 commits intoNimble-Co:devfrom
7D7D:feature/combat_tracker_group_minions
Draft

Nimble Combat System (NCS)#313
7D7D wants to merge 24 commits intoNimble-Co:devfrom
7D7D:feature/combat_tracker_group_minions

Conversation

@7D7D
Copy link
Collaborator

@7D7D 7D7D commented Feb 16, 2026

See latest comment for massive UPDATE

🎥 Minion Group Mode Demo

Click the image below to watch:

Watch Demo

PR Summary (Updated)

This PR adds full minion-only grouping support to the Combat Tracker so grouped minions share one turn slot, while still preserving per-minion state and management. It is focused on turn order and activation flow only (no grouped attack roll mechanics).

Key functionality delivered

  • Added minion grouping data model and helpers in minionGrouping.ts.
  • Grouping is restricted to actor type minion in both UI and document logic.
  • Grouped minions share initiative/sort and collapse into a single visible turn entry (leader only) via setupTurns() in combat.svelte.ts.
  • Added group operations on NimbleCombat:
    • createMinionGroup
    • addMinionsToGroup
    • removeMinionsFromGroups
    • dissolveMinionGroups
  • Preserved individual minion tracking while grouped (defeated state, remove/kill member actions, token identity).
  • Added persistent group lettering (A, B, C...) with monotonic progression and no reuse while groups still exist.
  • Added reset-to-A behavior when:
    • Ungroup All is used, or
    • the last remaining group is dissolved.
  • Added stable member numbering (G#) so existing members keep their IDs (example: A1, A3 stay; next added becomes A4).

Turn-order and reordering stability fixes

  • Added turn-index normalization/sync safeguards in combat.svelte.ts:
    • #syncTurnIndexWithAliveTurns
    • #syncTurnToCombatant
  • Ensures next actor stays correct after:
    • grouping/ungrouping,
    • adding active minion to a group,
    • GM drag reorder,
    • player-owned character reorder.
  • Added/updated tests covering these edge cases in combat.svelte.test.ts.

UI/UX additions and refinements

  • Group Mode workflow in CombatTracker.svelte + _combat-tracker.scss.
  • Selected card visual highlight for minion selection.
  • Group card badges now show:
    • group letter (bottom-left),
    • member count (xN, bottom-right).
  • Floating group popover:
    • anchored to the right of the group card,
    • auto-sized to show all members,
    • stays open during member remove actions.
  • Added per-member Kill action in popover (GM):
    • sets HP to 0,
    • marks combatant defeated,
    • refreshes live (optimistic + follow-up refresh).
  • Added token overlays for grouped minions in scene via minionGroupTokenBadges.ts:
    • top-right G# badge (for example A3),
    • removed automatically when ungrouped/dissolved,
    • improved text resolution.

Most recent popover changes (since prior summary)

  • Popover title typography updated to match combat tracker button style and improved readability.
  • Popover title text size increased and centered both horizontally and vertically.
  • Removed popover table header row entirely.
  • Removed popover status column.
  • Popover now shows compact member rows with G#, Member, Remove, Kill.

Group button logic and scenarios

Control Visibility/Enablement Action Typical scenario
Group Mode Always visible (GM). Active = green. Toggles minion grouping selection mode. Enter/exit grouping workflow.
Clear Visible while Group Mode is on. Disabled when nothing selected. Clears current selected combatants. Reset selection without leaving Group Mode.
Create Group Shown only when selected contains 2+ ungrouped minions and no grouped selections. Creates new group with shared turn and next letter. Build a fresh minion pack.
Add to Group Shown only when exactly one target group is selected plus at least one ungrouped minion. Adds selected minions into that existing group. Reinforce an existing pack.
Ungroup All Shown when any minion groups exist. Dissolves all groups in tracker; resets letter counter when none remain. Fast global reset.
Dissolve Shown when selection includes grouped minions (selected groups resolvable). Dissolves selected groups only. Remove specific groups without touching others.
Popover Remove GM-only, per member. Removes that minion from group; popover stays open. Pull one minion out for independent turn tracking.
Popover Kill GM-only, per member; disabled if already dead. Sets HP to 0 and defeats minion (live UI update). Instantly defeat a specific minion.
Popover Dissolve Group GM-only in popover footer. Dissolves the hovered group only. Quick per-group teardown.

@7D7D 7D7D self-assigned this Feb 16, 2026
@7D7D 7D7D changed the base branch from main to dev February 16, 2026 03:49
@7D7D
Copy link
Collaborator Author

7D7D commented Feb 16, 2026

Got feedback from @DoubleKing-Prime and @trevlar

Feedback/Reviews:
I think we need to be able to intuitively and quickly group and ungroup minions. If they are in a group, that means that they also all roll together when attacking. It would be nice to have a way to roll the attacks for those monsters together.
I think selecting/grouping minions on the token layer would be more intuitive than in the combat tracker.

Can you group them by selecting them on the map. Either drag-selecting them or just ctrl-selecting?I was just thinking that I think the way most people will default to trying to do it is multi-selecting, and then looking for a button to group them.

Working on a few different options starting with the plan below:

Option 1: Canvas "Group Selected" Action Bar

  • Use native token multi-select (drag-box or ctrl/shift multi-select, whatever Foundry keybinds are active).
  • When GM has token layer active and selects minion tokens, show a small floating action bar on canvas:
  • Group Selected appears when 2+ ungrouped minions are selected.
  • Add to Group appears when selection includes ungrouped minions plus exactly 1 existing group.
  • Remove from Group appears when grouped minions are selected.
  • Dissolve Group appears when one or more grouped minions are selected.
  • Clear Selection always available.
  • This should call your existing combat methods so tracker + map stay perfectly in sync.

Why this is best:

  • Fastest path for users.
  • Matches "multi-select then click button" expectation.
  • No mode-switch confusion.

@Fronix
Copy link
Collaborator

Fronix commented Feb 16, 2026

@7D7D

Based on the feedback, I would like an additional way to add minions to groups:

  1. Click "Group mode"
  2. Have it ask you to select minions on the canvas (click, drag to multi select etc works here) and only minions are selectable.
  3. You select the minions you want in the group
  4. Click "Create Group"
    During the selection the "Group mode" can transform into a "Selected minions {number}"

The option you suggested option could be added as well, they are not mutually exclusive.

Edit: Not sure if your option had this in mind but either way. I don't like it when UI:s aren't clear about what I'm doing, since there is so much stuff on the canvas during combat it should be very clear when you are "in group mode". I know dnd5e has this issue where grouping is very unintuitive and many times we've had monsters being grouped without it being clear and it's also a hassle to remove it.

@7D7D
Copy link
Collaborator Author

7D7D commented Feb 16, 2026

@7D7D

Based on the feedback, I would like an additional way to add minions to groups:

  1. Click "Group mode"

  2. Have it ask you to select minions on the canvas (click, drag to multi select etc works here) and only minions are selectable.

  3. You select the minions you want in the group

  4. Click "Create Group"

During the selection the "Group mode" can transform into a "Selected minions {number}"

The option you suggested option could be added as well, they are not mutually exclusive.

Agreed. We could have multiple options to fit different user preferences

Edit: I agree, we will get it dialed in so it is both intuitive and clear what it is doing.

Copy link
Collaborator

@trevlar trevlar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix merge conflicts

@7D7D 7D7D force-pushed the feature/combat_tracker_group_minions branch from ec93f12 to 6321210 Compare February 19, 2026 11:48
@7D7D 7D7D marked this pull request as draft February 19, 2026 16:17
@7D7D 7D7D dismissed trevlar’s stale review February 19, 2026 16:18

Fixed, reworking

@7D7D 7D7D changed the title Combat Tracker Support for Grouping Minions into Shared Turns Nimble Combat System for minions and non-minions Feb 20, 2026
@7D7D 7D7D force-pushed the feature/combat_tracker_group_minions branch from d6ce8d6 to ce8a31f Compare February 21, 2026 06:00
@7D7D
Copy link
Collaborator Author

7D7D commented Feb 21, 2026

Nimble Combat System (NCS)

  • Introduces a GM-only Nimble Combat System Window (NCSW) on canvas for running monster combat.
  • NCSW supports both non-minion monsters and minions in one place.
  • Blue check marks are added to map tokens and combat tracker cards when actor's turn has ended that round.
  • Non-minions use per-monster Roll / Roll + End Turn actions.
  • Minions attack together as a temporary selection-based group and generate a single combined group attack chat card.
  • Temporary minion groups are used for turn flow, appear as grouped for the round, and auto-dissolve at round boundaries.
  • Added target management in NCSW (token portrait targeting, live target info popovers, action tooltips, image popovers, draggable/resizable window).
  • Added turn/action flow updates so used-up actors are handled consistently during progression.
  • Added dark/light mode styling support for NCSW and moved NCS/NCSW user-facing text to i18n.
  • Closing NCSW (manual close or losing token selection) now automatically clears selected targets.

Out of scope

  • Group defend/interpose resolution logic is not included in this PR.

Screenshots of NCS

Screenshot 2026-02-21 020116 Screenshot 2026-02-21 015642 Screenshot 2026-02-21 020100 Screenshot 2026-02-21 015621 Screenshot 2026-02-21 020008 Screenshot 2026-02-21 015937 Screenshot 2026-02-21 015745 Screenshot 2026-02-21 015734 Screenshot 2026-02-21 015714 Screenshot 2026-02-21 015653

@7D7D 7D7D changed the title Nimble Combat System for minions and non-minions Nimble Combat System (NCS) Feb 21, 2026
@7D7D 7D7D marked this pull request as ready for review February 21, 2026 09:08
@Fronix
Copy link
Collaborator

Fronix commented Feb 21, 2026

@7D7D awesome work here!

Just a very important note that we are not allowed to use the Nimble logo as per the 3rd party license:

You may not use the System’s art or logo but may use the Nimble compatibility logo

Either remove it or replace it with the compatibility logo found on https://nimblerpg.com/pages/creators

Fronix
Fronix previously requested changes Feb 21, 2026
Copy link
Collaborator

@Fronix Fronix left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few things I'd like to see that are a bit codesmelly

The NCS window and related code should probably be named accordingly. As this looks like something we will probably build upon we should try to keep the code and related files named in such as way that's it easier to understand.

Comment on lines 10 to 17
export const MINION_GROUP_IDENTITY_COLOR_PALETTE = [
'#3B82F6', // A - Blue
'#F97316', // B - Orange
'#8B5CF6', // C - Violet
'#FACC15', // D - Yellow
'#06B6D4', // E - Cyan
'#D946EF', // F - Magenta
] as const;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason to hardcode these values like this? I'd like to se those editable

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will remove those, they were from the old system, just missed them on the clean up.

@7D7D
Copy link
Collaborator Author

7D7D commented Feb 21, 2026

A few things I'd like to see that are a bit codesmelly

The NCS window and related code should probably be named accordingly. As this looks like something we will probably build upon we should try to keep the code and related files named in such as way that's it easier to understand.

I did try to do that. I had to change the old names "Canvas Lite" "Group Mode" etc... but I may have missed some. If you see any let me know.

Going forward I am using:

  1. Nimble Combat System (NCS) for the entire system
  2. Nimble Combat System Window (NCSW) for referencing the window

@7D7D 7D7D dismissed Fronix’s stale review February 22, 2026 00:40

Addressed naming convention

@7D7D
Copy link
Collaborator Author

7D7D commented Feb 22, 2026

Changed Logo to the "Nimble Compatibility Logos". I prefer the Nimble logo used on the book (that as a bonus works well in light and dark mode thanks to the black text outline). I am hoping we can get permission from Even to use that Logo instead.

I cleaned/removed old combat system code.

Improved some of the dice roll value logic for the NCS

"Nimble Compatibility Logos"
Screenshot 2026-02-21 180437
Screenshot 2026-02-21 180425

Book Nimble Logo
Screenshot 2026-02-21 0840217
Screenshot 2026-02-21 084049

await this.#syncTurnToCombatant(previousActiveCombatantId, { persist: false });
return updated ? [updated] : [];
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scream 😱 We've got to start getting a handle on these long, complicated files. I think in the future I'll set limits on file length and function length. Essentially, keeping the total cyclomatic complexity down reduces the likelihood of bugs being introduced.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I’m trying to condense it right now. I will switch the PR to draft. I think it may be coming from the previous versions of this feature, I’m trying to make sure all the unnecessary code is actually cleaned out correctly. I’ve done a few passes

@7D7D 7D7D marked this pull request as draft February 22, 2026 04:03
Copy link
Collaborator

@trevlar trevlar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Duplicated canCurrentUserReorderCombatant function — Defined in both combat.svelte.ts:25 and CombatTracker.svelte:94. Consider consolidating.
  2. Test fixture refactoring — Shared fixtures were inlined into individual test files, increasing duplication.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants