TASVideos

Tool-assisted game movies
When human skills are just not enough

Game Resources / DOS / Captain Comic

Movies

Added [Tier: Moons][Fastest Completion][Has commentary]DOS The Adventures of Captain Comic: Episode 1 - Planet of Death (any,r1) by David Fifield & Kabuto in 06:30.98 (2020-12-04)

Versions

The Adventures of Captain Comic is one of the earliest arcade-style platform games for DOS. There are five revisions of this game. Later revisions fix bugs that are useful for TAS, so it's best to stick with Revision 1.

The DOS version is the original version of the game. There is also an NES port, which is completely different from the DOS one. It uses a completely different engine and even the levels look like they were completely remade.

There is a sequel for DOS, Captain Comic II: Fractured Reality.

Objectives

To win, the player must collect the three treasures: Gems, Crown, and Gold. These are the only items the game checks for. Once all three are collected, the game starts a countdown timer for 20 game ticks, after which the game-end sequence begins.

Mechanics

Unlike many DOS games, Captain Comic is not synchronised to the VGA refresh. Instead, it runs at a fixed "tick rate" of about 9.1 ticks per second, controlled by the programmable interval timer (IRQ 0). The precise tick rate is 14318180 / 12 / 65536 / 2 ≈ 9.103 Hz, with each tick therefore having a duration of 1 / 9.103 ≈ 110 ms. 14318180 is the frequency of the CPU's base oscillator; dividing by 12 gives the frequency of the base oscillator of the programmable interval timer chip; 65536 is the frequency divider used (the game doesn't touch this, but leaves it at its default); and dividing by 2 accounts for the fact that the game only updates on every other cycle of the interval timer (see the variables irq10_parity and game_tick_flag in the disassembly).

Long ticks and a lack of complicated processing mean that lag is not a consideration in this game.

The basic unit of distance in the game is 8 pixels, or ½ of a tile. Captain Comic is 2 units wide and 4 units tall. All enemies and items are 2 units wide and 2 units tall.

There are 8 levels in the game, each consisting of 3 stages. Every stage has a fixed size of 256×20 units. Comic moves at a speed of 1 unit / tick when walking. It takes 254 / 9.103 ≈ 27.9 s to walk from one extreme of a stage to the other.

The game sets a checkpoint whenever Comic crosses a horizontal stage boundary or goes through a door. When you die with lives remaining, you respawn at the latest checkpoint.

Tricks

Enemy logic

Each stage has up to four enemies, each one having one of five behaviours:
  • "Bounce": Move diagonally, bouncing off solid map tiles and the edges of the screen.
  • "Leap": Jump towards Comic, under gravity. Bounce off solid tiles and the left, right, and top edges of the screen, and fall off the bottom edge.
  • "Roll": Roll towards Comic when there is ground, fall when there is no ground.
  • "Seek": First move horizontally to match Comic's x-coordinate, then move vertically to match his y-coordinate.
  • "Shy": Move diagonally, bouncing off the left and right edges of the screen. Vertical movement depends on which way Comic is facing: if facing towards, fly up; if facing away, fly toward Comic (up or down).

An enemy may be "slow" or "fast". Slow enemies move every other tick. Fast enemies move every tick, like Comic does.

Each enemy has its own respawn timer. When entering a stage or respawning after dying, the respawn timer of all enemies is set to 20. (The enemy spawns when its timer would go below zero, so a timer initialised to 20 means the enemy will actually spawn 21 ticks later.) There are two global variables that govern enemy spawns: enemy_respawn_counter_cycle and enemy_respawn_position_cycle. These two variables are never reinitialised and their values carry across stages and levels. When an enemy is destroyed, its respawn timer is set to the current value of enemy_respawn_counter_cycle, and enemy_respawn_counter_cycle is advanced in the cycle 20, 40, 60, 80, 100. enemy_respawn_position_cycle goes in a cycle 0, 2, 4, 8. When an enemy is scheduled to respawn, it first advances enemy_respawn_position_cycle, then tries to place itself at a distance of enemy_respawn_position_cycle units offscreen, in the direction Comic is facing. If it turns out that the enemy cannot be spawned, enemy_respawn_position_cycle is advanced nonetheless.

Manipulating enemy_respawn_position_cycle is pretty easy because you can make it advance rapidly just by spawn-blocking enemies. Manipulating enemy_respawn_counter_cycle requires more advance planning because it advances only once per despawn. Enemies despawn when they are shot, when they collide with Comic, when they fall in a pit ("leap" and "roll" enemies only), or when they get 30 or more horizontal units away from Comic.

Rules for spawning enemies (useful for knowing how to manipulate them):

  • Only one enemy may be spawned per tick. If another enemy has already been spawned this tick, skip this enemy.
  • Compute the enemy's horizontal position by going enemy_respawn_position_cycle units past the edge of the screen, in the direction Comic is facing.
    • If the horizontal position would be below 0 (i.e., past the left edge of the stage), skip the enemy.
    • There is logic that is trying to do the same thing for the right edge of the stage, but it has a bug. Instead of skipping when the position would be 256 or greater, it skips when the position of the left edge of the screen is below 128, and the enemy's position would be greater than or equal to 128. This creates a "dead zone" near the middle of every stage, where enemies never spawn, as long as Comic is facing to the right. Enemies may still spawn off the right edge of the stage: they actually end up spawning near the extreme left edge of the stage, then despawn one tick later, because they are too far away from Comic.
  • Look for a non-solid tile directly above a solid tile, starting at the level of Comic's feet and searching upward. If no such tile is found, skip the enemy. Enemies never spawn below the level of Comic's feet or in mid-air.
  • All four enemy slots are considered in order on each tick. If an earlier enemy is already spawned or skips spawning this tick for some reason, it gives later enemies a chance to spawn.

