We are a 3 person team. Here are our games so far:

Retro Game Internals: Punch-Out Behavior Script

Last time we looked at match scripts which were the highest level scripts controlling opponents in Punch-Out. The basic function of a match script was to sequence opponent behaviors throughout the fight. Today we’ll dive into behavior scripts which are where those behaviors are actually implemented.

The following video shows an interpretation of what the behavior script for Piston Honda 1 might look like in something like plain English commands.

Animation Commands

Behavior scripts are in charge of sequencing animations in much the same way that match scripts were in charge of sequencing behaviors. The anim command plays a single specific animation, and the anim_rnd command plays an animation randomly selected from a list of 8 options. In the video above, whenever a random selection is made from a list of options, the chosen option is briefly highlighted in red. When Piston Honda throws his opening 2 jabs, he is using anim for each one. After that, he uses anim_rnd to randomly pick from a set containing 6 hook animations, and 2 empty animations. The result is that his third action will be to throw a hook 75% of time time, and to do nothing 25% of the time.

Animations will be played back synchronously from the point of view of the behavior script since the script interpreter is paused any time the animation system is not in its idle state.

Flow Control Commands

There are a few commands available to modify the execution of the behavior script itself. The pause commands can pause script execution for a specific number of frames, or a number of frames randomly chosen from a list of 2 options.

There are various branch commands available that optionally jump to a different part of the behavior script if certain conditions are met. The branch_rnd command has a specified probability that the branch will be taken each time it is executed. A special case of the probabilistic branch is branch_always which has a 100% chance of branching.

There is a simple looping mechanism built in to the behavior script interpreter that can be used to repeat sections of script a certain number of times. The set_loop_count command sets the current value of the loop counter. Then, each time the branch_while_loop command is executed, it decrements the loop counter by one and branches only if the counter is still above zero.

The final kind of branch checks the contents of memory to decide whether or not to take the branch. Piston Honda uses this branch_mem_test command to check if his most recent punch connected during his special behavior. Any time his punch connects, he branches directly to the next punch. If a punch does not connect, he uses a branch_while_loop command to keep punching only until he accumulates 5 failed punches.

Behavior Commands

There are 2 commands that behavior scripts can use to control the behavior system itself. The begin_behavior_main command is used to end whatever behavior is currently running and begin running the main behavior. This is different from a branch within the behavior script because the section of script that is considered to be the current “main” behavior can be changed during the course of the match by the match script (see the previous post about match scripts.)

The other command related to behavior is enable_behavior_change. Whenever a new behavior begins, it starts off in a locked state where any further requests to change behavior will be blocked. By using the enable_behavior_change command, the script is signaling that it is ready to allow other behaviors to happen. For example, in Piston Honda’s special behavior, the enable_behavior_change command is never executed and so if Mac gets tired during that time, the special behavior will continue to run. Knock down events will bypass this system however so if Mac gets knocked down during Piston Honda’s special, a behavior change will happen no matter what.

Up Next

With match script and behavior script out of the way, the final piece of the opponent script hierarchy puzzle is animation script. These are very low level scripts with a rich command set that run to implement the animations that the behavior scripts have been requesting. If you have any questions or comments, or you want to know when these (very infrequent) blog posts go up, please feel free to contact me on twitter @allan_blomquist

(Prev – This is part 4 of a series)

Welcome, all 7 Billion Humans!

Welcome, all 7 Billion Humans! We’ve been working on a thrilling followup to Human Resource Machine.

Finally! You can personally employ everyone on the planet inside your very own parallel computer made of people.

More info, images, and other fancy stuff here. For you Steam people, the link to wishlist and get more info on Steam is here. Coming soon…

Retro Game Internals: Punch-Out Match Script

The match script controls opponent behavior at the highest level in a fight. The basic operation it performs over and over is to wait for a certain time during the round and then make some kind of change to the opponent’s configuration data. The following video shows the first round of the first fight against Bald Bull along with a representation of the match script that is controlling his overall behavior.

There are three basic operations that a match script can perform. The first is just to wait until the round timer reaches a specific value. The second is to request that the opponent change his current behavior. Behaviors are registered in a fight configuration table in memory and then called on at various times by both match scripts and the game engine itself. There are two behavior slots in the table that match scripts use that I’ll call the “main” behavior and the “special” behavior. Special behaviors are things like Bald Bull’s Bull Charge and Piston Honda’s Honda Rush, while main behaviors are the normal punches the opponent throws the rest of the time. The particular behavior scripts used to implement these behavior types can be changed by the match script mid-round, so fighters can start out using one main behavior and then switch to a different main behavior later on (you can see Bald Bull do this when the timer reaches 0:20 in the video.)

A quirk of behavior changes from match scripts is that they are overridden by behavior changes requested by the game engine. The game engine uses four of the behavior slots to request new behaviors when Mac loses all of his hearts and becomes tired, recovers from being tired, gets up after being knocked down, and after the opponent gets up after being knocked down. If the match script has issued a request for a behavior change, but one of those four game engine events happens before that request can be honored (requests can’t be honored until the opponent is in an idle state), then the game engine will get to set the behavior it wants and the request from the match script will be lost. Some fighters, like Bald Bull, request their special behavior multiple times in quick succession. The only purpose of this seems to be to reduce the chance that any one of the requests will be accidentally skipped.

The third basic operation of a match script is to patch memory. Most memory patches affect the fight configuration table where the behavior scripts are registered. In addition to behavior selections, the table also contains data related to the difficulty of the fight. For example, when the timer reaches 0:30 in the video, Bald Bull changes his guard matching parameters making it so you can no longer fake him out by tapping up and then throwing a punch to the body. Match scripts have the ability to patch arbitrary memory addresses also, but the only time it is used is at the beginning of Mike Tyson round 2 to make it so that you will get a star the first time you punch him while he is idle.

Up Next

The next kind of script we’ll look at will be the behavior scripts. These are what the match script and game engine have been selecting to run and are where the actual punching behavior gets put together. If you have anything you’d like to see covered or any questions about a post you can contact me on twitter @allan_blomquist

(Prev – This is part 3 of a series – Next)

Retro Game Internals: Punch-Out Overview

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.

Match Script

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.

Behavior Script

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.

Animation Script

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.

Up Next

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

(Prev – This is part 2 of a series – Next)

Now Available in Europe and Australia… and Multiplayer Updates Everywhere!

European and Australian eShop customers enlarged to show texture.

 

World of Goo, Little Inferno, and Human Resource Machine are now available in Nintendo’s European and Australian regions, in adorable eShops everywhere! And extra thanks once again to our volunteers who made all these translations possible – all three games were translated by real live human community volunteers.

 

Two updates were also just released today, for all regions. The Switch should automatically apply these updates for you:

  • Little Inferno: Now with multiplayer, grab the other Joy-Con and burn it all down with a friend!
  • Human Resource Machine: Now you can swap which Joy-Con you’re using whenever you want. Just press a button on whichever one you want to use. This was, strangely, a very requested feature.