Each fighter in Mike Tyson’s Punch-Out!! is controlled by one or more interpreted bytecode scripts. The player character, Little Mac, runs a single script that contains the logic for each action available to the player (dodging, blocking, punching, etc.) The opponent characters are controlled by 3 tiers of independent scripts that work together to create the opponents’ behavior.
The highest level opponent script runs throughout all 3 rounds of the fight and controls the major changes in opponent behavior. I’ll call this script the “match script.” The main job of a match script is to set the behaviors that the opponent will run in response to various events during the fight. For example, a certain behavior will be selected to run immediately after the opponent gets up after being knocked down, or when the player runs out of hearts and becomes tired. These behaviors are recorded in a table and will be invoked by the game engine in response to the appropriate events. The match script also sets up initial values for configuration options related to the difficulty of the fight (like the amount of time that the opponent will remain vulnerable after missing a punch.) Finally, the match script will begin waiting for certain time markers during the fight to make changes to the values it has previously set.
The next lower level opponent script tier is the “behavior script.” This level is in charge of sequencing the specific punches and attacks the opponent is supposed to perform as part of his current behavior (as dictated by the match script.) Behavior scripts execute commands like “throw a right jab, pause for 28 frames, randomly throw either a left or right uppercut, repeat all that 5 times.” They also have commands for reading and writing any memory location from the underlying game engine so behaviors can be very dynamic.
The lowest level opponent script tier is the “animation script.” These scripts perform the nitty gritty details of a single punch, block or special attack as part of a behavior (as dictated by the behavior script.) Commands found at this level include things like “set the opponent’s current frame of animation to sprite #23, move him down and to the right by 1 pixel every 2nd frame for the next 10 frames, change frame of animation to sprite #24, play sound effect #7.” In addition to animation related commands, animation scripts also sequence various gameplay state changes that are closely tied to the movements of opponents. For example, as part of a long animation for a special attack, an animation script might insert commands to make the opponent vulnerable to being knocked down with a single punch during a very specific window of time. Like behavior scripts, animation scripts can read and write arbitrary memory from the game engine to achieve more dynamic effects.
Little Mac Script
The script that Little Mac runs is most similar to the opponents’ animation scripts. It changes the current frame of animation being displayed and moves the player around on screen as needed. Like the animation scripts, Little Mac’s script is also what sequences certain gameplay events like when exactly Mac is considered to be punching the opponent, or when he should register as blocking or dodging. The player’s input is what drives Little Mac’s script in the same way that behavior scripts drive animation scripts for the opponents.
Each of these 4 script systems is processed by a different interpreter. Although many of them share some common functionality like basic flow control and raw memory access, each system implements its own version instead of sharing code (or opcode space) with the others. This allows each type of script to be very domain specific and make efficient use of a small set of targeted commands. Script data accounts for about 22% of the non-graphics data on the game cart (the actual machine code for the game engine is only about 17%) so having a compact representation for scripts was very important.
In the following posts in this series I’ll go into more detail about each of these different kinds of scripts and explore how they interact to create gameplay. I’ll also look briefly at the hidden rules of the game like what determines when an opponent gets up after a knock down, and how star punches are awarded. If you have anything you’d like to see covered or any questions about a post you can contact me on twitter @allan_blomquist