TASVideos

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

Submission #2392: gocha's DS Castlevania - Dawn of Sorrow in 08:20.12

Console: Nintendo DS
Game name: Castlevania - Dawn of Sorrow
Game version: USA
ROM filename: 0121 - Castlevania - Dawn of Sorrow (U).nds
Branch:
Emulator: (unknown)
Movie length: 08:20.12
FrameCount: 30007
Re-record count: 26324
Author's real name: S.S.
Author's nickname: gocha
Submitter: gocha
Submitted at: 2009-08-31 01:34:26
Text last edited at: 2019-04-27 19:10:25
Text last edited by: gocha
Download: Download (8417 bytes)
Status: published
Click to view the actual publication
Submission instructions
Discuss this submission (also rating / voting)
List all submissions by this submitter
List pages on this site that refer to this submission
View submission text history
Back to the submission list
Author's comments and explanations:
Special Links: Youtube, NicoNico (with extra displays; watch w/o register), 日本語

Castlevania: Dawn of Sorrow is a one of famous Castlevania games, and it is also the sequel to Castlevania: Aria of Sorrow (GBA).

I recommend downloading my release package as it includes the movie file as well as other accessories such as memory watch files, lua scripts, etc.

This run aims for the fastest time to complete the game with the good ending, on normal difficulty. The run starts with no predefined save, but it completes the game in 8 minutes and 20.12 seconds, by utilizing a variant of a famous zipping glitch. The in-game completion time of this run should be 00:07:18 (26310 frames), but since game timers have been overwritten by a glitch, it is shown as 00:43:43 after the game has been completed.

About the run

The run completes the game in the following process.

  1. Prologue
  2. Meet Yoko and Julius, obtain Magic Seal 1
  3. Obtain Axe from Axe Armor
  4. Defeat Flying Armor
  5. Defeat Balore
  6. Save game for later glitch use
  7. Obtain Magic Seal 2
  8. Defeat Dmitrii
  9. Perform zipping to collect achieve things and suspend/restart the game
  10. Go to Warp Room and warp to The Abyss. The castle will self-destruct in a few seconds

It is well known that the famous zipping glitch, which is called Succubus glitch, allows you to obtain a bunch of souls and items immediately. That Succubus glitch is used in a few of speedruns. However, they needed to get to The Pinnacle to obtain Succubus' soul.

While making this run, I invented a variation of Succubus glitch, a method to interrupt special attack by a cutscene. It allowed me to perform a zipping much earlier than before. Moreover, I enthusiastically investigated what can be done by the zipping, and I finally concluded that the last warp room can be activated and also Menace can be skipped.

Since the emulator generates a ridiculous amount of lags, I did not mind lags and 1 frame losses very strictly (still I generally did my best, of course!). Instead, I tried to optimize the whole route/strategy hard, and also to discover general tricks of the game.

Tricks

Here I show you what I have found.

Backdash

There are three methods of move, backdash-jump, forward-backdash-blank and backdash-crouching. I compared their average speeds to see which is faster. I show the comparison on flat ground below.

  • Backdash-jump: (13784+13232+12680+12128+11576+11024+10472+9920+9368+8816+8264+7712)/12 = 10748
  • Forward-backdash-blank: (6144 + 13784 + 11384)/3 = 10437.3333
  • Backdash-crouching: (13784+13232+12680+12128+11576+11024+8624+0)/8 = 10381 (8 frame pattern = fastest one)
  • Additional note: Replacing crouching to subweapon use seems to be slightly faster if it does not lag. It will greatly decrement your MP, though.

That is why Soma jumps again and again. Crouching is used as an alternative move method, when Soma is on a downslope, or when Soma wants to jump earlier. Sometimes, it is also used for some luck-manipulations.

Actually, I also considered about one more method, "forward, backward + backdash, release". It has never been used since it was slower than the two methods above.

Motion cancels

  • Backdash can cancel an attack motion. It is a well-known behavior.
  • Landing can cancel an attack motion of some weapons. It is a well-known behavior, too.
  • Axe Armor's ability can cancel a landing motion after damage.
  • To cancel Black Panther's ability just before landing can cancel a landing motion.

Randomness

Some rooms (more precisely, enemies, backgrounds, and other effects) change the randomness on every frame, some rooms do not.

Soma can affect the randomness at least by a normal attack (changes it once), backdashing (sometimes changes it while doing that), or turning around (changes it once). It cannot be changed by jumping, crouching, or using a soul that I used in the run. Backdash+crouching is a handy way to manipulate randomness without losing speed much.

The recurrence equation of RNG is identical with later 2 DS games, Portrait of Ruin and Order of Ecclesia. Also, it is almost identical with Aria of Sorrow. It is a sort of linear congruential generator. The following C code emulates the behavior of the RNG.

  static int32_t x = 0; // $020c07e4
  int32_t rand() {
      x = (x >> 8) * 0x3243f6ad + 0x1b0cb175;
      return x;
  }
