Tag Archive: assembly


Quick Gun Modding

I didn’t have a lot of time either this week, but fortunately this blog post isn’t empty!

Here are two simple hacks that probably take up no more than 60 lines of code each. As you can see, I was being really lazy aiming for simplicity. For each mini-mod, just use the fireball and try to attack something.

(To avoid revealing new content inadvertently, these hacks are applied to plain copies of Cave Story instead of the current version of the Witching Hour.)

Fortunately, gun hacking is pretty straightforward as long as you understand what you’re doing. In both cases, the gun logic and the bullet logic is modified for maximum control over the weapon. I’ll probably add more frames (i.e. sprites) and give the bullets some fancier behavior later.

Well, not much else to say, since there hasn’t been spriting or TSC-ing this week. Ah, whatever. See you next Saturday.

Ice Monsters

I’ve created these monsters quite some time ago (you can even see their sprites in my forum sig), but I haven’t talked about them at all. I think they’ll be a good way to fill some time while the CS+ craziness goes on.

First up are the ice roaches. The artwork for these critters is really simple – just a recoloring of Pixel’s unused gaudi sprites. Well, they were unused some number of years ago, but now you can actually see these new gaudis in CS+ Wind Fortress, I believe.

Why am I talking about CS+ so much? I must be going insane. Really insane. Surely I’m turning into the kind of mentally psychotic person that you don’t want your parents to see. Err… anyway let’s get moving with some more mod discussion.

I’ve given the ice roach some special behavior using that magical language known as assembly. He can now shoot projectiles at you (which are the same projectiles that those “jumping beans” shoot in the Witching Hour’s sandy desert region), and he flies with a vertical wobble, for a more organic-looking motion. Bouncing off the walls is also a plus.

Here’s a second monster, a much more interesting one in my opinion. The ice eye.

This guy can fly pretty well, and he also has a special weapon: bomblets. He’ll drop one of these small bombs every so often, which explode when they impact the floor, so be careful if you’re staying on the ground.

And those are the new enemies for the floating cities area. So that concludes my post. I’m not sure what I’ll be doing next week, but surely I’ll think of something. Goodbye for now, and see you next Saturday.

Weapon Repairs

Sorry that today’s blog post is a bit late. This week I’ve fixed up a weapon planned for the new release. This weapon is the burst capacitor, an energy gun that was available for testing at the very end of Witching Hour Demo 1.1.

For the upcoming Demo 1.2, I changed the animation of the burst capacitor so that the energy blast renders on top of tiles and NPCs instead of below them. This means that burst-capacitor bullets will not suddenly appear ‘underneath’ doors and savepoints, which used to look really weird.

This involved doing some assembly work where the bullet code actually communicates with the health bar to get the animation to appear on the correct layer of the screen. Since the health bar code can render anywhere on the game screen, this works out nicely. The burst capacitor also behaves in a weird way for a weapon: when the bullet is destroyed (when it damages an enemy or times out), the sprite doesn’t disappear but instead persists to finish off the animation.

Animation of the Burst Capacitor's Bullet

Now, I could give you a block of assembly code to read, but I realize that’s a great way to put a lot of people to sleep through the boredom factor, so I have something different this time. You can now download a mini-mod of version 1.2 and test out the newest version of the weapon. Give it a go. This mini-mod also includes a redesigned health bar for the newest version, if any of you would like to see that.

Download Demonstration – Test the New Burst Capacitor

I’d like to say that the burst capacitor is heavily inspired by Daniel Remar’s “Resonance Detonator” from his freeware game Iji. If you haven’t played Iji yet, go grab a copy now, since it’s a great game.

That’s all folks! See you next week.

Splitting the Atom

What does the word “atom” mean, and what does it have to do with The Witching Hour in this case? Normally, when you hear of the word “atom”, you’d think of some small component of matter, and these pieces of matter dominate the Earth as we know it.

Atoms

An artist's impression of what atoms look like. No, they don't actually look like colorful pieces of candy.

That’s great and all, but “atom” has a more fundamental meaning. The first part, “a-“, means “not”. The second part, “-tom”, means “to cut”. Atoms are supposed to be “uncuttable”, meaning that they cannot be broken down into smaller parts. Today, we realize that atoms can be split, so the name isn’t very good anymore. Splitting atoms is a great way to build things that can blow stuff up, but we’re not here to discuss such matters.

What does it mean for a TSC command to be “atomic”? It’s uncuttable – meaning it cannot be broken down into smaller TSC commands. This is true of practically all commands. Take the commands <MOV and <WAI. The Cave Story command <MOV will move a player to a new set of coordinates on the current map. <WAI will pause the TSC script for a certain amount of time.

<MOV0046:0022<WAI0600

The difference between the two is that <MOV takes almost no time to execute (computers are fast, after all), but <WAI is purposely designed to take time to execute… that’s its only goal.

