By Damian Yerrick
When making Thwaite better, it is important to know how it works.
There are ten houses and two missile silos. Each non-player character (NPC) has a specific role in cut scenes.
# | Name | Sex | Role |
---|---|---|---|
0 | Tilda | F | Paranoid |
1 | Meg | F | Laid back |
2 | Milo | M | Player 1 |
3 | Isca | F | Detective |
4 | Gnivad | M | Detective |
5 | Justin | M | Laid back |
6 | Briar | F | Paranoid |
7 | Acha | F | Detective |
8 | Torben | M | Paranoid |
9 | Staisy | F | Player 2 |
10 | Thad | M | Laid back |
11 | Oliver | M | Detective |
The NPC personalities correspond loosely to the three personalities for each sex in Animal Crossing series:
To avoid any appearance of impropriety, I intentionally avoided using any names from Animal Crossing series. Villagers 5 and 8 were the last to be named. Snowy suggested "Trop", "Justin", "Willie", and one other that I forget. I chose "Torben" for 8, which sounds like "Trop" but doesn't call to mind TV Tropes, and I used "Justin" for 5, leading to plenty of Justin Bieber jokes among play testers who would intentionally let Justin's house get blown up. Interestingly enough, there were no Justin Timberlake jokes, proving once again that no one has a memory over two years old.
The game consists of seven days: Sunday through Saturday. Each day consists of five waves, one in each hour from 01: to 05:
There are seven types of salvo: 1 to 5 normal missiles, one balloon, and one MIRV missile. Each wave has from 10 to 40 incoming enemy missiles, with a few exceptions. A new salvo is generated once every time period that the wave specifies.
Each of one to five missiles in a salvo is generated at a random (start X, destination target).
Instead of a salvo of missiles, occasionally a balloon carrying a crate slowly drifts in from the left. It moves at half the speed of an ordinary missile. This costs two missiles and is timed to activate over a randomly chosen house (1-10). If the player doesn't blow it up, it drops a missile over that house, one to the left, and one to the right. Creating a balloon costs two missiles.
Occasionally, the first missile in a salvo is replaced with a MIRV (stands for "multiple independent reentry vehicles"). When a MIRV crosses 128 pixels above the impact line, it becomes three missiles. One follows the original track, another aims two houses to one side, and the third aims either two houses to the other side or (if that'd be off the playfield) between the two. Creating a MIRV costs two missiles.
The original formula for targeting the MIRVs was as follows.
building_dx = building_x[target[new]] - building_x[target[old]] yspeed[new] = yspeed[old] xspeed[new] = xspeed[old] + yspeed[old] * building_dx
There are a couple special kinds of waves intended to provide a change of pace that surprises complacent players. Fast waves are shorter and have smaller salvos of 1 and 2 missiles that have substantially increased travel speeds to test the player's reaction time and speed of precise ABM placement. Balloon Fever waves have a salvo set of 75% balloons and 25% MIRV, moderately increased travel rates, and substantially increased missile (40 to 50) balanced by the higher cost of splitting missiles. Because all balloons come in from the left, the player is tempted to overuse Milo's silo and leave Staisy's underused. (They're named after an inside joke on a Dance Dance Revolution fan forum.)
Each second is split into ten tenths, and each tenth is split into six (NTSC) or five (PAL) frames. To spread the CPU load across multiple frames, some parts of the logic execute only on one frame of the tenth.
A building is threatened (or in "check") when all of the following are true:
housesStanding[Target] = 1
)When a missile aimed at a threatened building collides with an explosion, the building it was targeting is removed from threat. Its state may change back to threat on the next frame if another missile is targeting it as well. But because regular missiles are subject to LRU limits on attacking a single building, this usually happens for missiles split from MIRVs and balloons.
There are 12 villagers, one for each building. Each starts in its own building. If not inside its target building, each villager takes a step toward its target building every two tenths of a second. If a villager is inside a threatened building in check, the villager will run toward a nearby building that is not threatened.
For dropout control purposes, out villagers should be drawn odd first then even first in alternate frames, but this shouldn't matter too much until the player is almost dead anyway.
STATE_NEW_LEVEL
Start displaying the level's tip and copy the wave's data into the level registers.
STATE_ACTIVE
Player and enemy missiles launch only during this state. Track whether the player has lost a building during the level. Once all enemy missiles have been destroyed, stop the music, and if there is at least one silo and at least one house, go to STATE_LEVEL_REWARD
; otherwise go to STATE_GAMEOVER
.
STATE_LEVEL_REWARD
Calculate 10 points for each missile and 100 for each house, add it to the player's score, and display a tip:
Nice Job! Left: 10⌂ 12⬋ Bonus: 11200
Once the tip finishes, go to STATE_REBUILD_SILO.
STATE_REBUILD_SILO
If the player has not lost a building during the wave or the wave is the fifth in the day, and there is only one silo left, repair the other silo and display a tip "Silo repair complete". Once the tip finishes displaying, go to STATE_CUTSCENE
.
STATE_CUTSCENE
Go to the next hour. If we haven't passed 05:59, go to STATE_NEW_LEVEL
. If a house has been destroyed for the first time, and the house's owner is not the current paranoid actor, choose new actors as described in "Choice of actors" below. Then choose the cut scene based on the first of the following rules that applies: If no building has been destroyed, show the cut scene for the current day from the perfect sequence. If the damage class has increased since last cut scene, show the cut scene for the new damage class. Otherwise, show the next cut scene from the investigation sequence and then go to STATE_REBUILD_HOUSE
.
STATE_REBUILD_HOUSE
If this is not the last day (SAT), and at least one house is destroyed, choose a house that is destroyed, rebuild it, and display a tip "House rebuilt". Otherwise go to STATE_NEW_LEVEL
. But if the tip has been displayed, then wait for it to end, and go to STATE_NEW_LEVEL
.
STATE_GAMEOVER
Display a tip "GAME OVER", and zero out the game state. Once state is zeroed, the game loop ends.
After the 5 AM round of each day, the game shows a scene with the center 6 houses drawn twice as big (4x4 tiles each instead of 2x2), with their left tile at x=1, 6, 11, 16, 21, 26. (This is slightly biased to the left, but the NES's video signal is biased to the right anyway.) Houses destroyed in the game are shown destroyed in the cut scene. Villagers are standing in front, also twice as big but still only 8px tall.
There are ten villagers with two sexes and four personalities (see villager names.txt). At two points in the game, the program chooses one character of each personality. And if the paranoid and laid-back character are the same sex, the detective has to be of the opposite sex. The steps are as follows:
Once a house is blown up for the first time, if it isn't the one belonging to the chosen paranoid, then set the owner of that house as the new paranoid and choose a new laid-back and detective.
The dialog between 6 AM and the next night depends on how well the player is defending buildings. The value in Y after jsr countHousesLeft can be
Each damage class has dialogue for the first day it was seen.
The script has two branches: perfect and at least one mistake. In the later stages of perfect (Wed-next Sun), it toys with the TASing player. (grep tas /usr/share/dict/words
)
To get on track for the canon ending, the player must do well but not perfect. Player doesn't learn who's behind this until something is blown up. If the player stays perfect even through Wednesday, the villagers begin to suspect something about the silos. Are they robotic?
A 100% run will not reveal the culprit, not even in the ending. The troubador returns to the Roost and continues to play as if nothing had happened that week. Next Sunday, the game runs for 20 seconds without a missile in sight.
At the end of a game day, the game calculates the town's damage class and displays a cut scene based on the first rule that applies:
Each scene starts with 4 bytes representing actors:
Most scenes will start with 'XYZM' or the like.
Following that is a set of control codes:
Ultimately, the player will see the house rebuilt as the sun rises and sets. http://iweb.tntech.edu/rhaggard/4120s10/Project/missile_command_specs.htm
Once, I ran into a problem where temporary variables used for collision were getting overwritten by the subroutine that starts a sound effect. After that, I established a calling convention, which I call "LOCAL-8":
The music is a so-called Jimmy Hart Version of the early morning music from Animal Crossing series, with several of the melodies replaced by pieces of Ludwig Beethoven's Piano Sonata No. 8 in C minor (Pathétique). All music is in compound (swung) time at 100 (dotted?) quarter notes per minute, mostly cut time. The dissonance between the action and the music parallels the dissonance between the action and the ordinary experience during the wee hours of the morning in a sleepy little village.
Copyright © 2011 Damian Yerrick. Copying and distribution of this file, with or without modification, are permitted in any medium without royalty provided the copyright notice and this notice are preserved. This file is offered as-is, without any warranty.