Interactive specification
One file, a whole competition.
FSDB is the XML database FS and Airscore write: every task of a comp, its turnpoints, its start gates and — in a scored file — every pilot's result. This page covers the half that defines the flying, and the part that trips up every importer: working out which turnpoint is the start, the end of the speed section, and the goal.
What an FSDB holds
FSDB — "FS database" — is the native file of FS (the long-standing hang-gliding and paragliding competition scoring suite) and of Airscore, its open-source successor. Unlike every other task format, one .fsdb is not one task: it is an entire competition — its identity, its dates, all of its tasks, and in a scored file the full pilot list with every result.
That makes it the format a comp organiser hands you at the end of the week, and the reason an FSDB importer returns a list. A five-task comp yields five tasks, each needing its own name and date.
FsTaskDefinition describes the flying — geometry, gates, deadlines. FsParticipants / FsTaskScoreParams / FsParticipant carry results. A file that has only been defined and not yet flown contains the first half alone, and is completely valid. Never require the scoring elements.Versions in the wild
The root element carries a version attribute (3.x for modern FS). The task-definition shape described here has been stable since FS 2018 and is what Airscore reads and writes. Older 2000s-era files exist with different attribute spellings; they are rare enough that the pragmatic move is to reject them loudly rather than guess.
The element tree
Fs [version] └─ FsCompetition [name, from, to, location] ├─ FsCompetitionNotes ├─ FsTasks │ └─ FsTask [id, name] ← repeats, one per task │ ├─ FsTaskState [task_state, cancel_reason] │ ├─ FsTaskScoreParams [task_distance, …] // scoring, optional │ └─ FsTaskDefinition [ss, es, goal, groundstart] │ ├─ FsTurnpoint [id, lat, lon, altitude, radius, open, close] │ └─ FsStartGate [open] // 0..n └─ FsParticipants // pilots + results, optional
Everything that matters is an attribute. FSDB has almost no element text content — if you are reading textContent anywhere, you are on the wrong track.
FsTask, FsTurnpoint and FsStartGate repeat. Most XML-to-object libraries collapse a single occurrence into an object rather than a one-element array — a one-task comp then crashes an importer that worked on a five-task one. Declare those three names as always-arrays.The four attributes that define the race
| Attribute | Type | Meaning |
|---|---|---|
ss | integer | Start of speed section — the 1-based index of the turnpoint that is the SSS. Absent or 0 means the task has no speed section. |
es | integer | End of speed section — 1-based index of the ESS. |
goal | string | CYLINDER or LINE — the shape of the final turnpoint's zone. |
groundstart | 0 / 1 | Whether the clock runs from a ground start rather than a gate. |
qnh_setting | number | QNH used for altitude checks, hPa. Advisory. |
ss and es are indices, not names. They point into the FsTurnpoint list, counting from 1. This is the single most common FSDB import bug: read them as zero-based and every task starts one turnpoint too early.There is no attribute naming the takeoff, and none naming the goal. Both are positional — see §04.
Which turnpoint is which
A turnpoint's role is derived from its position and the two index attributes. The rules, in the order that resolves conflicts correctly:
- Index 1 is the takeoff.
- Index
ssis the SSS, whenssis present and greater than zero. - Index
esis the ESS. - The last index is the goal — and it wins over everything above.
- Everything else is a plain turnpoint.
The precedence in rule 4 is not decoration. In a race that ends at the goal line, es commonly points at the last turnpoint — the ESS and the goal are the same cylinder. Applying the rules in any other order leaves you with a task that has an ESS and no goal.
ss, es → rolesA turnpoint's attributes
| Attribute | Unit | Meaning |
|---|---|---|
id | string | Waypoint name — usually "CODE Name" (B02 Aujour). Not a numeric id. |
lat / lon | degrees | Signed decimal WGS84. Legacy files may use sexagesimal "DD MM SS.ss" — see §08. |
altitude | metres | Terrain elevation at the point. |
radius | metres | Cylinder radius. |
open / close | ISO datetime | The turnpoint's own window. Present on some points, absent on others. |
Start gates, deadlines and the flying day
FSDB is the only task format that carries full datetimes with a UTC offset, not bare times of day:
<FsTurnpoint id="B02 Aujour" lat="44.28500" lon="5.74000" altitude="1834" radius="2000" open="2022-07-06T12:30:00+00:00" close="2022-07-06T19:00:00+00:00"/> <FsStartGate open="2022-07-06T12:30:00+02:00"/>
That offset is a gift: it makes the flying date recoverable, and it lets every gate convert to a true UTC HH:MM:SSZ — the same canonical form XCTrack and Airtribune use. An FSDB task and its Airtribune twin therefore reduce to the same times, and deduplicate to one library entry.
12:30:00+02:00 is 10:30:00Z. Slicing the time substring out of the string keeps the wall-clock digits and silently shifts the task by the offset — and because the result still looks like a plausible gate, nothing downstream complains.Race, elapsed time, or open distance
| File says | Task is | Gates |
|---|---|---|
ss present, ≥ 1 FsStartGate | Race to goal | Each FsStartGate open is a gate. |
ss present, no FsStartGate | Elapsed time | The clock starts per pilot; fall back to the SSS turnpoint's open. |
no ss | Open distance / free | No speed section at all. |
Start direction
FSDB does not record whether the start cylinder is entered or exited. The FS convention recovers it from geometry: when the takeoff and the SSS share a position, the start is an EXIT (you launch inside the cylinder and leave it); otherwise it is an ENTER. That is what Airscore's own importer does, and it is right often enough to be the sane default — but it is an inference, not data.
The task deadline comes from the close attribute of the ESS turnpoint.
Every element and attribute
Search by element, attribute or meaning, or narrow by category.
Paste an FSDB, read the tasks out
Every FsTask is listed with its turnpoints, the roles derived from ss/es, and its gates converted to UTC. Parsed with the browser's own XML parser — nothing is uploaded.
Where FSDB imports go wrong
ssandescount from 1. The one bug that produces a task which looks almost right.- Goal beats ESS. Apply the last-index rule after the
esrule, or a task whose ESS is the final cylinder ends up with no goal. - Datetimes carry an offset. Convert to UTC; never slice the time out of the string.
- Coordinates may be sexagesimal. Older files write
lat="44 16 40.8"— degrees, minutes, seconds, space-separated. Sniff for whitespace before callingparseFloat, which would happily return44. - Negative sexagesimal is sign-on-degrees.
"-5 30 0"is −5.5°, not −5 + 0.5. Take the magnitude of all three components and apply the sign of the first. - One task can be malformed without the file being malformed. Skip an unreadable
FsTaskand keep the rest — a cancelled or half-defined task is normal in a real comp file. - Scoring elements are optional. A defined-but-not-yet-flown comp has no
FsParticipants. Do not treat that as an error. - Bound the file. A scored FSDB with a few hundred pilots runs to megabytes of results you do not need. Cap the input size and the task count. We-Fly allows 4 MB and 60 tasks.
What We-Fly reads
We-Fly imports .fsdb in the competition-task library. One upload can create many tasks; each is named "<competition> — <task>" and dated from the first turnpoint window, so a whole comp week lands as a set of dated, linkable tasks.
| Behaviour | |
|---|---|
| Direction | Import only. We-Fly exports tasks as .xctsk, never as FSDB. |
| Size limit | 4 MB per file, 60 tasks per file. |
| Ignored | All scoring elements — pilots, results, formulas. |
| Dedup | Because gates convert to true UTC, an FSDB task matches the same task imported from Airtribune or XCTrack and is stored once. |
How the four task formats map onto one model — and what each loses — is in the competition-task formats guide.