Mega Man vs Ghosts 'n Goblins 2.0

December 27th, 2009

So I’ve been pumping everything I know about 2D platformers into this game engine in my free time. Schoolwork and other distractions conspire against me to delay this effort, so I’ve been doing it for a while. I decided to use Mega Man vs Ghosts ‘n Goblin‘s content to make an incomplete game as a way to find bugs and further understand what the engine needed. Naturally this turned into a complete port.

I graduated from college a few weeks ago, and rather than look for a job like I should be doing, I used the time to finish it up. Since 95% of the work that’s been done also works for it’s prequel, I’m already planning on redoing that one too.

Even though I would normally leave well enough alone I’ve really got a soft spots for these two games, and some things about them really bother me. Namely the numerous framerate shenanigans I pulled in the past have made them inexplicably choppy today. That and I hate the unlockable weapons. A lot.

So, here it is. The new and improved Mega Man vs Ghosts ‘n Goblins. Once I finish the other one I’ll try and spread them out across the Internet. If you find any bugs let me know.

EDIT: Play both games here.

I like my shared host, it’s cheap, it’s great, and any problems are easily overcome through a little ingenuity. In this case it’s hotlinking, something that’s been a serious problem in the past without a clear solution. Time has proven blocking outside referers with an .htaccess file is both ineffective, and can cost honest users. Without access to the httpd.conf, I’m forced to do things a little differently.

The system I have works using an .htaccess file that requires all files accessed in its folder have a unique key in the URL (as part of the query, the stuff that comes after the ‘?’ symbol). This key is changed every once in a while, and the .htaccess file is simply rewritten with the new information.

The files are updated by a cron job that runs a bash file that updates all the files. It fails gracefully too, if any file is unwritable everything will be left in a working state, albeit one that doesn’t prevent hotlinking anymore. The .htaccess file also lets the previously used key to still be used as well, so that the URLs don’t expire immediately after a new key is introduced.

Here’s how to get it working.

1. Get the files.

Available here. The files in the protected folder should similarly go into the folder you want protected and “update-key” should go somewhere else where it can be executed by the cron job but have no chance of being visible to the outside world. Make sure the file permissions are kept intact, “.htaccess” and “.htkey” files must all be writable by the cron job and “update-key” must be executable.

2. Set up a cron job.

Add a cron job that executes update-key every so often with whatever method you’re allowed. The “update-key” script changes files in the current directory, so you need to execute it in the same folder as the .ht files. Here’s an example cron job that runs every 8 hours. Change the paths to the right locations.

0 0,8,16 * * * cd $HOME/path/to/protected && $HOME/path/to/update-key

3. Use it in your pages.

To generate the URLs, just dump the contents of “.htkey”  as your key at the end of the URL. Here’s some examples.

PHP

<? echo '<img src="http://www.brokenfunction.com/protected/awesome.jpg?key=' . trim(array_pop(file("/path/to/protected/.htkey"))) . '">' ?>

Python

keyfile = open("/path/to/protected/.htkey", "r")
key = keyfile.readline().strip()
keyfile.close()
print("<a href='http://www.brokenfunction.com/protected/awesome.jpg?key=%s' />" % key)

If anybody can offer some other examples in the comments I’ll add them here.

This isn’t a perfect solution of course, anybody could check with your site and update their links accordingly whenever the key changes, but it’s good for lightweight protection and a lot more reliable than referer blocking.

The _why is gone.

August 20th, 2009

Internet eccentric and Ruby patron why the lucky stiff has apparently vanished, along with the sum of his work. It’s a damn shame. I’ve never coded a line of Ruby but he was the kind of programmer the world needs more of.

“when you don’t create things, you become defined by your tastes rather than ability. your tastes only narrow & exclude people. so create.” – _why

That quote is gone too, since his twitter account is gone.

EDIT: Here’s some more. The last ones are pretty recent, and give some indication as to what happened.

“if you program and want any longevity to your work, make a game. all else recycles, but people rewrite architectures to keep games alive”

“programming is rather thankless. you see your works become replaced by superior works in a year. unable to run at all in a few more.”

Flash GPU experiments

August 3rd, 2009

With the release of Flash 10, Adobe added some support for GPU’s via OpenGL and DirectX. The Flex SDK currently offers no way to flag any appropriate bits for this, so recently I endeavored to set this bit myself and see what the wonders of the GPU had to offer.

I wrote a small script to do this, but there is no way I have found to actually know if it’s working, save for graphical anomalies in some circumstances. I couldn’t see any difference in Linux (even with Compiz turned off), so I loaded up ye olde XP and tried it there with no obvious results.

Frustrated, I tried manually setting the wmode of the swf in an HTML page and finally saw some differences (although only in XP). Unfortunately the framerate decreased, something that I suspected might happen, but even worse the framerate seemed even more inconsistent and choppy than under regular rendering modes. It might’ve been because I was using it inside a browser or maybe due to my numerous framerate shenanigans. But more importantly the bit I flipped seemed to do nothing at all.

