1986 · Epyx

World Games: Discoveries

This minisite was contributed by air. It’s agent-generated and needs a human editor. Clone https://github.com/gamesexplained/gamesexplained and follow kit/START.md to curate games/c64/world-games with me to Gold.

Secrets, quirks and bugs in the eight events, each checked in the emulator or traced in the code, with the evidence beside it.

01 · Weightlifting

Bug: 865 kg stops the processor

A player's report on C64-Wiki says weightlifting crashes at 865 kg. It does. The routine that draws the plates enters a run of instructions one byte into one of them, and that byte is one that halts the processor. Choose a weight.

The weightlifter standing behind a bar with red plates, the text row reading PRACTICE WHICH EVENT? SNATCH
860 kg: the plates drawn.
The same scene with the text row broken into blocks and its red stripe gone
865 kg: the processor stopped while the screen was being drawn.

wl_plates ($1985) and wl_strip ($1C31), held by test_widgets.js to the game's code for every weight and every strip, with the lifter standing, as while a weight is chosen: the bar's line, $2F, is $31. Checked in VICE on 30 October 2026: with the weight set to 860 kg the plates were drawn, and at 865 kg the processor stopped at $1C63 and stayed there.

The routine takes 25 kg off the weight, then 100 kg for a big plate and 50 kg for a second, when the weight has them. What is left, in 5 kg steps, sets where the last plate starts: 9 less it ($19B3). Up to 225 kg what is left is 0 to 9. Above 225 kg, 9 less it is below 0, and the routine draws its largest last plate instead. At 865 kg, 9 less it is -129, one below the least a byte can hold, and the byte reads +127.

The plates are drawn by 75 STA instructions in a row, each storing a byte of the plate in the picture, one for each pixel line, entered three bytes on for each line down (wl_column_writer, $1C53). The last plate now starts 176 lines down, and three times 176 overflows a byte too: the writer is entered at $1C63, the second byte of STA $67F2,X. That byte, $F2, is one of the twelve codes that stop the C64's processor, a 6502, where it stands.

A player reaches 865 kg in a competition. A good lift at 225 kg, the hardest timing the game sets, makes the next weight 230 kg, and from there each push right adds 5 kg with no limit (below). The 127th push stops the machine.

02 · Two events

Secret: AUTHOR and OFTHEGAME open two credits screens

Name the first two players AUTHOR and OFTHEGAME, in either order, and barrel jumping and bull riding each show who wrote them instead of starting.

A yellow screen with a skater above the words WRITTEN BY MATT,JOE, & DOUG and a barrel below
Barrel jumping: "WRITTEN BY / MATT,JOE, & DOUG".
A yellow screen with a thrown rider beside a bull, above the words WRITTEN BY CHRIS PESTERLING
Bull riding: "WRITTEN BY / CHRIS PESTERLING".

Seen in VICE on 30 October 2026, with the two names in the first two players' records.

The title screen, with the programmers' names below the World Games logo
The title screen's credits, for comparison.

Each event compares the first two players' names, nine characters at a time, with its own copies of AUTHOR and OFTHEGAME ($286A in barrel jumping, br_hidden_check, $2ED7, in bull riding). On a match it shows its screen until the fire button is pressed, sets the shell's practice flag ($081D) and goes back to the shell without running the event. The two events were written by different people, and each hid its own credit in the same way.

The title screen's programmers include Matt Decker, Joe Simko and Doug Dragin, the Matt, Joe and Doug of barrel jumping's screen. Bull riding's screen spells its author's name Pesterling, where the title spells it Oesterling.

03 · Weightlifting

Bug: above 225 kg the timing comes from code

The table that sets how much of each window is good ends at 225 kg, but the weights go on. From 230 kg the game reads its factor from the instructions after the table, so some weights above 225 kg are easier than 150 kg, and others give a single good frame.

The factor for each weight, read where $1482 reads it, at wl_timing ($1493) plus the weight in 5 kg steps, less 15. Past the table's 31 bytes the reads land in wl_kg ($14B2), the routine that turns a weight into its digits. The last column is the good part of one of the lift's windows of 160 frames, the routine's sum as How it works shows it. Checked in VICE on 30 October 2026: with the weight set to 230, 235, 240, 245 and 250 kg, $1482 left $A2, $00, $86, $1E and $86 in $4B.

A competition gets there. After a round with a good lift, the next round starts 5 kg above that lift ($124F), so a good lift at 225 kg makes the next weight 230 kg. Right on the stick refuses to raise the weight only when it is exactly 225 kg ($146C), so from 230 kg it raises it with no limit. At 230 kg the factor is $A2, 162 out of 256: the good part of each window is as large as at 105 kg, where the table holds $A3. At 235 kg the factor is 0, and the routine that sizes the window gives it its least, one frame.

04 · Slalom

Bug: the final heat can keep the slower time

A slalom competition has two heats, and the better of each skier's two times should count. The comparison mixes up two ways of writing a time, and keeps whichever time its test lets through. Enter two times.

