Why the ZWO format sucks
ZWO is a workout file format used by Zwift, and it’s really really bad. Basically it’s a showcase of all the things not to do when designing a file format.
Here’s an example of a ZWO file:
Inconsistencies
The most basic inconsistency is in how names are written:
- Element names are
sometimes in lowercase (e.f.
<textevent>
), sometimes in snake case (e.g.<workout_file>
), sometimes camel case (e.g.<sportType>
), sometimes start case (e.g.<SteadyState>
). - Similarly with attributes:
PowerLow=
v/stimeoffset=
.
Then there are inconcistencies of forming names:
- In ramps a suffix is used:
PowerLow
andPowerHigh
, but in intervals a prefix:OnPower
andOffPower
. - The
On
andOff
prefixes are used for bothPower
(OnPower
/OffPower
) andDuration
(OnDuration
/OffDuration
), but not forCadence
(Cadence
/CadenceResting
).
Finally, specific to XML, the free-form text is sometimes as a content and sometimes as attribute value:
- As content:
<description>Some description here</description>
- As attribute:
<textevent message="Your message here" />
Misleading names
The previous things were just the surface. Often the names are misleading or just plain weird:
<IntervalsT>
- what does thisT
mean? No idea.Power="1.00"
- it’s not power (in watts) at all, it’s an intensity value.Duration="200"
- it might not be a duration at all, instead it might be a distance.PowerLow
might contain higher value thanPowerHigh
.
Coupled with implementation
Looks like lots of the values in the XML come straight out of the Zwift app, in the way that just happened to be most convenient for developers.
The worst of these is the pace
field which contains a number from 1
to 5
,
with the following meanings:
1
- 1 mile pace2
- 5 km pace3
- 10 km pace4
- half marathon pace5
- marathon pace
That’s just bad in so many ways:
- it’s impossible to understand the meaning of these values from XML file alone.
- the relationship between the values and their meaning is completely arbitrary.
- Currently they’re nicely ordered by the distance, but what if you want to extend this list in the future with 1000 meters pace?
The values coming out of Zwift’s own workout editor are also fun:
- Power=“0.89999998“
- Duration=“180.00002“
They clearly want you to be very exact and exercise precisely at 89.999998% of FTP for 3 minutes and 20 microseconds :) Or was it 180 meters and 20 micrometers?
So…?
Because of all these problems and several others, authoring a ZWO file manually is quite some pain. That’s why I created my own workout file format and a tool (available as online editor) for converting it to ZWO file, which Zwift could understand.