I wrote a Lua script that displays how many times the RNG is called in a frame (I learned about the implementation of RNG after I finished the run, so the script was not used for the run).

Crystal blocks

Crystal blocks are shattered by touching the screen (Balore's soul needed). In a tool-assisted speedrun, so many blocks can be shattered immediately, by moving the stylus incredibly fast.

Go down floating footholds without losing speed (not used)

Here is the demonstration video (youtube).

I just discovered it after I finished the run, so I cannot tell you the detail at present. I assume that it happens under a limited pixel conditions. This trick might improve the run a little. I hope it will because it looks good.

Activate a switch behind the wall (not used)

One of famous glitches. The Cutall/Cinquedea/Alucard Sword's special attack is teleporting behind an enemy and stabbing it. By utilizing that, you can activate a switch, which is on the other side of the wall.

Infinite jump glitch (not used)

http://www.youtube.com/watch?v=HoyLggIDa9g

I don't know the detail since I have never had a look at it.

Zipping: General info

When Soma goes outside the room, the game writes "visited" flag to abnormal location. As a result, it causes various things like the run has done.

In other words, the write address is determined from Soma's location. I studied how to calculate the exact write address from Soma's position, and wrote up a lua script which shows the write address in realtime. It definitely helped me to consider the optimal route of the zipping part.

When Soma goes to the right as long as one room, the write bit gets shifted to the left. However, the range of the write address changes per 16 rooms (i.e. 2 bytes). Read the script below for details.

  -- Address view for memory writing with zipping
  -- Open the memory viewer to see what's actually going on.

  if not emu then
    error("This script runs under DeSmuME.")
  end

  if not bit then
    require("bit")
  end

  function cvdosPosToMapFlag(x, y)
    x, y = x % 256, y % 256

    local xl, xh = x % 16, math.floor(x / 16) % 16
    local i = (y * 16) + (xh * 46 * 16) + xl
    local pos = 0x20F6E34 + math.floor(i / 8)
    local mask = math.pow(2, math.floor(i % 8
    return pos, mask
  end

  gui.register(function()
    local x = memory.readbyte(0x0210F018)
    local y = memory.readbyte(0x0210F014)
    local i = (y * 16) + x
    local pos, mask = cvdosPosToMapFlag(x, y)
    agg.text(140, 5, string.format("%08X:%02x", pos, mask
    agg.text(140, 24, string.format("[%04X-%04X]", cvdosPosToMapFlag(x - (x % 0x10), 0) % 0x10000, cvdosPosToMapFlag(bit.bor(x, 0x0f), 255) % 0x10000
    agg.text(140, 43, string.format("[%04X-%04X]", cvdosPosToMapFlag(x - (x % 0x10) + 0x10, 0) % 0x10000, cvdosPosToMapFlag(bit.bor(x, 0x0f) + 0x10, 255) % 0x10000
    agg.text(140, 62, string.format("(%03d/%X,%03d)", x, x % 16, y
  end)
Here are some of addresses I planned to (not) manipulate in the run.

Address Size Description
020F70D7 lower 4 bits Yorick
020F70E0 lower 4 bits Succubus
020F70E1 lower 4 bits Erinys
020F70EB higher 4 bits Black Panther
020F70F3 higher 4 bits Final Guard
020F70FC higher 4 bits Golem
020F70FD higher 4 bits Lilith
020F7104 higher 4 bits Draghignazzo
020F7109 lower 4 bits Stolas
020F710A higher 4 bits Malphas
020F710B lower 4 bits Doppelganger
020F710B higher 4 bits Rahab
020F710C lower 4 bits Hippogryph
020F710C higher 4 bits Procel
020F710D lower 4 bits Mud Demon
020F71E2 lower 4 bits Cutall
020F71E2 higher 4 bits Cinquedia
020F71ED lower 4 bits Kaladbolg
020F71F2 higher 4 bits Claimh Solais
020F720E lower 4 bits Dracula's Tunic
020F7216 higher 4 bits Death's Robe
020F721B lower 4 bits Rosary
020F7226 lower 4 bits Chaos Ring
020F6E20 1 byte Room X position (for start from suspend)
020F6E22 1 byte Room Y position (for start from suspend)
020F6DFC 4 bytes If the value bitand 0x44000007 is non-zero, disable Suspend
020F7018 4 bytes X position for start from suspend
020F701C 4 bytes Y position for start from suspend
020F703C 4 bytes Ingame time
020F7187 bit2|bit3 (04|08) Save Room & Warp Room first time message flag
020F718A 1 byte Menace related flags ($30 is the best value to skip him)
020F71A8 2 bytes Activated warp destinations (bit11/$0800 = The Abyss)
020F7228 2 bytes * 6 Button settings
020F7256 2 bytes Disable Suspend/Pause (Julius Mode)
020F7259 1 byte Hard Mode if nonzero

Note: As you can see in the run, Soma can move through the wall by sliding.

Zipping: The Succubus glitch and its variations

All of these glitches cancels a special attack halfway to go into the wall. The difference is only how to cancel an attack.

The steps to achieve the most famous Succubus glitch are:

  1. Equip Cutall/Cinquedea/Alucard Sword and Succubus
  2. Use its special attack then cancel the motion by Succubus immediately
  3. Walk/Attack for about 2.5 seconds (do not stop, jump, backdash, and so on. It's important)
  4. Use the special attack again against the wall
  5. The special attack will be canceled in the wall if it succeed

Axe also can be used to perform the glitch. Here is a demonstration video (youtube). When you use Axe, you'll need to switch your equipment during the glitch, because Axe's special attack is too long.

Axe also can be used to perform the glitch. However, you'll need to unequip the Axe once after you used a special attack (it's good to use Doppelganger to unequip a weapon quickly, by the way), because Axe's special attack is too long.

A cutscene after the boss fight also cancels the special attack (it's the core of the run). It can be used earlier since it doesn't require a Succubus' soul.

Additionally, there are some special locations you can perform the zipping (flat ground + door, narrow gap + Skeleton Ape): http://www.youtube.com/watch?v=lkohuZnKPAg

See also: Castlevania: Dawn of Sorrow - Glitch Locations

Memory addresses

Most of the zipping related addresses are shown above.

Address Length Description
020CAA40 4 bytes X position
020CAA44 4 bytes Y position
020CA95C 4 bytes X position (next)
020CA960 4 bytes Y position (next)
020CA968 2 bytes X velocity
020CA96C 2 bytes Y velocity
020C07E4 4 bytes Random number
020F703C 4 bytes Ingame frame
020CA9F3 1 byte Soma invulnerability 1
020CAA24 1 byte Soma invulnerability 2
020F7410 2 bytes Current HP value
020F7412 2 bytes Max HP value
020F7414 2 bytes Current MP value
020F7416 2 bytes Max MP value
020F7448 4 bytes Current EXP value
0210AF42 2 bytes Left of sprite hitbox
0210AF46 2 bytes Right of sprite hitbox
0210AF44 2 bytes Top of sprite hitbox
0210AF48 2 bytes Bottom of sprite hitbox
020F2A88 1 byte Magic Seal Step
020F2A8C 1 byte Magical Seal Substep
020CED88 4 bytes Succubus timer

The following addresses might change randomly.

Address Length Description
020D36A8 2 bytes Flying Armor HP
020D3513 1 byte Flying Armor invincibility #1
020D3514 1 byte Flying Armor invincibility #2
020D3515 1 byte Flying Armor invincibility #3
020D26E8 2 bytes Balore HP
020D2553 1 byte Balore invincibility #1
020D2554 1 byte Balore invincibility #2
020D2555 1 byte Balore invincibility #3
020D2EC8 2 bytes Dmitrii HP
020D2D33 1 byte Dmitrii Invisibility #1
020D2D34 1 byte Dmitrii Invisibility #2
020D2D35 1 byte Dmitrii Invisibility #3

Also, I posted some info about cheat codes before.

Stage by stage comments

Prologue

In fact, the first Skeleton can be defeated 1 frame faster, by not jumping at second backdash and sliding earlier.

Golem battle is one of my favorite parts. Soma attacks him with insane speed.

Lost Village - Up to Flying Armor

Actually, Soma moves faster than a bone of Skeleton's soul. So it's rather difficult to throw a bone optimally. After all, I tested all patterns I came up with. I am not so smart :P

It might be better to defeat Peeping Eye by using Knife (with backdash and 2 frame jump) instead of Armor Knight, but I am not sure.

The Axe Armor room is very luck-manipulative room. You need to manipulate the randomness to obtain Axe Armor's soul and Axe, and also to manipulate Zombies' positions. I manipulated the randomness hard by brandishing a knife here and there, but I could not manage to eliminate one zombie who is just after Axe. Also, this is the first room I really wanted a lag-free emulator :P

Upgrading Axe Armor's soul here (and possibly in Wizardry Lab) might save time later (if a lag-free version of the emulator is used). Perhaps it will make that luck-manipulative room even harder. *shivers*

Stylus can be used in the menu screen. It is sometimes faster than using keys.

Lost Village & Wizardry Lab - From Flying Armor, up to Balore

As Atma told me in the forum, in the Flying Armor battle, I need to manipulate him to position as low as possible to make attacking him easier, and defeat him with scrolling to the left as far as is possible. I tried hard but I could not get to the most left side of the room. A better luck might improve the battle a little.

You may think that I can perform the cutscene zipping with Flying Armor. That is right, but I cannot do anything during the zipping so that it takes a few minutes to return. Additionally, I can get nothing there (the range of write address: 020f6e34-020f7033).

After I used Flying Armor, I switched it back to Armor Knight soon, to make the Balore battle a bit faster and to cancel damage motions. I considered that it is faster than keeping Flying Armor equipped.

If I can go down floating footholds without losing speed here and there, it will save 10-20 frames.

Wizardry Lab & Garden of Madness - From Balore, up to the save room

Balore is defeated without Mind Up. It makes the battle about 3 seconds longer, but later I can gain about 10 seconds. After I defeated Balore, there is a chance to leave a message on crystal blocks. However, I did not do that since it lags too much. This is one of obvious improvable point, isn't it? ;)

I used two Potions after the Balore battle, but I guess it might be a mistake. Reducing the amount of damage might make the run faster, rather than potion use.

In the Slaughterer room, it might be better to take damage instead of defeat them. It gives Soma less exps, and it might allow us to defeat more enemies later. By the way, it was a little hard to manipulate Slaughterer's position and hitbox. If you want to make a tas of the game, I suggest to you writing a hitbox display lua.

To activate the suspend command, I saved the game in Garden of Madness. Particles in the room might affect the time, but I really did not care. Even a zipping cannot skip this process. That is known via memory value.

Garden of Madness & The Dark Chapel - Up to the end of the Dmitrii battle

I didn't defeat enemies much because it causes a levelup and it freezes Soma for a few seconds. Also, I didn't equip Breastplate because it takes time a little to equip and I assumed that it doesn't save time after all.

I did not go up until the last axe hits Yorick. If I go, the collision detection will be skipped and I cannot defeat him.

Outside of the world - The zipping part

It's the most difficult section to explain... Well, read the general info section about zipping above first of all.

What I did in the run are:

  1. Obtain Black Panther
  2. Obtain Hippogryph (optional; I think it saves time rather than not use it, or more than obtaining Malphas instead)
  3. Set $30 to $020F718A to skip Menace (as a result, the game considers the first conversation and the battle are already done)
  4. Activate the warp to The Abyss

What I did not do in the run (because it seems to take time to do that) are:

  • Obtain Malphas
  • Skip the "Warp Room" description of the first time

I sometimes stopped to not overwrite the starting position after suspend much.

I constructed this route in the following steps:

  1. List up all possible useful locations (and dangerous locations as well)
  2. Divide them into 4 groups (odd number address or even number address, in higher 4 bit or in lower 4 bit)
  3. Count the minimum horizontal distance to get to each location, and group them by it (in the 16-bit alignment)
  4. See what is near/far each other and consider about how to visit them

One vertical loop takes a few seconds, so that I think it is not so smart to wait again and again to visit more locations.

The finale

In the room of lift, I compared which is faster, going from the upper or lower. They were the same.

When I fall from high position, I cancel Black Panther immediately just before the landing and cancel the motion.

Comments

I had never thought that I would invent such a odd route. In fact, before I met DeSmuME-rerecording, I had never considered about the speedrun of the game.

One day, I wanted to try recording a DS TAS movie with a new emulator, so I TASed the very beginning part of this game (the first battle against three enemies) just for curiosity. I learned some of the basic mechanisms of the game through the recording, and it told me that I can improve Atma's demonstration TAS in the forum. This is why I started working on the game suddenly. I had never expected that I would make a Castlevania TAS.

After I decided to work on the game, I watched Groobo's semi-TAS video on YouTube (and Satoryu's non tool-assisted speedrun).

The video completes the game in 28:58, by utilizing famous two glitches. One is a way to open a gate from the opposite side of a switch by Cutall's special attack, and the other is the one called "Succubus glitch" which allows us to go through/into a wall, and get a bunch of souls and items (details are described later). My original aim was to optimize his speedrun, and I assumed the completion time would be 20+ minutes at best.

However, that was not true. I'd like to thank all people who supported/encouraged me. I could not make the run without them.

Special thanks

  • Satoryu: for his non tool-assisted speedrun
  • Groobo: for his semi tool-assisted speedrun
  • People in the Dawn of Sorrow topic: You guys are always kind. Especially, I thank Atma for posting his first TAS attempt of the game. That motivated me a lot.
  • #TASers: A Japanese IRC channel. They motivate me always! Especially, I thank pirohiko for inventing a new style of video editing! ヽ(>ヮ<)

Hope you enjoy the run, thank you!

Screenshots

gocha: Hi! I am an idiot. I took a few screenshots of this movie and placed them here. Here goes! Feel free to clean up the list.


adelikat: Accepting for publication under one condition. A video like the one on the nicovideo be the published MKV.

ShinyDoofy: Processing...


Similar submissions (by title and categories where applicable):