So while at first I was miffed at being left out of the Flash GPU club, now I’m content to wait longer. There’s no indication of what, exactly, these features are supposed to offer that I’ve found, nor any way to even be sure if you’re getting any benefit/hindrance from them. Unless you’re in Windows and have an eye for graphical anomalies I suppose.

Here’s the python script I used to set the aformentioned UseGPU bit (from the command line: python setusegpu.py <swf>). You can modify it easily to set the UseDirectBlit bit too (see the code for details). I’d love to hear if anybody can get better results than me, or maybe tell me how wrong and foolish I am and I’ve been misinterpreting everything.

I’ve got a PS3 controller, but using it with Ubuntu is a huge hassle, not that it doesn’t work mind you, it’s just that most software doesn’t seem to expect 28 axes and 19 buttons that overlap with each other. I’m even perfectly happy using it with a USB cable but I am scorned nonetheless.

Anyway, while I don’t have a perfect solution, I have a good enough solution for ZSNES. ZSNES normally confuses the axes and buttons when configuring different keys, so the input dialog is basically useless. But, I noticed the start/select/PS buttons all don’t have axes so I guessed that the seemingly arbitrary values ZSNES uses for those specific keys were the only correct ones. So I used select (310 according to zsnes, and button 0) to determine the offset for the buttons.