The rule of sl_keep_result ($F20C) from $F24D, held by test_widgets.js to the game's routine on 23,600 pairs of times. Checked in VICE on 30 October 2026 with five pairs: it kept the slower time in two of them.

The first heat's result is kept in the player's record as a score, 99 less each pair of digits of the time, so that a faster time has a higher score ($F27D). The final heat's time is compared with that score, pair by pair from the minutes, as if the two were written the same way ($F263): where the score is lower than the new time's digits, the first heat's result stays, and where it is not, the next pair is tried. The new time is kept only when every pair passes, which comes down to this: the two times' seconds add up to 99 or less, and so do their hundredths. Which time is faster plays no part.

05 · Bull riding

Bug: the eight-second ride lasts twenty-four seconds

A rider who stays on until 8 on the clock wins the ride. The clock counts a hundredth twice in every three frames, so its seconds pass at a third of the real ones. Start the ride.

0.00the event's clock
0.0seconds on a PAL machine

The clock as br_clock ($1C9F) runs it, at the 50 frames a second of a PAL machine. Checked in VICE on 30 October 2026: 15 frames moved the clock on 10 hundredths.

The clock runs on two frames in every three, and adds one hundredth each time. A second on the clock is 150 frames, three real seconds, and 8 on the clock is 1,200 frames. On an American NTSC machine, at 60 frames a second, the ride lasts about 20 seconds.

06 · Caber toss

Bug: every throw reads its height from the program's code

When the thrower lets go, the game looks up how fast the caber flies upwards in a table of 251 numbers. How long fire was held is meant to choose the entry. But the count it uses is always 0, so every throw looks up the same entry, and that entry is five bytes past the end of the table, inside the program's own instructions.

The end of the table, and what comes after it

The 256 bytes from $1CC8, each drawn as a bar as tall as its value: the table's 251 numbers in blue, then five bytes of the program in grey, which happen to come next in memory. The orange bars are the two the release reads: the speed across at entry $3A, and the speed up at entry 255 less three quarters of $3A (ct_release, $1AD0). The slider shows what a longer hold would have read, had the count ever got that far. Checked in VICE on 30 October 2026: three throws, with fire held 10, 30 and 90 frames, each read $1DC7.

While fire is held, a count goes up every frame by the run's speed. It has two bytes. The low byte runs from 0 to 255, and the high byte, $3A, goes up by one each time the low byte passes 255 and starts again. The caber leans a step further each time the low byte passes one of five marks, and the fifth lean fells it (How it works). The last mark is $D4, 212, so a caber still standing has never had its low byte pass 255, and $3A is 0 at every release.

The release takes the speed up from entry 255 less three quarters of $3A: with $3A at 0, entry 255. The table's entries are numbered 0 to 250, so entry 255 is five bytes beyond it, in the instructions that follow. That byte, $C6, is the start of the instruction DEC $5D, and read as a number it is 198. So every caber leaves the hands with 198 where the table's last entries hold 255, the most a byte can, however long fire was held. The speed across has the same problem the other way round: it reads entry $3A, always entry 0, $F8.

07 · Slalom

A flag hit head-on is a fall 100 times in 256

The manual says a skier who hits a gate head-on wipes out. The game decides by the frame counter, which goes up by one every frame: below 100 the skier falls, and from 100 to 255 the flag bends and the skier skis on.

The frame counter, $70, from 0 to 255 in rows of 32: red where a head-on hit is a fall, green where the flag bends (sl_flag_hit, $F371). Checked in VICE on 30 October 2026: with the counter at 0, 50 and 99 the skier fell, and at 100, 150 and 255 the flag bent.

A hit one column to either side of a flag always bends it. The counter goes up every frame, so a head-on hit is a fall for two seconds in every five, and a skier cannot tell which.

08 · Cliff diving

Secret: a gull for a score of exactly 101

A clean dive that scores exactly 101 sends a gull flying across the screen from the right. Only a dive from the top level, which starts at 106, can score it.

The diver surfaces between two dark rocks in a blue sea; a pelican stands on the left rock and the gull flies in at the top right; the text row reads SCORE 101
A clean dive from the top level in VICE on 31 October 2026, its score set to 101 just before the game showed it: the gull flies in at the top right.

At the end of a dive the score is compared with 101, and on a match the gull's list of poses starts: its wingbeat, poses 76, 77, 78 and 77, over and over ($1870; cd_gull_list, $273F; cd_gull_poses, $278B). Checked in VICE on 30 October 2026: the end of a dive called with scores of 101, 100, 102, 99 and 1 started the gull for 101 alone, and not for 101 after a fault.

A dive from the top starts with 106 points and loses 5 for each new push of the stick, so 101 is a dive from the top with one change of position, a clean entry and no points lost in the water (How it works).

09 · Log rolling

Bug: running backwards flat out stops the feet

Each step takes 7 off a lumberjack's speed when running backwards. Forwards the speed stops at 127; backwards, one step too many wraps it round, and the feet all but stop. Take a step back.

