> For the complete documentation index, see [llms.txt](https://swu-forge.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://swu-forge.gitbook.io/docs/teams/team-battle-log.md).

# Team Battle Log

The **Team Battle Log** rolls up karabast.net games **scoped to the team** into archetype buckets, so a team can see at a glance which decks the group is grinding and how they're performing.

Each match carries a **set of teams** it's scoped to (set when the match is recorded, editable per-match; see [Recording scope](#recording-scope) below), and the stats filter on it. This is what stops a member who belongs to multiple teams from having their games bleed into every team they're on: a game counts toward exactly the teams its match is scoped to — nothing automatic.

## Where to find it

From your team's home, click the **Battle Log** button in the header. The page is visible to every team member regardless of role — read-only for VIEWERs is the same as for everyone else here.

## What you'll see

### Archetype list

Each row is a unique `(leader, base-group)` combination. Bases are normalised through `karabastBaseGroupKey()` so all 30HP-Vigilance common bases collapse into one archetype, while rare bases (e.g. *Lake Country*) keep their own row.

Above the list are the same controls as the per-user [Battle Log tab](/docs/battle-log/battle-log/battle-log-tab.md), and they **apply to every view** — Leader + Base, Leader, Base type, and Pilot alike:

* A **Date range** (from–to) that narrows the list to games in the window. It **composes with the selected** [**stats period**](/docs/teams/team-battle-log/team-stats-periods.md) — the date range further narrows within the active meta. Clear it with the ✕ next to the inputs.
* A **Sort by** control — **Recent** (default; most recently played first) or **Win rate** (over decisive games, wins ÷ (wins + losses)) — plus a direction toggle for descending/ascending. Rows with no decided games sort to the bottom in the default order.
* A **Min games** control that hides archetypes with fewer than the chosen number of games, so a win-rate sort isn't dominated by one-off matchups. Pick a preset (**Any** / **10** / **15** / **25** / **50** / **100**) or type any custom number in the box next to it.
* Three dropdowns that narrow which matches are counted at all:

  * **Pilot** — one team member's games only.
  * **Archetype** — games your team played on one leader + base.
  * **Opponent** — games your team played *against* one leader + base.

  Each lists the archetypes and pilots that actually appear in the current stats period and date range, most-played first, and you can type to search a long list. They combine, so "Alice, on Palpatine, against Boba" is one selection away, and they stay in force whichever view you're in.

Your date range, sort, minimum, and the three dropdowns all carry over as you switch between the group-by views.

Columns:

* **Archetype** — leader and (representative) base. A small `· Common 30HP` tag indicates a common-base rollup; otherwise the row is identified by the specific rare base.
* **Games** — total games this archetype has logged across the team.
* **W–L–D** — cumulative record. Draws appear only when there are draws to show.
* **Players** — unique pilots on the team who've recorded games with this archetype.
* **Last played** — relative time since the most recent game.

If any games couldn't be archetype-bucketed (karabast missed the leader or base in capture), a footer surfaces the count.

### Archetype detail

Click any row to drill in. The detail page is laid out as:

* **Header** — the leader/base hero plus the two headline rates side by side: **Game win rate** (over decided + drawn games) and **Match win rate**. A match (one recorded lobby) is scored by majority game result — more game wins than losses = a match win, more losses = a match loss, tied = a *split*; splits are excluded from the match-rate denominator. The header also shows a static pilot count and last-played, plus a **Decks** button.
* **Decks** (modal) — a mini repo of the team's decks for this archetype: every team-folder deck whose leader + base group matches (commons collapse by hp+color, so different common bases of the same group are the same archetype). Each row shows the leader/base thumbnails, a deck link, a "Created by …" subline, and **Copy link** + **Share image** buttons (the latter opens the deck's share-image generator). No win/loss stats — it's a deck list, not pilot stats. The detail page has a prominent **Matches / Card stats** toggle right under the header; the **header and filter bar persist** across both, so switching only swaps the body below.

**Matches** (the default) shows:

* **Win/loss over time** (left) and the **matchup radar** (right), side by side. Both are **filter-aware** (they recompute from the same filtered game set as the replay list) and **interactive**: clicking a radar axis sets the opponent-leader filter (click again to clear), and clicking a point on the win/loss chart sets the date filter to that bucket's window. The radar always renders even with a small sample. (The win/loss timeline ignores the *date* filter so it stays a full, clickable series — clicking a point is what sets the date.)
* **Replays by opponent** — per-opponent bucket accordions, each expanding to its games (replay links). A filter bar above them narrows the list instantly:
  * **Opponent leader** typeahead and **Pilot** typeahead (single-select). Each leader is listed with the set it was printed in — `Ahsoka Tano (TWI)` — so two printings of the same character are told apart.
  * **Wins** / **Losses** checkboxes — check one or both to restrict by result (leaving both unchecked shows everything).
  * **Date** — macros (All / 7d / 14d / 21d / 30d) or a custom from–to range. Each accordion header's record (W–L and win %) recomputes for the active filters.

