Skip to content
Skip to documentation content

Defense / Def Calls

Def Calls

Coordinate defensive troop requests, record contributions and compare dispatch deadlines from captured villages.

At a glance

Product route: /workspaces/{workspace_id}/def-calls.

Who can open this page: signed-in users with enabled workspace entitlement and verified membership, including the owner. Non-owners need active membership and collection; verified owners bypass the individual grant check, not entitlement or verification. Page viewing does not require a current linked-account resolver; certain write actions do. Navigation visibility never grants endpoint access.

What you see

The call table shows Snipe, Player Name, Village, Troops pushed / needed with progress, Coords, Send Before, reinforcement Link, Update and manager-only Delete. Player and village links open the game map. Call opens the manager create dialog: Coordinates or Link, Send Before, positive integer Troops Needed and optional Snipe Call. Location and needed are required; Send Before is optional. The create dialog initially selects today at midnight in browser-local time; clear it for no deadline. Call configuration is not editable after creation.

Dispatch Troops has Account, Add village, Min Def and Show all rows controls. The account selector can browse workspace accounts; it is initially the current account, with first-account fallback when resolution fails. Min Def compares calculated defensive combat points (infantry plus cavalry defense), not crop upkeep. Rows show source Village, Target Village, Last Send Time, Timer, selected troop icons/counts, game Send troops link and local Remove. Links open game pages for the reader to complete the action; Trapitan does not send troops automatically.

Who fills in each field

Field or data What it means Who fills it in Can it be changed here? When it updates
Destination and needed Roster destination player/village/coordinates, requested troop count, optional deadline and snipe flag. workspace-manager, roster-ingest manage_def_calls at creation; no configuration editor Creation
Pushed Absolute recorded troops total, shown against needed; progress width is clamped 0…100%. Update replaces the total, not an increment. signed-in-member, backend-derived collection with current linked account; nonnegative integer Save; positive delta alone records contribution activity
Dispatch village and troops Selected workspace account recorded troop counts/TS and configured defensive unit slots; other accounts can be selected. All defensive counts plus one slowest non-defensive escort are initially included. extension-collected, backend-derived Read-only data; account/village/Min Def controls select display Account selection reloads latest recorded villages
Travel and last send Wrapped travel at the slowest included troop speed; latest departure is deadline minus travel. backend-derived Read-only Dispatch render; timer ticks each second

Calculations

Wrapped map distance

Calculation ID: map.wrapped-distance. Shortest Euclidean distance on a toroidal Travian world.

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 supplies it Unit 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: fields. Precision: Floating point hypot. Rounding: No rounding. Clamp: No output clamp. Timezone: not-applicable.

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.

For each axis choose the shorter of the direct difference and the difference across the map edge, then take the Euclidean length of those two distances. On the default map coordinates lie in −200…200. For synthetic (−200|0) to (200|0), the distance is one field. This helper is not an out-of-bounds validator.

Canonical source and dependencies: see the reviewed references below. Mirrors are independent copies, not an equivalence guarantee.

Calculation source references - Canonical: `src/trapitan/core/travian.py` — `travian_distance`. - Non-canonical mirror: `src/trapitan/web/static/js/travian-distance.js` — ` function travianDistance(`. - Non-canonical mirror: `extension/chromium/lib/def-call-dispatch.js` — `function travianDistance(`.

Used on: Villages, Def Calls, Counter Scout Plan, Artifacts Registry, Operation Dashboard.

Server troop movement multiplier

Calculation ID: server.movement-multiplier. Map hostname speed labels to actual troop movement scaling.

Regex .x(\d+). yields server label (default1); mapping {1:1,2:2,3:2,5:2,10:4}, unknown label=>1. Movement is not linear with server speed.

Input Who supplies it Unit Optional / fallback
server_domain backend-derived canonical hostname Required; Required; no fallback
UNIT_SPEEDS backend-derived fields/hour per tribe slot Optional; Unsupported tribe uses Roman speed table

Output: speed multiplier. Precision: Exact integer. Rounding: No rounding. Clamp: No output clamp. Timezone: not-applicable.

No xN label defaults1. Unknown speed labels fall back1. Browser/extension dispatch consumes the backend multiplier, rather than copying the hostname map.