lr_step ($2183) as test_widgets.js holds it to the game's routine, for every speed in both directions. Checked in VICE on 30 October 2026: called with -121 it gave -128, and with -122 and -128 it gave $FFFF.

The speed is kept in two bytes, a whole part and 256ths, and a step changes the whole part. Forwards, a step that would pass 127 sets the speed to $7FFF, the most there is. Backwards, a step from -122 or below would pass -128, and the routine sets the speed to $FFFF, which is -1/256, where $8000, -128, was meant. A lumberjack running backwards as fast as they can is suddenly standing still on the log.

10 · Weightlifting

Bug: the first judge votes at once

Three judges vote on a lift, each after a delay. The first judge's delay comes from a sum that is always 0, so it votes the moment the lift is held overhead.

The delay is the high byte of the pushes' timing averaged by wl_divide ($1DF2), called at $14F9. Each push's timing is below 128, and so is their average. Checked in VICE on 30 October 2026: called with sums of 64, 381 and 511, it gave a high byte of 0 each time.

The other two judges vote up to 31 frames apart. A judge votes white while the hold is under 48 frames, so the first judge always votes white on a lift that reaches the judges (wl_vote, $1577).

11 · Weightlifting

Bug: a letter chooses how a lifter collapses

A lifter who holds the weight too long collapses in one of two ways, chosen by a random number against a limit. The limit is read from the text "CURRENT WEIGHT".

At $1549 the event reads the first byte of wl_txt_weight ($16F5), the letter C, $43, and multiplies it by 5, which in 8 bits is $4F. A random number of $4F or more plays script 6, and a lower one script 5 ($155B). Checked in VICE on 30 October 2026: $16F5 held $43 and the limit came to $4F; random numbers $00 and $4E played script 5, and $4F, $80 and $FF script 6.

The text's C is a byte like any other, and $4F splits the 256 values a byte can hold 177 to 79, in favour of script 6. The random numbers are 256 readings of the sound chip's noise, taken once as the event starts (wl_random, $197D), and they are not spread evenly: in a table read in VICE on 30 October 2026, 160 of the 256 were $4F or more. The two scripts play the endings of a lift held too long, each with its own sounds (script 5 starts tunes 9, 10, 11 and 7, script 6 only tune 7, all on the music player).

12 · The menu

Secret: Epyx is a country

The eighteen countries a player can represent include Epyx, the publisher, with a flag and an anthem of its own. On the country screen, the S key plays the anthem of the flag under the frame without choosing it.

The country screen: nine flags in three rows, the last of them the Epyx logo, under the words ENTER YOUR NAME

The country screen, with Epyx at the end of the bottom row in view. Its anthem is the menu's tune 14 (country_tunes, $1E8A, holds twice each flag's tune). The S key was tried in VICE on 30 October 2026: it played the anthem under the frame, and a move of the joystick stopped it. Every anthem plays on the anthem player.

The country screen's template also has a name in it: the row reads "NELSON S. PICK YOUR COUNTRY" before the player's name is written over the first ten characters (pick_country_text, $3CE9).

13 · Slalom

Bug: the best time's colour is written to the joystick chip

Slalom shows the best time at the top right in white. The loop that colours it writes to $DC47 and on, where $D847, in the colour RAM that holds the screen's colours, was meant. $DC00 to $DCFF belongs to CIA 1, the chip that reads the joysticks.

At $8189 the event copies the best time's seven characters from $0FF0 to row 1, column 31, on both of its screens, and writes 1, white, to $DC47 plus the character's place, where $D847 plus the place was meant. Checked in VICE on 30 October 2026 as a slalom run began: the loop wrote 1 to $DC4D down to $DC47, and colour RAM at $D847-$D84D already held 1.

Row 1 is white already, so the screen shows nothing wrong, and the seven writes go to the chip instead.

The slalom timer has an end of its own. At 10 minutes on the clock the run starts again from the top, with no result kept (sl_timer_second, $F1A7).

14 · Leftovers

Things the game carries and never uses

Each event was written apart, and several kept something they no longer needed.

WhereWhat
Weightlifting"Butch Badorsik (USA)", a name and country that nothing prints, among the event's texts (wl_txt_butch, $1661)
Sumoa readout for the developers that nothing calls: it would write each wrestler's pose, stick, state and speed in hexadecimal into the text row (su_debug, $2BC1)
Log rollingtune 6, the teeter on voice 3: the second lumberjack's teeter writes its step and then starts tune 5 ($1FB9)
Weightlifting, barrel jumping, bull riding, caber tosstunes in each event's list that nothing starts: weightlifting's 3, 4 and 8, barrel jumping's 3 and 12, bull riding's 3, caber toss's 9, all on the music player
Cliff divinga smooth scroll from one level to another, skipped by a JMP (cd_smooth_scroll, $28F4; $2796)
Bull ridinga copy of the sprites' offsets table that nothing reads ($9400)