**Card stats** shows the per-card **Card performance** panel — each card's win rate by stage (in deck / played / resourced / discarded), framed against the archetype's win rate, with Heatmap / Bars / Scatter / Movers views (see [Card performance](/docs/battle-log/battle-log.md#card-performance)). Aggregated across every pilot; leader and base excluded. Because the filter bar is shared, the **same opponent / pilot / result / date filters apply here too**, and the stats re-aggregate live.

Replay links go to the per-game replay viewer. A member of **any team in the match's set** can watch the replay even when the deck lives in the recorder's *personal* folder — replay access follows the match's team set, so anything listed here is openable by members of that team. (Members of the recorder's teams that the match was *not* shared with cannot open it — that's the anti-bleed scoping.)

## What counts toward the rollup

* **Games whose match is scoped to this team** — i.e. the match is scoped to this team (set from the recorder's [recording scope](#recording-scope) when the match is recorded, then editable per-match). A match can be scoped to several teams at once, in which case its games count toward each of them.
* Games where `karabast` recorded a leader and a recognised base (rare card id or common rollup key).

Games with no captured leader, or a base that couldn't be classified, are counted as "hidden" and surfaced in the footer. Games whose match is scoped to no team (the recorder had no team, or a multi-team user who hasn't declared a set) don't appear in any team's rollup.

## Recording scope

The set of teams a new match starts scoped to comes from the teams the user has declared in their **Recording scope** checkbox list. It's intersected with the user's current memberships, so a team they've since left silently drops out.

* **No teams** → empty set (the match saves but counts toward no team).
* **All teams unchecked** → empty set — explicit opt-out works for everyone, including single-team users.
* **One or more checked** → that set.

Joining a team auto-adds it to the user's recording scope (opt-out: they can uncheck it on `/teams`).

The set is seeded only when a match is **first created**, so re-POSTs / later Bo3 games in the same lobby don't undo edits. After the fact, the match owner can **add or remove teams** on the match's replay page ("Visible to teams") or from the personal **Battle Log** top-nav tab — both changes affect which teams can open the replay and which teams' rollups it counts toward. Changing the `/teams` set only affects **future** recordings.

You can only add a team you belong to (no sharing into teams you're not on); removing is always allowed for the match owner.

### Orphaned matches

When the recording scope excludes a team deck's own team, that match becomes **orphaned** — its `deckId` is preserved but the team deck's Battle Log doesn't show it. The recording user finds it on their personal [Battle Log](/docs/battle-log/battle-log/battle-log-tab.md) tab and can **assign** it to the team there, which adds the team to the scope set and makes it appear in the team's Battle Log and rollups.

## Dashboard: headline KPIs

The team home dashboard's top KPI strip — **Games logged** and **Team win rate** — reports the team's record **against the field**, i.e. games against non-teammates. Internal games (two teammates who played each other) are excluded so that scrimmaging within the team doesn't drag the win rate toward 50% (every internal game is one teammate's win and the other's loss).

This is broader than the archetype rollup's mirror exclusion. The rollup only drops **same-deck mirrors** (both teammates on one shared team deck), so per-archetype win rates still include teammates who faced off on *different* decks (a deck beating a teammate's deck is real per-deck data). The headline KPIs additionally drop those different-deck internal games: any game recorded by **two or more team members** is internal.

Internal games aren't lost — they're surfaced as their own stat under [Teammate matchups](https://github.com/acousineau/swu-deck-visualizer/tree/main/docs/howto/teammate-matchups.md).

> **Limitation:** only *double-recorded* internal games are detectable. If just one of the two teammates recorded the game, it's a single row whose opponent is only a handle string, so it can't be told apart from a game against the field and still counts toward the headline.

## Dashboard: win/loss over time

The team home dashboard shows a **Win/loss over time** line chart. Each line is one archetype, and its value is that period's **net record** (wins minus losses) — a point above the line is a deck that won for the team that period, below it one that lost. Buckets auto-scale to the span of the data (daily → weekly → monthly) and follow **your own time zone**, so late-night games count on the day they were played. Each label names where its bucket **starts**, so hover a point to see the full span it covers.

By default it plots the team's **top 5 archetypes** by games. A team **ADMIN/OWNER** sees an **Archetypes** picklist (the slider button in the card header) to choose exactly which archetypes are charted, up to 8. That selection is **saved on the team** and shared with everyone — so the whole team sees the lines their admins curated. Regular members see the chart read-only, without the picklist.

It uses the same team-scope + mirror-exclusion rules as the archetype rollup above.

## Dashboard: Win rate by archetype + Most played

Below the timeline, two side-by-side cards summarize the team's archetypes — both keyed by **leader + base** archetype (commons collapse to their fungible class), each row showing the leader and its base label:

* **Win rate by archetype** — archetypes with **≥ 10 decided games**, ranked by win %.
* **Most played** — every archetype ranked by games played (no minimum).

Each card shows the **top 5** and reveals **one additional page** (up to 10) with **Show more** — the second page loads up front, so the reveal is instant. Anything past two pages isn't surfaced here; the Battle Log is the full list. Both lists collapse back to the first page when the [stats period](/docs/teams/team-battle-log/team-stats-periods.md) selection changes.

Every row links to that archetype's [Battle Log detail page](#archetype-detail). Once a card is **fully expanded** (no more pages to reveal), a hint appears at the bottom of that card linking to the team Battle Log itself — the place to drill into matchups and game-by-game results.

## Permissions

Same as the rest of the team feature: any team member can view, regardless of role. Non-members can't see a team's Battle Log.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://swu-forge.gitbook.io/docs/teams/team-battle-log.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
