kirby-campaign
The campaign entity layer's rules for the Kirby HERO System platform: teams, rosters, and the two-tier definition/instance merge.
No database, no HTTP, no tenancy. Zero dependencies.
Team is not side
A Team is an identity that persists between fights — you are a Sentinel on Tuesday and still one on Wednesday. A side is an alignment within one fight: who is shooting at whom right now.
They usually agree, and they must be able to disagree — a schism, a
temporary alliance against something worse, a mind-controlled turncoat. So
sides_from_teams is the default mapping, not an identity, and
assign_sides never overwrites a side someone already carries.
from kirby_campaign import Team, TeamMember, sides_from_teams
sentinels = Team(
id="sentinels", name="Sentinels of Dawn", team_type="hero",
members=(TeamMember("aurora", "leader"), TeamMember("bulwark")),
base_ids=("dawn-spire",),
)
sides_from_teams([sentinels])
# {'aurora': Side(id='sentinels of dawn', name='Sentinels of Dawn',
# team_id='sentinels'), 'bulwark': ...}
A Side is an object, not a string — Side.named folds case and spacing
into one identity, so "Golden" and "golden" are one army rather than
two. It lives in kirby-combat, because a free-for-all in an alley has
sides and no campaign at all.
The dependency runs one way
kirby-campaign sits above kirby-combat and imports it. The reverse must
never happen: if the engine imported this package, resolving an attack would
depend on knowing what a campaign is, dragging rosters and narrative prose
behind every roll. tests/test_independence.py asserts both halves.
Two tiers
A library definition is the authored or sourcebook canon; a campaign instance is a thin overlay of nullable overrides where NULL means inherit, plus instance-only state.
from kirby_campaign import effective_team
effective_team(definition, instance) # COALESCE(instance, definition)
COALESCE, not or: an override of "", 0, False or () is a
deliberate statement and is honoured. Only None inherits.
Bases are builds
Team.base_ids are opaque references and nothing here dereferences them. A
Base is built with the base-building rules and imported from HDC, the same
as a character — kirby-cost costs it, and in a fight its walls are terrain
with BODY and DEF. Only the edge belongs in the entity layer.
A note on content
The shape here is publishable. The teams are not.
Team exists as a first-class entity because villain teams do: the corpus sources are CV1–CV3 (Champions Villains Volumes 1–3, with CV2 a volume dedicated to villain teams) and Old School Enemies, and a team entry in those books is the book's prose. All of it is paid Hero Games material — local by default, published never. Every fixture and example in this repository uses an invented team for that reason.
Naming
Team.tactics is a paragraph about how a team fights. kirby_combat.tactics
is the doctrine catalogue that decides a combatant's action this Phase. They
are unrelated; this package holds neither.
Licence
PolyForm Noncommercial License 1.0.0. For personal, non-commercial use. Not affiliated with or endorsed by Hero Games.
Metadata
Release files for kirby-campaign 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| kirby_campaign-0.1.0.tar.gz | 20.0 kB | Without provenance | Details for kirby_campaign-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| kirby_campaign-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for kirby_campaign-0.1.0-py3-none-any.whl |
Total release size: 33.3 kB
Release files / kirby_campaign-0.1.0.tar.gz
| Download URL | kirby_campaign-0.1.0.tar.gz |
|---|---|
| Size | 20.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ef07e86294143ce9e8920dd223cf213e02ec4821dfd4200c8ed819f974aac128
|
|
BLAKE2b-256 checksum How to use checksums |
6768343d8e929f66a362c5581b049f82262a8613dcf3c0ea4c6f024c6d79c803
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Release files / kirby_campaign-0.1.0-py3-none-any.whl
| Download URL | kirby_campaign-0.1.0-py3-none-any.whl |
|---|---|
| Size | 13.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
fb2f94f622cf48fbb6fe2b81e4f6bfeb70afd329f7a3a2356a5f4719f90d74bd
|
|
BLAKE2b-256 checksum How to use checksums |
9ea2dcc3f36479807b7d86ffa37a9137ddfc8a8b53db4cc14448814389bd4c3e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Security for kirby-campaign 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.