Movies
Versions
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
irq0_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 most recent 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).
Besides its behavior, 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
- Walk right, collect the Door Key, then immediately enemy suicide warp back to the last stage start. Return to the castle.
- In the castle, enemy suicide and hover into the Crown room, velocity underflow suicide warp back to the entrance, then exit and take the door to the lake.
- Walk to the left past one stage transition. At the next stage transition, cross, cross back, then fall in a hole to initiate hover. Hover leftward and fly all the way to the door leading to the cave.
- In the cave, jump in a hole then hover up to the first door. On the other side of the door, enemy suicide hover out of the pit, collect the Gold, and go to the right to collect the Teleport Wand. Suicide warp back to the left edge of the stage and retrace your steps back the cave entrance, doing left-teleports as much as possible. It is equally fast to collect the Gold before or after the Teleport Wand.
- Walk to the base door, enter the base, walk right and teleport to the basement door. On the other side of the door, teleport up to the top level and walk to the space door.
- Move left and collect the Gems. You can end input early by finding the x-coordinate at which you need to jump, then buffering a jump input through a left-teleport that leaves you at that coordinate.
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:
- In the absence of new discoveries, the segment most likely to be improvable is the beginning part of the cave. The damage manipulation there is tricky because of the HP refill right in front of the door. Finding a way to take even one additional point of damage before entering the door would save time.
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.