data/claims/pw64.yamlPilotwings 64 (the pw64 decompilation, n64decomp/pw64)
Game: Pilotwings 64.
In the US version of Pilotwings 64, the gyrocopter's update routine func_8030399C clears a vector (unk31C) and has five routines add terms to it: func_80307A9C, func_80307E2C, func_80308478, func_80307BAC, and func_80307EA8. A routine chosen by state can add to it after them (func_80304B98, for states 1 and 4, does), and func_80309090 copies the result to unk1AC. In state 1 (unkC0), the routine adds unk1AC times the frame time to the craft's velocity (unk190), with no mass dividing it; in state 0 it first combines unk1AC with cross terms of the velocity and the turn rates (unk1B8). func_80307E2C adds (0, 0, −9.8), z being the world's vertical, turned into the craft's frame through the inverse of its matrix (by the atlas's reading, gravity). func_80307A9C adds, on each of the craft's axes, a curve of the square of unk364's component on that axis, signed like the component: 0 at 0, 4.2 at 2661.2188, and 7.56 at 6944.389 and above, linear between (by the atlas's reading, air resistance). Those squares are speeds of about 51.59 and 83.33 (computed). func_80308478 sets unk364 to the vector env_802E1754 returns for the craft's position, in the craft's frame, less the craft's velocity, and adds 0.21 of that vector as a term of its own; by the atlas's reading the vector is the air's velocity and unk364 the airspeed. Below a speed (unk1A8) of 51.587303 the vector is scaled by the square of the speed over 51.587303, and outside state 0 it's taken as zero. The other two routines are in pw64/gyrocopter-lift. pw64/gyrocopter-forces
About: Pilotwings 64 Flight model
Value: 9.8 units per second squared (gravity)
Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) ·src/app/gyrocopter.c#L251-L279void func_8030399C(GyrocopterData* gcData) {
…
gcData->unk31C.x = 0.0f;
…
func_80307A9C(gcData);
func_80307E2C(gcData);
func_80308478(gcData);
func_80307BAC(gcData);
func_80307EA8(gcData);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L349-L365uvMat4Copy(&gcData->unk150, &gcData->unk10);
uvMat4InvertTranslationRotation(&gcData->unk110, &gcData->unk150);
if (gcData->unkC0 == 1) {
gcData->unk190.x += D_8034F854 * gcData->unk1AC.x;
…
uvMat4LocalToWorld(&gcData->unk150, &gcData->unk19C, &gcData->unk190);
} else {
gcData->unk19C.x += D_8034F854 * gcData->unk1B8.x;
…
uvMat4LocalToWorld(&gcData->unk110, &gcData->unk190, &gcData->unk19C);
…
gcData->unk10.m[3][0] = (gcData->unk19C.x * D_8034F854) + spF4;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L280-L310switch (gcData->unkC0) {
case 0:
func_80304738(gcData);
break;
case 1:
case 4:
func_80304B98(gcData);
…
func_80309090(gcData);
if ((gcData->unkC0 == 0) && (gcData->unk190.z < gcData->unk190.y) && (gcData->unk6D == 0)) {
gcData->unk1B8.x = (gcData->unk1AC.x - (gcData->unk190.y * gcData->unk1C8.z)) + (gcData->unk190.z * gcData->unk1C8.y);
…
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1818-L1837void func_80309090(GyrocopterData* gcData) {
…
gcData->unk1AC.x = gcData->unk31C.x;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L566-L623void func_80304B98(GyrocopterData* gcData) {
…
uvVec3Add(&gcData->unk31C, &gcData->unk31C, &sp11C);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1442-L1452void func_80307E2C(GyrocopterData* gcData) {
…
sp1C.z = -9.8f;
uvMat4LocalToWorld(&gcData->unk110, &gcData->unk358, &sp1C);
gcData->unk31C.x += gcData->unk358.x;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L122-L125D_80369528.count = 3;
D_80369528.unk4[0].x = 0.f, D_80369528.unk4[0].y = 0.0f;
D_80369528.unk4[1].x = 2661.2188f, D_80369528.unk4[1].y = 4.2f;
D_80369528.unk4[2].x = 6944.389f, D_80369528.unk4[2].y = 7.5599995f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1360-L1380void func_80307A9C(GyrocopterData* gcData) {
…
sp24.x = func_80313F08(&D_80369528, SQ(gcData->unk364.x));
if (gcData->unk364.x < 0.0f) {
sp24.x = -sp24.x;
…
gcData->unk31C.x += sp24.x;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L257-L280f32 func_80313F08(Unk803599D0* arg0, f32 arg1) {
…
if (arg1 <= arg0->unk4[0].f[0]) {
return arg0->unk4[0].f[1];
…
if (arg0->unk4[arg0->count - 1].f[0] <= arg1) {
return arg0->unk4[arg0->count - 1].f[1];
…
temp_fv1 = (arg1 - prev->f[0]) / (cur->f[0] - prev->f[0]);
return (cur->f[1] * temp_fv1) + (prev->f[1] * (1.0f - temp_fv1));pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1563-L1605void func_80308478(GyrocopterData* gcData) {
…
if (gcData->unkC0 == 0) {
env_802E1754(gcData->unk10.m[3][0], gcData->unk10.m[3][1], gcData->unk10.m[3][2], &sp38);
uvMat4LocalToWorld(&gcData->unk110, &sp44, &sp38);
…
} else {
sp44.x = sp44.y = sp44.z = 0.0f;
…
if (gcData->unk1A8 < 51.587303f) {
temp_fv0 = gcData->unk1A8 / 51.587303f;
temp_fv0 = SQ(temp_fv0);
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L410gcData->unk1A8 = uvVec3Len(&gcData->unk19C);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L471hud->altSeaLevel = gcData->unk10.m[3][2] * 0.7f;Checked by claude, 2026-10-22 — read func_8030399C to the call of func_80309090 and the unk1B8 branch after it, the velocity and position integration, the copy of unk31C into unk1AC in func_80309090, the addition to unk31C in func_80304B98, func_80307E2C, func_80307A9C and its curve, the curve reader func_80313F08, func_80308478 whole, the speed's definition, and the HUD's height line; no VERSION_JP conditional encloses these linesThe decompilers name none of these functions or fields. z being the world's vertical rests on the HUD reading the matrix's z translation as height above sea level. unk1A8 is the length of the world velocity, a ground speed, so the curve's knots (on unk364) match a speed readout only in still air; the readout figures are left out for that reason. State 0 is, from func_80305DC0, the state with no ground contact, but the atlas hasn't stated that rule.
Cited by: Flight model, Pilotwings 64
In the US version of Pilotwings 64, two of the terms the gyrocopter's func_8030399C sums give it lift, by the atlas's reading. The one the atlas calls the rotor term (func_80307BAC) is 0.3 times the square of the airspeed's component on the z axis of the matrix unk25C, signed like that component and capped at 200 when positive, times the square of the airspeed's y component over 25, held between 0.05 and 1; it's added along the z axis of the matrix unk21C. The one it calls the engine term (func_80307EA8), while usingFuel is set, is 35 × power (unkB4) × a factor of height (spD8, the atlas's altitude factor), split 0.24 onto y and 0.76 onto z, the z part also times a curve of the negated y airspeed: 0 at 0, 0.15 at 10, 0.4 at 20, 1.2 at 50, and 1.5 at 100 and above. It too goes through unk21C, and its y component is cut to 0.9 when unk1F0 is nonzero, unk190.y is positive, and unk7C is 0. That factor is 1 up to a height of 700 and falls by 0.01 per unit above it, held at 0 from 800 up; that hold is under #if !defined(VERSION_JP), so a Japanese build lets the factor go negative. Neither term applies while unkC1 is set or in state 2 (unkC0). pw64/gyrocopter-lift
About: Pilotwings 64 Flight model
Value: 700 height where engine thrust begins to fade
Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) ·src/app/gyrocopter.c#L1382-L1440void func_80307BAC(GyrocopterData* gcData) {
…
if ((gcData->unkC1 != 0) || (gcData->unkC0 == 2)) {
gcData->unkE8 = func_80313AF4(0.0f, gcData->unkE8, 0.5f);
return;
}
uvMat4LocalToWorld(&gcData->unk25C, &sp34, &gcData->unk364);
sp54 = -(0.3f * sp34.z * sp34.z);
if (-sp34.z < 0.0f) {
sp54 = -sp54;
if (sp54 < -10.0f) {
sp54 = -10.0f;
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1454-L1463void func_80307EA8(GyrocopterData* gcData) {
…
if ((gcData->unkC1 != 0) || (gcData->unkC0 == 2)) {
gcData->unkF0 = func_80313AF4(0.0f, gcData->unkF0, 0.5f);
return;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1490-L1516if (gcData->unk10.m[3][2] > 700.0f) {
spD8 = 1.0f - ((gcData->unk10.m[3][2] - 700.0f) / 100.0f);
#if !defined(VERSION_JP)
if (spD8 < 0.0f) {
spD8 = 0.0f;
}
#endif
} else {
spD8 = 1.0f;
}
if (gcData->usingFuel) {
temp_fv0 = func_80313F08(&D_803692C0, -gcData->unk364.y);
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L74-L79D_803692C0.count = 5;
D_803692C0.unk4[0].x = 0.0f, D_803692C0.unk4[0].y = 0.f;
D_803692C0.unk4[1].x = 10.0f, D_803692C0.unk4[1].y = 0.15f;
D_803692C0.unk4[2].x = 20.0f, D_803692C0.unk4[2].y = 0.4f;
D_803692C0.unk4[3].x = 50.0f, D_803692C0.unk4[3].y = 1.2f;
D_803692C0.unk4[4].x = 100.0f, D_803692C0.unk4[4].y = 1.5f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L470-L474hud->altSeaLevel = gcData->unk10.m[3][2] * 0.7f;
…
if (hud->fuel > 0.0f) {
hud->power = gcData->unkB4;Checked by claude, 2026-10-22 — read func_80307BAC whole, func_80307EA8's early return and its thrust block through the additions to unk31C, the thrust curve, and the HUD's height and power lines; the only VERSION_JP conditional in these lines is the one the statement namesNeither term is named by the decompilers; "rotor" and "engine" are the atlas's reading (the engine term runs only while fuel is in use, and the rotor term grows with air flowing along the rotor matrix's z axis). That the 0.24 part pushes the craft forward and the 0.76 part up, with lift rising with forward airspeed, is a reading of the axes, not stated in the code. The README lists only the US build as supported, so the Japanese behavior is read from the conditional, not a build.
Cited by: Flight model, Pilotwings 64
In the US version of Pilotwings 64, the gyrocopter's fuel is a number from 0 to 1, starting at the value the task's first start pad holds, or 0 if the task has no start pad (db_getstart). While usingFuel is set, func_80307EA8 takes off each update the frame time times a rate read from a curve of the power (unkB4, the throttle that A raises and B lowers, which the HUD shows as power; in the throttle's case 0 A sets usingFuel, and in cases 1 and 2 A sets it only with fuel above 0): 0.001 at 0, 0.002 at 0.5, and 0.005 at full, linear between. The frame time (D_8034F854) is the time since the last frame held between 0.01 and 0.1, so the rate is per second, and a full tank lasts 200 s at full power and 1,000 s at none (computed). At 0 it clears usingFuel. In a Class B task, each update that func_802E08F4 returns nonzero for the craft's position sets the fuel to 1, and SFX_UI_FUEL_ADDED plays on the first. func_80307EA8 does none of this, refill or drain, while unkC1 is set or in state 2 (unkC0). Separately, the HUD update in code_7CF30.c warns below 0.15 (TEXT_FUEL_WAR) and at 0 (TEXT_FUEL_OUT). pw64/gyrocopter-fuel
About: Pilotwings 64 Fuel gauge
Value: 0.005 tank per second at full power
Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) ·src/app/gyrocopter.c#L84-L88D_803694D0.count = 3;
D_803694D0.unk4[0].x = 0.0f, D_803694D0.unk4[0].y = 0.001f;
D_803694D0.unk4[1].x = 0.5f, D_803694D0.unk4[1].y = 0.002f;
D_803694D0.unk4[2].x = 1.f, D_803694D0.unk4[2].y = 0.005f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1454-L1488void func_80307EA8(GyrocopterData* gcData) {
…
if ((gcData->unkC1 != 0) || (gcData->unkC0 == 2)) {
…
return;
}
if (D_8036957E == CLASS_B) {
if (func_802E08F4(gcData->unk10.m[3][0], gcData->unk10.m[3][1], gcData->unk10.m[3][2]) != 0) {
if (gcData->unk67E == 0) {
gcData->unk67E = 1;
sndPlaySfx(SFX_UI_FUEL_ADDED);
…
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L257-L280f32 func_80313F08(Unk803599D0* arg0, f32 arg1) {
…
temp_fv1 = (arg1 - prev->f[0]) / (cur->f[0] - prev->f[0]);
return (cur->f[1] * temp_fv1) + (prev->f[1] * (1.0f - temp_fv1));pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L9f32 D_8034F854 = 0.1000000015f; // actual time since last framepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L210-L220temp_fv0 = uvGfxGetFrameTime();
if (temp_fv0 < 0.01f) {
D_8034F854 = 0.01f;
} else if (temp_fv0 > 0.1f) {
D_8034F854 = 0.1f;
} else {
D_8034F854 = temp_fv0;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L95db_getstart(&gcData->unk10, &gcData->unk190, &sp5F, &gcData->fuel);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_66F70.c#L260-L294temp_v1 = taskGetTPAD(&sp44);
if (temp_v1 == 0) {
…
if (fuel != NULL) {
*fuel = 0.0f;
}
} else {
…
first = &sp44[0];
…
if (fuel != NULL) {
*fuel = first->unk2C;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L248-L309switch (gcData->unk5F) {
case 0:
if (buttons & A_BUTTON) {
gcData->unkB0 += gcData->unk654 * D_8034F854;
if (!gcData->usingFuel) {
gcData->usingFuel = TRUE;
…
if (buttons & B_BUTTON) {
gcData->unkB0 -= gcData->unk658 * D_8034F854;
…
case 2:
…
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L473-L474if (hud->fuel > 0.0f) {
hud->power = gcData->unkB4;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L494-L499if ((gcData->fuel <= 0.0f) && !gcData->fuelEmpty) {
hudWarningText(TEXT_FUEL_OUT, 1.5f, 8.0f);
…
} else if ((gcData->fuel < 0.15f) && !gcData->hasLowFuel) {
hudWarningText(TEXT_FUEL_WAR, 1.5f, 8.0f);Checked by claude, 2026-10-22 — read func_80307EA8 from its start to the fuel clamp, the fuel curve, func_80313F08, D_8034F854's definition and func_80313D74, db_getstart, the throttle switch in code_7CF30.c through the copy into unkB4, and the HUD's power and warning lines; no VERSION_JP conditional encloses these linesThe 200 s and 1,000 s are 1 divided by the end rates. What func_802E08F4 tests (by its use, a refuelling area) isn't named. The start pad's value is task data from the ROM, so whether a test starts full isn't read.
Cited by: Fuel gauge, Pilotwings 64
In the US version of Pilotwings 64, a thermal is a vertical cylinder from the task's data (TaskTHER): a base position, a radius (scale), and a height. therm_80346C08 sums a vector from each thermal whose cylinder holds the point (by the atlas's reading, its air velocity): its horizontal distance d from the axis at most the radius r, and its height z above the base between 0 and the thermal's height. In therm_80346E04 the vector's vertical part (the atlas's updraft) is the thermal's unk24 × √((r − d)/r), full on the axis and 0 at the edge. Beyond 1 unit from the axis its horizontal part is at right angles to the axis direction, of length unk20 × (1 − 2|r/2 − d|/r) × d, longest halfway out (the atlas's swirl). Both fade in from 0 at the base to full at height unk18, and from unk1C fade out to 0 at the top. env_802E1754 adds the sum to the vector wind_8034D550 gives for the point (by the atlas's reading, the wind), along with, unless the task's unk8 is set, a further wind and a push from beyond 2050 units outside the map's bounds. The hang glider (hangGlider_802F391C) multiplies the total by its pilot's unk2F8: 1.2 for Lark and Kiwi, 1.0 for Goose and Ibis, and 0.8 for Hawk and Robin. pw64/thermal
About: Pilotwings 64 Thermal
Value
{
"lark": 1.2,
"goose": 1,
"hawk": 0.8,
"kiwi": 1.2,
"ibis": 1,
"robin": 0.8
}src/app/task.h#L274-L283typedef struct {
Vec3F pos;
f32 scale;
f32 height;
…
} TaskTHER; // size = 0x28pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L156-L199void therm_80346C08(f32 x, f32 y, f32 z, Vec3F* dst) {
…
dx = x - therm->pos.x;
dy = y - therm->pos.y;
dz = z - therm->pos.z;
dist = uvLength2D(dx, dy);
if (taskTherm->scale < dist) {
continue;
}
if (taskTherm->height < dz) {
continue;
}
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L201-L235temp_fv0 = therm->scale * 0.5f;
if (dist > 1.0f) {
if (dist < temp_fv0) {
var_fa0 = temp_fv0 - dist;
} else {
var_fa0 = -(temp_fv0 - dist);
}
var_fv1 = 1.0f - ((2.0f * var_fa0) / therm->scale);
dst->x = therm->unk20 * var_fv1 * dist * (y / dist);
dst->y = -var_fv1 * therm->unk20 * dist * (x / dist);
…
var_fv1 = uvSqrtF((therm->scale - dist) / therm->scale);
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/environment.c#L338-L382void env_802E1754(f32 arg0, f32 arg1, f32 arg2, Vec3F* arg3) {
…
wind_8034D550(arg0, arg1, arg2, &sp44);
therm_80346C08(arg0, arg1, arg2, &sp38);
…
temp_fv0 = (temp_v0->unk0.unk0 - 2050.0f) - arg0;
if (temp_fv0 > 0.0f) {
sp2C = (50.0f * temp_fv0) / 2050.0f;
…
if (D_80362690->unkC[D_80362690->unk9C].unk8 == 0) {
arg3->x = sp44.x + sp38.x + D_80359D80.unk0.x + sp2C;
…
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider2.c#L574-L591STATIC_FUNC void hangGlider_802F391C(HangGliderData* hgData) {
…
if (hgData->unk8C != 2) {
env_802E1754(hgData->unk10.m[3][0], hgData->unk10.m[3][1], hgData->unk10.m[3][2], &sp20);
sp20.x *= hgData->unk2F8;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L519-L569void hangGliderLoadPilot(u8 pilot, HangGliderData* hgData) {
switch (pilot) {
case PILOT_LARK:
…
hgData->unk2F8 = 1.2f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L572-L618case PILOT_GOOSE:
…
hgData->unk2F8 = 1.0f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L623-L669case PILOT_HAWK:
…
hgData->unk2F8 = 0.8f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L674-L722case PILOT_KIWI:
…
hgData->unk2F8 = 1.2f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L725-L771case PILOT_IBIS:
…
hgData->unk2F8 = 1.0f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L776-L822case PILOT_ROBIN:
…
hgData->unk2F8 = 0.8f;Checked by claude, 2026-10-22 — read TaskTHER, therm_80346C08 and therm_80346E04 whole, env_802E1754 whole, hangGlider_802F391C, and each pilot's case in hangGliderLoadPilot to its unk2F8; no VERSION_JP conditional encloses these lines"Updraft" and "swirl" are the atlas's reading of the vertical and tangential parts; the decompilers name neither field. Each thermal's strengths and heights are task data from the ROM. The swirl's peak at d = r/2 is computed. How the hang glider's lift uses the air (the rest of hang_glider2.c) isn't read.
Cited by: Pilotwings 64, Thermal
In the US version of Pilotwings 64, the thermals switch off in one test: the hang glider's test with index 0 in the Pilot class (cls 3, CLASS_PILOT). There, from 240 on the clock D_8034F850 (by the decompilers' comment, the current time; the test's setup, gameUpdateStateTestSetup, sets it to 0, and each time func_80313D74 runs it adds the time since the last frame held between 0.01 and 0.1, so it counts seconds of game time), therm_8034695C narrows the drawn cylinders to nothing over the next 10, and at 250 (THERM_DISABLE_TIME) removes the thermals and shows TEXT_THERM_OFF. The narrowing scales only the model's matrix: the updraft reads the task's radius until the thermals are gone. pw64/thermal-cutoff
About: Pilotwings 64 Thermal
Value: 250 seconds
Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) ·src/app/thermals.c#L14-L18#define THERM_ENABLE_DURATION (4 * 60) // 4 minutes in sec
#define THERM_WEAKEN_DURATION (10)
#define THERM_DISABLE_TIME (THERM_ENABLE_DURATION + THERM_WEAKEN_DURATION)pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L98-L101sThermShouldDisable = 0;
temp_v1_2 = &D_80362690->unkC[D_80362690->unk9C];
if ((temp_v1_2->veh == VEHICLE_HANG_GLIDER) && (temp_v1_2->cls == 3) && (temp_v1_2->test == 0)) {
sThermShouldDisable = 1;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/task.h#L53-L56CLASS_BEGINNER = 0,
…
CLASS_PILOT = 3,pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L114-L140var_fs0 = 1.0f;
…
if ((D_8034F850 >= THERM_DISABLE_TIME) && (gThermalCount != 0) && sThermShouldDisable) {
thermDeinit();
gThermalCount = 0;
gThermReady = 0;
hudWarningText(TEXT_THERM_OFF, 1.5f, 8.0f);
…
if ((D_8034F850 >= THERM_ENABLE_DURATION) && (gThermalCount != 0) && sThermShouldDisable) {
var_fs0 = (f32)(1.0 - (f64)((D_8034F850 - THERM_ENABLE_DURATION) / THERM_WEAKEN_DURATION));
…
sp74.m[0][0] = taskTherm->scale * var_fs0;
…pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L182-L184if (taskTherm->scale < dist) {
continue;
}pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L8f32 D_8034F850 = 0.0f; // current timepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L210-L221void func_80313D74(void) {
…
temp_fv0 = uvGfxGetFrameTime();
if (temp_fv0 < 0.01f) {
D_8034F854 = 0.01f;
} else if (temp_fv0 > 0.1f) {
D_8034F854 = 0.1f;
…
D_8034F850 += D_8034F854;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/game.c#L431-L545s32 gameUpdateStateTestSetup(Unk80362690* arg0) {
…
func_80313E0C(0.0f);
…
return GAME_STATE_TEST_UPDATE;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L225-L227void func_80313E0C(f32 arg0) {
D_8034F850 = arg0;Checked by claude, 2026-10-22 — read the three defines, the end of thermLoad, the class enum, therm_8034695C whole, the radius test in therm_80346C08, the clock's definition, func_80313D74's addition, func_80313E0C, and its call in gameUpdateStateTestSetup; no VERSION_JP conditional encloses these linesfunc_80313D74 is called from game.c and a dozen other state updates; the atlas hasn't shown it runs exactly once per frame, so the clock is stated as the sum of its calls. Which test index 0 is in the game's numbering (most likely the class's first) isn't checked against the game. Whether the clock runs while paused isn't read. The radius test in therm_80346C08 and therm_80346E04 read sTaskTHER's scale, not the drawn matrix.
Cited by: Pilotwings 64
The North American instruction booklet for Pilotwings 64 gives the game's copyright to Nintendo and Paradigm Simulation, Inc. (1996); it names no developer as such. pw64/copyright
PDF p. 2 (inside the front cover)© 1996 Nintendo / Paradigm Simulation, Inc.Checked by claude, 2026-10-22 — read the scout's pinned PDF text layer at the line quotedCited by: Pilotwings 64
In a recording of the PAL version, Pilotwings 64's ending credits list a "Nintendo Staff" group, directed by Makoto Wada, then a separate "Paradigm Staff" group under project manager Dave Gatchel, and end on "Presented by Nintendo"; the credits never name Nintendo EAD. pw64/credits
1:15:27 — DIRECTOR / MAKOTO WADA at about 1:15:34NINTENDO STAFFPilotWings 64 (N64, PAL) full-game longplay, with the ending credits · 1:16:09 — PROJECT MANAGER / DAVE GATCHEL at about 1:16:16PARADIGM STAFFPilotWings 64 (N64, PAL) full-game longplay, with the ending credits · 1:18:49PRESENTED BY / NINTENDOThe Making of Pilotwings 64Nintendo handled the game design while Paradigm was responsible for the technologyChecked by scout, 2026-10-22 — read from frames of the pinned video at 1–3 s steps; no claude re-read of the framesA recording of the game is a secondary source here, so the claim is T1; the credits screen itself would be primary. The Nintendo Life article's profile box lists "Nintendo EAD", the only place the scout found that name.
Cited by: Pilotwings 64