Basically it means (310 + button #) = zsnes button #. At least on my computer. So I used jstest to get the button numbers and hand-edited my ~/.zsnes/zinput.cfg, ending up with this in the player 1 section:

; Player 1 Input
; Input Device: 0 = Unplugged, 1 = KEYBOARD/GAMEPAD
pl1contrl=1
; Keys for Select, Start, Up, Down, Left, Right, X, A, L, Y, B, R
pl1selk=310
pl1startk=313
pl1upk=314
pl1downk=316
pl1leftk=317
pl1rightk=315
pl1Xk=322
pl1Ak=323
pl1Lk=320
pl1Yk=325
pl1Bk=324
pl1Rk=321

It works perfectly. Oh, and one last tip. I’m not sure how everyone experiences this, but the controller gives me no input until I press the PS button. This has the strange effect of turning on my PS3 when I unplug the controller later, but whatever.

After adding a custom event to something I was coding up today I started intermittently receiving something like this error message:

TypeError: Error #1034: Type Coercion failed: cannot convert flash.events::Event@148cb29 to com.brokenfunction.CustomEvent

It came with no stack trace, no line numbers, and had no determinable source. In other words, it was incredibly annoying. I had recieved this message before because I had not implemented clone(), but clone() was working properly now, what could be the cause? I pressed the play/pause button on my keyboard while pondering this and it triggered the error message. More research indicated it had nothing to do with any keyboard events, and was actually due to the player apparently quickly losing and then gaining focus. Why my OS sees fit to do this is still an unsolved mystery.

For my CustomEvent I had a couple types, including ACTIVATE and DEACTIVATE, which are already handled by Event but I added them anyway (var ACTIVATE:String = Event.ACTIVATE) so I wouldn’t even have to import Event when using my CustomEvent. So, on a hunch I changed the values of ACTIVATE to a different string and it fixed the bug!

The EventDispatcher I used to dispatch my CustomEvents was completely isolated so I foolishly thought it wouldn’t actually start broadcasting events implicitly – I was wrong. EventDispatcher still dispatches ACTIVATE/DEACTIVATE (when the player focuses/blurs) no matter what. I presume the error message came up when listeners were expecting a CustomEvent and got an Event instead. The lack of a stack trace could be explained by the fact that there is no stack to trace, as the caller is some Flash internal somewhere and it never actually gets to my code because of the errors.

Compiling AS3 quickly

June 24th, 2009

One thing I’ve always missed from my mtasc days is the sheer speed of mtasc. It was almost too fast. Now these days mxmlc provides a similar command line experience, only dirt slow. I suppose Adobe can’t be blamed because it’s due in no small part by Java’s slow startup time, but then again I think I can blame them for that too.

Now, compiling using Flex Builder is faster because the compiler is not unloaded, but it has it’s own problems. In one particular instance I had multiple build targets and experienced even slower speeds than mxmlc alone was capable of. Besides all that, Flex Builder requires a license.

The sole imperfect light on the horizon was fcsh. It only compiles what has changed (crazy! I know!) which makes it extremely fast. The only problem is fcsh is annoying to use and requires that you not leave the program to reap its rewards. There’s also the Flash IDE, and since it’s not really a programmer’s environment, that makes four ways to compile AS3 but no good ways to compile AS3.

Since fcsh has the most promising results I tried to put together a script to manage it, but I couldn’t quite get it to work. Then Ali Rantakari did it with fcshctl. It’s basically what fcsh should’ve been. I’ve had no trouble with multiple build targets, it keeps fcsh running using screen, and the only time it’s ever the slightest bit slow is the first time it compiles something.

So, to save time, I’ve been creating these scripts which make it easy to quickly (re)compile and then launch whatever I’m working on. Here’s an example, which requires fcshctl and flashplayer are in your PATH. If no arguments are given, it will attempt to compile and launch the swf, otherwise it will pass whatever you give it to fcshctl (in case you want to run fcsh commands, like “info”)

#!/bin/bash
if [ -n "$1" ]; then
  fcshctl $@
else
  fcshctl mxmlc 
  -output deploy/target.swf 
  -use-network 
  -compiler.debug 
  src/com/brokenfunction/Target.as 
  -compiler.source-path src && 
  flashplayer deploy/mmvsgng.swf
fi

Despite the fact a lot of this should be unnecessary in the end it’s basically my ideal compilation solution — quick, easy, and customizable. I still keep my ant build files around for my non-debug builds, so they still have a purpose too.

Broken for 5 years

May 26th, 2009

Almost forgot, yesterday was the fifth anniversery of the day I registered brokenfunction.com. To celebrate, I renewed it for another 5 years!

Some combined stats for blog.brokenfunction.com and www.brokenfunction.com over the full five years:

  • Page hits: 5.6 million
  • Data transferred: 1684 GB

I like how high it seems but it’s not really that high when you remember this is over 5 years. It’s roughly 2 page hits and .65 MB downloaded per minute. Feel free to be impressed anyway though.

I read a scientific article on a topic of which I have some experience, namely NES-era Mario Bros physics. It was “Acceleration Due to Gravity: Super Mario Brothers“. I was very disappointed in the quality of this article, as the entire basis of the article was made under more than one incorrect assumption. For shame Adam Lefky and Artem Gindin.

When I created this demo my usual formula for velocity/acceleration used on Mario simply did not work. I had to look carefully at his movements until I realized his acceleration was not constant. After some experimentation I estimated his acceleration downward to be 0.6 in pixels per frame (1 frame = 1000/30 ms) before the peak of his jump, then it dramatically increases to 3 after the peak of his jump. This produces Mario’s hovering jump, which can be hard to notice unless you’re looking for it, but it’s there. This is not taking into account when a player releases the jump button mid-jump, which also changes the acceleration.

Additionally, there is also a maximum velocity in the Mario world, which probably came into play for some of their experiments. Not that they’d notice while wontedly ignoring the scientific method. I am very disappointed in you Adam Lefky and Artem Gindin.

Update: There’s some indication this method no longer works in Flex 4, be careful.

If you use mxmlc and the [Embed] tag you may be aware that you’ve just involved Flex in your project since [Embed] is actually a Flex concept.

Using the “-link-report” option in mxmlc you can see what classes have been compiled into your swf and how much space they use. I found this entry like this in my link report for an [Embed]’d image.

<script name="com/brokenfunction/project/SomeClass_EmbeddedImage.as" mod="1236990005000" size="684" optimizedsize="343">
   <def id="com.brokenfunction.project:SomeClass_EmbeddedImage" />
   <pre id="mx.core:BitmapAsset" />
   <dep id="AS3" />
</script>

See the “mx.core:BitmapAsset” requirement? Since the [Embed]’d asset ends up as a class which extends BitmapAsset it is used even if you don’t use it. I generally just use it as a Bitmap, rather than a BitmapAsset, so it’s largely unnecessary for my needs.

Now, this is all fine, this is how mxmlc does embedding, so it’s necessary. But checking the documentation for BitmapAsset and looking at the link report, we see it’s actually bringing in a bunch of extra classes and interfaces.

<script name="/home/max/bin/flex3/frameworks/libs/framework.swc(mx/core/BitmapAsset)" mod="1224183575340" size="1300" optimizedsize="678">
   <def id="mx.core:BitmapAsset" />
   <pre id="mx.core:IFlexAsset" />
   <pre id="mx.core:FlexBitmap" />
   <pre id="mx.core:IFlexDisplayObject" />
   <dep id="flash.display:BitmapData" />
   <dep id="AS3" />
   <dep id="mx.core:mx_internal" />
</script>

All the “mx” classes are actually compiled into the swf. Now Flex isn’t really bogging down the swf, all in all I found these classes to be around 2k-3k when compressed, but they annoyed me anyway while trying to shrink a preloader for a project. After a lot of Googling I found a solution, but I decided to write a more complete solution here.

You can replace the mx.core.*Asset classes with your own, which replace the originals and remove those unnecessary dependencies. Something like this:

package mx.core {
   import flash.display.Bitmap;
   public class BitmapAsset extends Bitmap {}
}

You can download a collection of these I’ve made here.

I recommend adding them to a new AS3 library, rather than mixing it with any major ones you use, then adding it as another source path for a project.

These could interfere with how classes interact in AS3 if you mix classes using this library and classes that use Flex. Since saving that extra 2k is unnecessary for Flex projects anyway, it’s probably a good idea to use it for AS3-only projects that need to save space.