A hostname containing .x3. gives movement ×2; .x10. gives ×4. Missing or unrecognized labels give ×1. The base speed is measured in fields per hour. Roman t1…t10 speeds are 6,5,7,16,14,10,4,3,4,5; Teuton 7,7,6,9,10,9,4,3,4,5; Gaul 7,6,17,19,16,13,4,3,5,5. Unsupported tribe uses the Roman table. Dispatch uses the slowest included troop; Counter Scout uses the manually chosen attacker unit and the scouter tribe’s scout (Roman slot4 speed16; Teuton slot4 speed9; Gaul slot3 speed17).

Canonical source and dependencies: see the reviewed references below. Mirrors are independent copies, not an equivalence guarantee.

Calculation source references - Canonical: `src/trapitan/intelligence/service.py` — `parse_server_speed`. - Dependency: `src/trapitan/intelligence/service.py` — `_SERVER_SPEED_RE`. - Dependency: `src/trapitan/intelligence/service.py` — `troop_speed_multiplier`. - Dependency: `src/trapitan/intelligence/service.py` — `_TROOP_SPEED_MULTIPLIERS`. - Dependency: `src/trapitan/intelligence/service.py` — `UNIT_SPEEDS`. - Dependency: `src/trapitan/intelligence/service.py` — `unit_speeds_for_tribe`. - Non-canonical mirrors: none registered.

Used on: Def Calls, Counter Scout Plan, Operation Dashboard.

Tournament Square travel

Calculation ID: travel.tournament-square. Platform one-way travel seconds using slowest troop speed and TS after20fields.

d=wrapped distance; d==0 =>0 before speed validation; v=base_speedspeed_multiplier; v<=0 raises; d<=20 or TS<=0 =>3600d/v; otherwise3600(20/v+(d-20)/(v(1+0.1TS))). Caller chooses slowest present selected unit. Operation planner rounds one-way seconds to integer. Related extension farm-list variant uses0.2TS, clampsTS0..20, returns round-trip minutes and is not interchangeable with this platform formula.

Input Who supplies it Unit Optional / fallback
Coordinates signed-in-member, roster-ingest map coordinates Required; Required; no fallback
base_speed backend-derived fields/hour Required; Required; no fallback
speed_multiplier backend-derived multiplier Optional; 1
Tournament Square extension-collected, signed-in-member level Optional; 0

Output: one-way seconds. Precision: Floating-point seconds; planner uses integer seconds. Rounding: Python round(seconds) in planner; browser display varies: operation travel rounds minutes with minimum1 for positive travel, defense countdown floors absolute seconds. Clamp: No output clamp. Timezone: Travel duration independent of timezone.

Zero distance returns0 even with invalid speed. Unknown/empty speeds: platform raises on nonpositive speed; browser dispatch returns null, operation mirror Infinity. Farm-list mirror is a related divergent20% round-trip variant outside web guide scope; do not describe it as equal. No hero/artifact movement bonus is applied by these formulas.

Let d be distance in fields, v the base fields/hour multiplied by server movement, and L the source TS level. Convert hours to seconds by multiplying by 3,600. The first 20 fields use ordinary speed; only the remaining distance uses the factor 1+0.1L. At distance20 or TS0 there is no TS benefit. A synthetic distance30, speed10, multiplier1, TS10 takes 9,000 seconds (2½ hours). Def Calls uses fractional seconds internally and floors the absolute countdown; Counter Scout retains fractional travel for its timestamp calculation and floors only the displayed timer. No hero or artifact travel bonus is included.

Canonical source and dependencies: see the reviewed references below. Mirrors are independent copies, not an equivalence guarantee.

Calculation source references - Canonical: `src/trapitan/intelligence/service.py` — `travel_seconds`. - Dependency: `src/trapitan/intelligence/service.py` — `TS_BONUS_PER_LEVEL`. - Dependency: `src/trapitan/intelligence/service.py` — `UNIT_SPEEDS`. - Dependency: `src/trapitan/core/travian.py` — `travian_distance`. - Dependency: `src/trapitan/api/routes/web.py` — `create_operation_plan`. - Non-canonical mirror: `src/trapitan/web/templates/def_calls.html` — ` function travelSeconds(`. - Non-canonical mirror: `src/trapitan/web/static/js/operation-dashboard.js` — ` function planTravelSeconds(`. - Non-canonical mirror: `extension/chromium/lib/def-call-dispatch.js` — `function travelSeconds(`. - Non-canonical mirror: `extension/chromium/lib/farm-list-calculator.js` — `export function roundTripMinutes(`.

