Command / Villages
Villages¶
Compare captured villages across the workspace, filter by map distance and maintain manual village tags.
At a glance¶
Product route: /workspaces/{workspace_id}/villages.
Who can open this page: collection. Opening collection pages requires enabled entitlement and verified membership, including for the owner. A non-owner needs active membership and the collection grant; the owner bypasses grant checks only after verification.
Primary data owners: backend-derived, extension-collected, roster-ingest, signed-in-member, workspace-manager. Values reflect recorded data at page load; they are not a live view of Travian.
What you see¶
The table shows Tribe, Account, Village with coordinates, Distance, Off, Deff, Rams, Catas, Update and Village tags, followed by Note only when you can view manager notes. Account opens Account Villages; village opens the external Travian map. Tribe icons cover Romans, Teutons and Gauls; an unknown tribe displays ?. Distance is a dash without an origin and otherwise has one decimal. Off and Deff are crop upkeep, not combat points. Rams/Catas are raw siege counts with compact number formatting. Update prints the captured timestamp to the minute. The account note is repeated on each village; an empty note displays an em dash. Alliance, population, Tournament Square and Treasury are not displayed columns here.
In Trapitan, enter Search villages to match account, village or coordinate text; choose All tribes, Romans, Teutons or Gauls; enter origin coordinates such as (12|-34) and a nonnegative Max distance in fields. Choose Apply filters. Typing alone does not apply village filters. Origin alone shows distances; distance alone does not restrict rows. Both valid inputs apply the inclusive maximum-distance test.
All labelled data headers except Tribe toggle sorting; active header arrows show direction. Default is newest Update first. Previous/Next retain current visible filters and sort, with 50 rows by default. Footer shows row range, total and page count. Tags open a checkbox menu: choose defaults wwk, wwr, work hammer, deffender, scouter, ghost or workspace-defined tags. Changed selection saves when the menu closes; a manual chip’s remove control saves immediately. Automatic tags are disabled selections and cannot be removed. Editable chips show automatic tags first, even though the backend combined-label calculation returns manual tags first.
Who fills in each field¶
| Field or data | What it means | Who fills it in | Can it be changed here? | When it updates |
|---|---|---|---|---|
| Village, account and coordinates | Captured village name/coordinates and linked workspace account; village links open the game map and account links open Account Villages. Alliance and population are not columns here. | signed-in-member, extension-collected |
Read-only | Page load from latest recorded values |
| Off/Deff crop upkeep | Configured off/deff unit role flags weight counts by base crop upkeep; independent from combat strength. | backend-derived |
Read-only | Page load from latest recorded values |
| Tags | Default/custom manual tags plus read-time artifact-size and cata-point tags; automatic tags are read-only. | signed-in-member, workspace-manager, backend-derived |
Verified collection for manual values | Manual tag submit / current artifacts and snapshots |
| Distance filter | Distance in fields from an entered origin, displayed to one decimal; no origin shows a dash. Maximum-distance filtering requires both a parsed origin and distance. | signed-in-member, backend-derived |
Viewer enters origin/distance filters; calculated value is read-only | Explicit Apply filters submit |
| Last update | Recorded observation freshness; missing/stale capture is not live game status. | extension-collected, backend-derived |
Read-only | Page load from latest recorded values |
| Rams and Catas | Raw siege counts split by seeded siege-unit name, distinct from Off/Deff crop upkeep. | extension-collected, backend-derived |
Read-only | Page load from latest recorded values |
| Tribe | Roster tribe icon for Romans, Teutons or Gauls; unknown tribe shows ?. | roster-ingest |
Read-only | Roster refresh, visible on page load |
| Note | Account manager note repeated on its village rows; hidden and redacted without view_manager_notes. | workspace-manager |
Read-only here; edit on Members | Manager note change, visible on page load |
Calculations¶
Off and Deff in this table are crop upkeep per hour. Combat strength is a separate measure calculated from the same counts; the combat cards below explain the distinction, not additional visible columns. The active coefficient dataset defaults to tl-base-v1; the configured version can change. No hero bonuses, smithy upgrades or crop-upkeep reductions are included. Classification never changes the coefficient role flags.
Base offensive combat strength¶
Calculation ID: combat.offense. Attack coefficient total for combat-class troops; excludes smithy/hero upgrades.
Rule: Sum count*attack only for coefficient slots whose unit_class equals combat. Siege/admin/expansion do not contribute. Current Members/Villages Off columns show grain instead; this entry explains the distinct combat measure used by intelligence read models, not a second visible grain column.
| Input | Who fills it in | Unit | Required or optional | Fallback |
|---|---|---|---|---|
| counts by slot | extension-collected |
troops | Optional | Missing slot =>0; counts<=0 contribute nothing |
| Versioned tribe coefficients | backend-derived |
attack/defense points, crop per troop and role flags | Optional | Missing/unseeded tribe coefficient mapping => all-zero numeric result; active version configuration selects dataset |
Output unit: base attack points. Precision: Exact integer. Rounding: No rounding. Clamping: No output clamp. Time zone: not-applicable.
Edge cases: Unknown/Nature/Natars/unseeded tribes produce zero. Nonpositive counts ignored. The current Account Villages screen shows counts, not combat columns.
Canonical implementation: compute_strength. Non-canonical mirrors: None registered.
Calculation source references
- compute_strength —
src/trapitan/intelligence/calculator.py - CoefficientSet —
src/trapitan/intelligence/calculator.py - COMBAT_CLASS —
src/trapitan/intelligence/calculator.py - SIEGE_CLASS —
src/trapitan/intelligence/calculator.py - BASIS —
src/trapitan/intelligence/calculator.py - load_coefficients —
src/trapitan/intelligence/calculator.py - IntelligenceService._coefficients_for_tribe —
src/trapitan/intelligence/service.py - Settings.active_coefficient_version —
src/trapitan/core/config.py
Base defensive combat strength¶
Calculation ID: combat.defense. Sum of infantry and cavalry defense components from every coefficient slot.
Rule: Sum countdef_infantry and countdef_cavalry for every positive coefficient slot, then def_total=def_infantry+def_cavalry; includes all classes and excludes smithy/hero upgrades. Current Off/Deff columns use grain totals rather than these points.
| Input | Who fills it in | Unit | Required or optional | Fallback |
|---|---|---|---|---|
| counts by slot | extension-collected |
troops | Optional | Missing slot =>0; counts<=0 contribute nothing |
| Versioned tribe coefficients | backend-derived |
attack/defense points, crop per troop and role flags | Optional | Missing/unseeded tribe coefficient mapping => all-zero numeric result; active version configuration selects dataset |
Output unit: base defense points. Precision: Exact integer. Rounding: No rounding. Clamping: No output clamp. Time zone: not-applicable.
Edge cases: This is the sum of components, not their average or opponent-dependent weighted defense. Unknown tribe and missing slots contribute zero.
Canonical implementation: compute_strength. Non-canonical mirrors: None registered.
Calculation source references
- compute_strength —
src/trapitan/intelligence/calculator.py - CoefficientSet —
src/trapitan/intelligence/calculator.py - COMBAT_CLASS —
src/trapitan/intelligence/calculator.py - SIEGE_CLASS —
src/trapitan/intelligence/calculator.py - BASIS —
src/trapitan/intelligence/calculator.py - load_coefficients —
src/trapitan/intelligence/calculator.py - IntelligenceService._coefficients_for_tribe —
src/trapitan/intelligence/service.py - Settings.active_coefficient_version —
src/trapitan/core/config.py
Off/Deff crop upkeep¶
Calculation ID: grain.offense-defense. Separate configured role-weighted crop totals.
Rule: For each positive count, add count*grain_upkeep to offensive_grain if counts_as_off and to defensive_grain if counts_as_deff. Flags are independent: a slot may contribute to both or neither. Members/Villages DTO strength properties carry these grain totals. Base upkeep excludes reductions.
| Input | Who fills it in | Unit | Required or optional | Fallback |
|---|---|---|---|---|
| counts by slot | extension-collected |
troops | Optional | Missing slot =>0; counts<=0 contribute nothing |
| Versioned tribe coefficients | backend-derived |
attack/defense points, crop per troop and role flags | Optional | Missing/unseeded tribe coefficient mapping => all-zero numeric result; active version configuration selects dataset |
Output unit: crop upkeep per hour. Precision: Exact integer. Rounding: No rounding. Clamping: No output clamp. Time zone: not-applicable.
Edge cases: Does not use attack/defense combat coefficients. No artifact/trough/upkeep reductions are applied. Role flags come from the active coefficient dataset, not member classification. Compact UI formatting: abs>=1million =>one decimal M, abs>=1000 =>one decimal K; trim .0; below1000 truncate to integer. Numeric derivation remains exact. None formats0.
Canonical implementation: compute_strength. Non-canonical mirrors: None registered.
Used on: Villages, Members, Artifacts Registry
Calculation source references
- compute_strength —
src/trapitan/intelligence/calculator.py - CoefficientSet —
src/trapitan/intelligence/calculator.py - COMBAT_CLASS —
src/trapitan/intelligence/calculator.py - SIEGE_CLASS —
src/trapitan/intelligence/calculator.py - BASIS —
src/trapitan/intelligence/calculator.py - load_coefficients —
src/trapitan/intelligence/calculator.py - IntelligenceService._coefficients_for_tribe —
src/trapitan/intelligence/service.py - GRAIN_BASIS —
src/trapitan/intelligence/calculator.py - IntelligenceService.list_members —
src/trapitan/intelligence/service.py - IntelligenceService.list_villages —
src/trapitan/intelligence/service.py - Settings.active_coefficient_version —
src/trapitan/core/config.py - format_compact_number —
src/trapitan/web/formatting.py - _trim_decimal —
src/trapitan/web/formatting.py
Wrapped map distance¶
Calculation ID: map.wrapped-distance. Shortest Euclidean distance on a toroidal Travian world.
Rule: size=2*radius+1; dx=min(abs(x1-x2),size-abs(x1-x2)); same for dy; hypot(dx,dy). Default radius200 means401coordinates per axis, so -200 and200 are adjacent.
| Input | Who fills it in | Unit | Required or optional | Fallback |
|---|---|---|---|---|
| Source/destination coordinates | signed-in-member, roster-ingest, extension-collected |
map coordinates | Required | Required; no fallback |
| radius | backend-derived |
fields | Optional | 200 |
Output unit: fields. Precision: Floating point hypot. Rounding: No rounding. Clamping: No output clamp. Time zone: not-applicable.
Edge cases: Same coordinate returns zero. Assumes coordinates in the configured world; this helper does not validate/wrap arbitrary out-of-world values. Browser radius null also defaults200; mirrors are separately hashed and not proof of equivalence.
Canonical implementation: travian_distance. Non-canonical mirrors: Non-canonical mirror 1, Non-canonical mirror 2
Used on: Villages, Def Calls, Counter Scout Plan, Artifacts Registry, Operation Dashboard
Calculation source references
- travian_distance —
src/trapitan/core/travian.py - src/trapitan/web/static/js/travian-distance.js —
src/trapitan/web/static/js/travian-distance.js(non-canonical mirror) - extension/chromium/lib/def-call-dispatch.js —
extension/chromium/lib/def-call-dispatch.js(non-canonical mirror)
Village automatic tags¶
Calculation ID: village.auto-tags. Current artifact-size and siege threshold labels, following manual tags.
Rule: artifact size small/large/unique =>s.arti/l.arti/u.arti; catapults>=configured cata threshold =>cata point. Manual labels normalized defaults-first then custom; automatic labels follow fixed order s.arti,l.arti,u.arti,cata point. No automatic tag is stored/edited here.
| Input | Who fills it in | Unit | Required or optional | Fallback |
|---|---|---|---|---|
| artifact_size | extension-collected |
size label | Optional | Missing/unrecognized => no artifact tag |
| catapults | backend-derived |
catapult count | Required | Required; no fallback |
| cata_threshold | backend-derived |
units | Optional | Configured default60 |
| Manual values/custom label map | signed-in-member, workspace-manager |
tags | Optional | Empty manual list; unknown stored label falls back raw value |
Output unit: ordered labels. Precision: Exact ordered labels. Rounding: No rounding. Clamping: No output clamp. Time zone: not-applicable.
Edge cases: Threshold equality adds cata point. Unknown artifact size adds none. Current troop table tags are read-only; manual edits live on Villages.
Canonical implementation: auto_tag_labels. Non-canonical mirrors: None registered.
Used on: Troops Overview, Villages, Account Villages
Calculation source references
- auto_tag_labels —
src/trapitan/intelligence/village_tags.py - combined_tag_labels —
src/trapitan/intelligence/village_tags.py - ARTIFACT_SIZE_TAGS —
src/trapitan/intelligence/village_tags.py - CATA_POINT_TAG —
src/trapitan/intelligence/village_tags.py - _AUTO_ORDER —
src/trapitan/intelligence/village_tags.py - _AUTO_ORDER_INDEX —
src/trapitan/intelligence/village_tags.py - manual_tag_labels —
src/trapitan/intelligence/village_tags.py - normalize_manual_tags —
src/trapitan/intelligence/village_tags.py - order_values —
src/trapitan/intelligence/village_tags.py - DEFAULT_MANUAL_TAGS —
src/trapitan/intelligence/village_tags.py - DEFAULT_TAG_LABELS —
src/trapitan/intelligence/village_tags.py - Settings.cata_point_threshold —
src/trapitan/core/config.py
Rams and catapults¶
Calculation ID: siege.split. Separate raw siege unit counts from combat strength.
Rule: For positive counts where unit_class==siege, a seeded unit_name containing ram case-insensitively increments rams; every other siege unit increments catapults. These raw counts are used in derived intelligence/planning and auto tags, not added to offensive strength.
| Input | Who fills it in | Unit | Required or optional | Fallback |
|---|---|---|---|---|
| counts by slot | extension-collected |
troops | Optional | Missing slot =>0; counts<=0 contribute nothing |
| Versioned tribe coefficients | backend-derived |
attack/defense points, crop per troop and role flags | Optional | Missing/unseeded tribe coefficient mapping => all-zero numeric result; active version configuration selects dataset |
Output unit: siege units. Precision: Exact integer. Rounding: No rounding. Clamping: No output clamp. Time zone: not-applicable.
Edge cases: Translated UI labels are not used to detect rams. Unknown coefficients yield zero. Off/Deff crop flags can independently include siege upkeep. Compact UI formatting: abs>=1million =>one decimal M, abs>=1000 =>one decimal K; trim .0; below1000 truncate to integer. Numeric derivation remains exact. None formats0.
Canonical implementation: compute_strength. Non-canonical mirrors: None registered.
Used on: Villages, Members, Artifacts Registry
Calculation source references
- compute_strength —
src/trapitan/intelligence/calculator.py - CoefficientSet —
src/trapitan/intelligence/calculator.py - COMBAT_CLASS —
src/trapitan/intelligence/calculator.py - SIEGE_CLASS —
src/trapitan/intelligence/calculator.py - BASIS —
src/trapitan/intelligence/calculator.py - load_coefficients —
src/trapitan/intelligence/calculator.py - IntelligenceService._coefficients_for_tribe —
src/trapitan/intelligence/service.py - _is_ram —
src/trapitan/intelligence/calculator.py - Settings.active_coefficient_version —
src/trapitan/core/config.py - format_compact_number —
src/trapitan/web/formatting.py - _trim_decimal —
src/trapitan/web/formatting.py
Freshness and updates¶
Village rows are current captured overviews for workspace game accounts, joined to roster tribe data; this is not a complete roster-only village listing. Collector captures replace stored current values; imported roster updates change resolved tribe metadata. Update records observation time, not your page visit or tag edit. Reload or apply filters to read current rows. Manual tag writes update just the cell; artifact/catapult auto labels are derived again at read time. Stored timestamp formatting does not convert to your personal clock.
Actions and permissions¶
Who can take action / Who can perform each action: the following gates are separate from page visibility. Hidden navigation alone never authorizes a request.
| Action | Actor | Permission |
|---|---|---|
| Edit manual tags | signed-in-member |
Verified collection, enabled entitlement and same origin; labels filtered to allowed workspace/default vocabulary; stored by workspace and coordinate without a collected-village existence check |
| Apply filters | signed-in-member |
Verified collection and enabled entitlement; invalid coordinate or negative/invalid distance silently omits that filter; no power-filter controls on Villages |
In Trapitan, Apply filters, sort headers and Previous/Next make collection-authorized page reads. Manual tag selection needs no manager-only tag-edit grant beyond collection. The server checks enabled entitlement, verification, same origin and allowed workspace/default labels. Writes are keyed by the authorized workspace and submitted coordinate; the current handler does not verify that this coordinate belongs to a collected village. The visible controls use the displayed village’s coordinate. Unknown labels are filtered out. Auto labels remain derived. Notes cannot be edited here; use Members with its note grants. The UI offers existing workspace tag options, with no custom-tag creation input here.
States and edge cases¶
No rows without filters shows No villages collected yet and explains that the extension must collect an overview. With filters it says No villages match your filters. Invalid coordinate syntax and invalid/negative distance silently omit their respective constraints; this is not a displayed validation error. Sorting by Distance without a valid origin falls back to Update. Hidden notes are also redacted server-side; note sorting without the view grant falls back to Update. Unknown sort keys fall back to Update, and directions other than asc become descending. Empty pages show disabled pagination links. Collector gaps or unknown coefficients can yield zero derived values without proving an empty army. An unauthorized or cross-origin tag write is rejected; the tag cell has no dedicated error message.
Related pages¶
Source references¶
Source reviewed: 2026-10-05
Source references
Stable page ID: command.villages.
src/trapitan/api/routes/web.pysrc/trapitan/web/templates/villages.htmlsrc/trapitan/web/templates/partials/villages_table.htmlsrc/trapitan/web/formatting.pysrc/trapitan/intelligence/repository.pysrc/trapitan/intelligence/service.pysrc/trapitan/web/templates/partials/village_tags_cell.htmlsrc/trapitan/web/static/js/village-tags.jssrc/trapitan/authorization/dependencies.pysrc/trapitan/authorization/policy.pysrc/trapitan/api/routes/guards.py