The enemies themselves have small bugs too, for example some fast enemies become slow after 254 ticks, and bouncing enemies sometimes bounce out of the level horizontally and get despawned.

Collision detection oddities

The game engine only distinguishes solid and non-solid tiles. It makes sure that you can't enter any solid tiles moving vertically; however when moving horizontally only the foot level is checked for collisions. You can see this, for example, right at the start of the game: you can just walk into the first platform and then jump up onto it, whereas you can't jump through the second platform, even though they are identical in terms of solidity.

Hover glitch

Holding the jump key when starting the game, or respawning after dying, allows the player to jump very far: the jump counter that normally restricts upward acceleration to a few frames for a normal-sized jump is in these cases initialised incorrectly and allows accelerating upward for 255 frames, which is long enough to traverse an entire stage. You can even let go of the jump key for a while: as long as the ground isn't touched for more than 1 tick, the counter isn't reset (but it still keeps on counting down). Touching the ceiling resets your vertical velocity, but touching the top of the level does not, and holding the jump key there for too long will lead to your vertical velocity underflowing from a large negative number to a large positive number, sending you downward so quickly that on the next tick you will be almost at the bottom of the screen—and if you don't land on anything there, you will be below the bottom screen and dead in the following frame.

The hover state can be carried across stages but not through doors, since you can only enter the door when on ground.

The hover glitch works in Revisions 1 and 2. It doesn't work in Revisions 3, 4, and 5.

This glitch, along with exploiting collision detection, can be abused to collect the Crown without playing the entire castle level. The Crown is located right at the start of the castle, protected by an L-shaped wall. You can, however, suicide after entering the level, then hover to the corner of the L, with your head at the height of the horizontal piece of the wall and your feet below it. You may then hover to the right and your head will glitch into the wall (since only your feet are checked for collisions at this point), and once you have hovered beyond the vertical part of the wall you can just fly upward, because only the tiles above your head are checked for collision when moving upward.

But once you are in this area you cannot easily escape. You can do one of these options, ordered by increasing time:

  • Make the Crown the third and final treasure, so the game ends and there is no need to escape.
  • Use the Teleport Wand to teleport downward.
  • Continue hovering against the top of the screen until your vertical velocity underflows and you fall off the bottom of the screen, to respawn at the entrance door.
  • Spawn enemies in the upper area in order to take damage from them and respawn at the entrance door (testing shows this to be slower than velocity underflow).
  • Take the door and traverse the whole level.

Teleport-run-left trick

The Teleport Wand is meant to move Comic 6 units in the direction he is facing. The teleport animation takes 6 ticks, so teleporting is nominally no faster than Comic's walking speed of 1 unit per tick. But the destination of the teleport is always rounded (leftward) to an multiple of 2 units. This means that if you start a teleport while standing between tiles (i.e., at an odd x-coordinate), a teleport actually moves you 7 units over 6 ticks, which is slightly faster than walking. Each time you do this, it saves 1 tick, but also Comic moves 1 unit closer to the left edge of the screen, and when you get too close, you can no longer use the trick. Teleporting to the right can never save time, but can lose time if you do it at an odd coordinate.

In Revision 1, this trick also allows for obtaining the Lantern early (apart from the hover glitch), because it allows for teleporting across a 6-unit-wide gap that wasn't supposed to be crossable that way.

Route

This is the route used in [4345] DOS The Adventures of Captain Comic: Episode 1 - Planet of Death (any,r1) by David Fifield & Kabuto in 06:30.98. It's quite likely that this is the fastest route possible in Revision 1 and 2; see the discussion of algorithmic route optimization in #6944: David Fifield & Kabuto's DOS The Adventures of Captain Comic: Episode 1 - Planet of Death in 06:30.98.

A diagram showing the route

The route requires seven intentional deaths, but there are more than enough extra lives on the way. Each treasure is a 1-up, as are Shields collected while at full HP. Certain score levels also aware an extra life.

The major difficulty is manipulating enemies for suicide warps/hover glitches. Manipulating enemies to just get out of our way is rather trivial.

Ideas for improvement:

Resources

Various programs, Lua scripts, disassemblies of all five revisions, and other resources are in a Git repository:

   git clone https://www.bamsoftware.com/git/comic.git
   cd comic/tas/
Some large or static files are not cloned by default. To download them, you need git-annex:

   git annex get
Among the files is a hud.lua script that permits you to advance time tick by tick, and see the values of hidden game variables.



Combined RSS Feed
GameResources/DOS/CaptainComic last edited by Sand on 2020-12-27 19:11:47
Page info and history | Latest diff | List referrers | View Source