Used on: Def Calls, Counter Scout Plan, Operation Dashboard.

Freshness and updates

Calls load from recorded workspace rows on page entry and after create/update/delete. The rows endpoint lazily removes calls whose non-null Send Before is at or before backend UTC now; calls with no deadline persist. There is no background capture poll. Dispatch reloads on account selection; countdowns tick each second without refreshing troop captures. Send Before and Last Send Time display browser-local DD/MM/YYYY HH:MM:SS; local form input is converted to ISO UTC on submission. Troop counts and TS are latest recorded observations, not live availability.

Actions and permissions

Who can perform each action / Who can take action: the actor labels describe data responsibility; actual grants and action-specific guards decide access. Every feature request remains workspace-scoped and entitlement/verification-gated.

Action Actor Permission
Create call workspace-manager Verified manage_def_calls plus collection, current linked account, enabled entitlement and same origin; destination must resolve in workspace server roster; needed ≥1
Update pushed total signed-in-member Verified collection, current linked account, enabled entitlement and same origin; workspace-scoped call, pushed ≥0
Delete call workspace-manager Verified manage_def_calls, enabled entitlement and same origin; workspace-scoped call; no current-account dependency
Select account/villages, Min Def, local Remove / Show all rows signed-in-member Page collection access; these select/hide rows locally and never delete calls or troop observations

States and edge cases

No calls displays “No def calls yet.” A calls-load failure displays “Def calls could not be loaded.” No dispatch troops, unknown account, unavailable unit speeds or an account-load failure yields the empty dispatch state. A malformed location/amount or unmatched roster destination prevents creation; server errors remain in the dialog. Updating/deleting missing or cross-workspace calls is rejected.

To meet a deadline the browser removes the slowest troop types and retries, retaining the fastest type even if already late. A negative timer is an overdue suggestion, not proof that reinforcements can arrive in time. Missing/invalid deadline sends the full selection, shows a dash for Last Send Time, and anchors its negative countdown to render time minus travel. Zero distance gives zero travel before speed validation. Removing a dispatch row hides that source/call pair in browser storage; Show all rows resets hidden rows. A recorded pushed total may exceed needed; the displayed ratio retains that total while the progress bar stops at 100%.

Incoming Attacks, Counter Scout Plan, Troops Overview.

Source references

Stable page ID: defense.def-calls.

Source reviewed: 2026-10-07

Reviewed handlers, visible controls and producers - `src/trapitan/api/routes/web.py` — `def_calls_page`. - `src/trapitan/web/templates/def_calls.html` — bounded template/script region. - `src/trapitan/api/routes/web.py` — `_shell_context`. - `src/trapitan/api/routes/web.py` — `list_def_calls`. - `src/trapitan/api/routes/web.py` — `list_def_call_account_villages`. - `src/trapitan/api/routes/web.py` — `_purge_expired_def_calls`. - `src/trapitan/api/routes/web.py` — `_def_call_payload`. - `src/trapitan/web/templates/partials/def_call_modal.html` — bounded template/script region. - `src/trapitan/authorization/dependencies.py` — `require_workspace_permission`. - `src/trapitan/authorization/policy.py` — `authorize_workspace_action`. - `src/trapitan/authorization/policy.py` — `_authorize_from_database`. - `src/trapitan/authorization/policy.py` — `is_membership_verified`. - `src/trapitan/authorization/policy.py` — `_active_membership`. - `src/trapitan/authorization/policy.py` — `_is_workspace_entitled`. - `src/trapitan/authorization/policy.py` — `_has_active_permission`. - `src/trapitan/authorization/policy.py` — `WorkspaceAction`. - `src/trapitan/authorization/policy.py` — `GRANTABLE_ACTIONS`. - `src/trapitan/api/routes/web.py` — `create_def_call`. - `src/trapitan/api/routes/web.py` — `update_def_call_pushed`. - `src/trapitan/intelligence/service.py` — `IntelligenceService.get_account_dispatch_villages`. - `src/trapitan/api/routes/guards.py` — `is_same_origin`. - `src/trapitan/authorization/dependencies.py` — `require_current_workspace_travian_account`. - `src/trapitan/authorization/current_account.py` — `resolve_current_workspace_travian_account`. - `src/trapitan/api/routes/web.py` — `delete_def_call`.