Do you remember multi-threaded TSC? It’s still in the primitive stages of development, but now it’s possible to let either the user or modder run 2 TSC events at the same time.

Here’s how multi-threaded TSC works. It’s actually a not-so-complex mechanism:

  1. Run the first command of Event A.
  2. Run the first command of Event B.
  3. Run the second command of Event A.
  4. Run the second command of Event B.
  5. and so on…

If all TSC commands ran in a split-second, this would work out just fine. But the many commands that have side effects, like <WAI or <MSG, will cause problems because they will prevent the other event from running. It takes some time to get through <WAI, and it takes some time to get through <MSG (because the player must wait for the message box to show all its text and then close).

To make multi-threaded TSC run as smoothly as possible, we need to ‘split the atom’, so to speak. If each command with time-based side effects could be chopped into a bunch of smaller commands, that’d be great. Here’s an idea for manipulating <WAI into a non-atomic command:

I think the idea to making WAI non-atomic is to make it a self-modifying TSC command: <WAI0500 should wait for 1 tick, modify itself to be <WAI0499 (by changing the big TSC string itself), and then not update the script position.

The script position should only increased by 8 when <WAI finally reaches 0000. Each <WAI command will split itself (essentially) into a bunch of 1-tick <WAIs, which means individual <WAIs will not clog up threads.

EDIT: Actually there is an issue with this particular implementation of non-atomic WAI. When an event is called the first time, the WAIs will work fine, but when the event is called again, all its WAIs will look like <WAI0000. To fix this, each WAI must have a method for storing the original number of ticks and resetting itself once 8 is added to the script position. This could be done by reserving a special hex byte, such as 0x00, that will signify the instruction is a non-atomic WAI.

In other words, <WAI0500 will transform into <(0x00)(0x01F4)0499 once executed. The first part is 0x00, which signifies that this instruction is still WAI. The second part holds the original number of ticks, 0x1F4, which is 500 in decimal. The rest are ASCII bytes that are decremented accordingly until they reach 0000. Once that happens, the command is reset to <WAI0500, the parser moves on, and all is well.

Whoa… technical information overload. Don’t freak out if you don’t get it because most people won’t understand it anyway. Instead of letting <WAI wait for the full time all at once, we can make <WAI run only a little bit at a time so that it’s not an unsplittable command anymore.

Thanks for reading this (rather huge) chunk of text. I should have more pictures next time… at least I hope I will. Have a good week everybody!

Boss & TSC Engine Modifications

That boss from the last post… yes his name was Minoss. Maybe I chose it because Minoss sounds similar to Minotaur, and this guy attacks rather aggressively. His behavior is here:

  • Step 1 = Randomly choose a step from step 2 to step 6. Go to that step.
  • Step 2 = Walk around. At a random time, go to step 4 or step 1.
  • Step 3 = Run faster and jump in the air. Will slow down to regular speed quite quickly. After a while, go back to step 1.
  • Step 4 = Fire weapon. This will only fire a single bullet in the direction Minoss is facing. Go back to step 1.
  • Step 5 = Rapid fire. This will fire a stream of bullets for a short time. Go back to step 1.
  • Step 6 = Super barrage. Jump in the air, and fire a big cloud of bullets (Most powerful attack). Go back to step 1.

As you can see, the boss starts off at step 1 when the fight begins. Step 1 will lead to all the other steps (2 through 6) by randomly choosing one of them. All the other steps will go back to step 1 to repeat the cycle. So you might see Minoss walk around, maybe jump, maybe fire some bullets, and then possibly go for some big attack. Or perhaps he will go for the big attack first. It all depends on the random number generator.

Now, Minoss’s code is rather huge, and he’s the guy who caused the birth of the Doukutsu Assembler because I got so annoyed at rewriting his calls and jumps whenever I needed to fix a bug.

I’ll give you a small piece of his code right here. This is “Step 4”, where Minoss fires a single bullet and then goes back to step 1.

:state4
PUSH 0
PUSH 0
PUSH 0
PUSH 0
CMP [EDX+4C],0   ;If direction is 0, fire left.
JE :fire_left
PUSH 750
JMP :next1
:fire_left
PUSH -750
:next1
MOV EAX,[EDX+C]  ;Boss's y-position.
ADD EAX,400
PUSH EAX
PUSH [EDX+8]     ;Fire the bullet at my coordinates.
PUSH 7B
CALL 46EFD0
ADD ESP,20
PUSH 1
PUSH 36
CALL 420640      ;Play firing sound.
ADD ESP,8
MOV EDX,DWORD [EBP+8]
:goto_beginning
MOV [EDX+74],1
JMP :set_velocities

Now, what other weird things did I also accomplish during this week? To give you an idea, think about how Cave Story cutscenes and events work in general. If you are a modder, you should be able to comprehend the following TSC script:

I’ve finished up a proof-of-concept assembly hack that lets you run two events at (essentially) the same time. It does this by modifying the TSC engine in slight ways and introducing a couple of new commands for the functionality.

If you would like more info, look at this thread on the CS Tribute Forums.

Ack, maybe that was too much assembly for a single day. I’ll probably have some art ready by next Saturday. See you later.

Autoplatforms

Okay, the blog is finally here. I have no idea why this took forever, but of course you don’t want me to blab about the boring aspects of setting up a site like this, do you?

What’s this blog about? The Witching Hour of course. I’ll let you do the clicking around to figure out what this mod entails, but here I’m gonna jump right in.

Dome Computer

There we go. Some progress right? It’s a simple resprite of Cave Story’s blue-ish computer that you see in Arthur’s house and other places. I went for a dome shaped screen because interesting appearances come out of impractical design features.

Computers would be rather useless if they didn’t activate something. That’s why I designed the “autoplatform”.

Autoplatforms

It’s a custom NPC that can move in a simple oscillating pattern. By positioning each of these autoplatforms and controlling how fast they move, I can create jump puzzles and other challenges.

Now I’ll give you a big chunk of assembly code I used for this NPC:

...

MOV EDX,DWORD [EBP+8]
INC DWORD [EDX+64]       ;FrameTimer
INC DWORD [EDX+78]       ;ScriptTimer
MOV EAX, DWORD [EDX+74]  ;get scriptState
TEST EAX,EAX             ;check if EAX is 0.
JE (do nothing)          ;if scriptState is 0, then don't move!
BT EAX,0                 ;get the last bit of EAX -> Carry flag
JC (leftright)           ;if last bit is 1, goto leftright

;up/down
SHL EAX,1                ;just in case vel is too small.
BT DWORD [EDX+4C],0      ;get last bit of Direction
JC (negvel)
ADD DWORD [EDX+14],36
CMP DWORD [EDX+14],EAX   ;remember EAX still holds Scriptstate
JGE (limitvel)           ;if vel is too great, limit it.
JMP (framecycler)
;negvel
NEG EAX                  ;negate EAX -- we need to move up instead of down.
SUB DWORD [EDX+14],36
CMP DWORD [EDX+14],EAX   ;remember EAX still holds Scriptstate
JG (framecycler)         ;if max neg vel isn't reached, goto framecycler.
;limitvel
MOV DWORD [EDX+14],EAX   ;store ScriptState to Y-vel
XOR DWORD [EDX+4C],1     ;flip direction
JMP (framecycler)

;leftright
SHL EAX,1
BT DWORD [EDX+4C],0      ;get last bit of Direction
JC (negvel2)
ADD DWORD [EDX+10],36
CMP DWORD [EDX+10],EAX   ;remember EAX still holds Scriptstate
JGE (limitvel2)          ;if vel is too great, limit it.
JMP (framecycler)
;negvel2
NEG EAX                  ;negate EAX -- we need to move left instead of right.
SUB DWORD [EDX+10],36
CMP DWORD [EDX+10],EAX   ;remember EAX still holds Scriptstate
JG (framecycler)         ;if max neg vel isn't reached, goto framecycler.
;limitvel2
MOV DWORD [EDX+10],EAX   ;store ScriptState to X-vel
XOR DWORD [EDX+4C],1     ;flip direction

...

For you ASM hackers, notice that this isn’t fully written in Doukutsu Assembler format because that didn’t actually exist when I made this NPC.

For you non-ASM hackers, you are probably very confused right now. That’s perfectly okay.

Just know that BT means “bit test”, and it lets me test whether a number is even or odd. Actually, it can do lots of other things, but that’s mainly what I used it for.

Bit test lets me maximize <ANP’s great power, which is the script command used to animate NPCs. Here’s how that TSC command works with the autoplatforms:

<ANPXXXX:YYYY:ZZZZ

Animate autoplatform X with magnitude Y and motion Z.

If Y is even, autoplatform will move up/down. If Z = 0, goes down at first. If Z = 1, goes up at first.
If Y is odd, autoplatform will move left/right. If Z = 0, goes right at first. If Z = 1, goes left at first.
If Y is zero, autoplatform stops.

So that’s all for today. Yeah – I know, I went into too much technical detail… yet there’s not much I can talk about if I just say, “the platforms form puzzles that you have to solve”, even if that’s basically all there is to it.

Now, this blog will not necessarily show all updates in the order they were originally… err… updated in. That means, sometimes I’ll show you an old feature that I forgot earlier because you didn’t see it yet. Sometimes the blog will keep up with the actual progress. Sometimes the blog will go beyond the real progress and speculate upon future ideas – a sort of time travel but with modding.

This controlled chaos should create fewer “empty” blog posts that don’t have any actual content. At least I think it should.

As some sort of parting note, this blog will also be updated on Saturdays (that’s the plan, anyway). Have a good day. Hope you enjoyed the first post.