Sunday, July 25, 2010

Three Laws of Robotics

  1. A robot may not injure a human being or, through inaction, allow a human being to come to harm.
  2. A robot must obey any orders given to it by human beings, except where such orders would conflict with the First Law.
  3. A robot must protect its own existence as long as such protection does not conflict with the First or Second Law.

It's clear that droids in Paradroid violate the first two laws, but that doesn't mean that they have to violate the third law as well. After all, Elvex dreamt of world without the first two laws.

So... why would a droid with any brains rush straight into explosion it surely knows will harm it? The most common situation where you see that happening is when a high-speed droid (like 834) shoots a low level droid in front of it and then runs (or flies, 834 is an anti-grav droid) into the explosion, destroying itself. I see no reason for that, so the droid must stop. The fastest way for detecting this was to give every patrol route segment an unique number and update droid info when it leaves a waypoint. When droid is destroyed its type is changed to explosion, but most of other attributes remain. That means that when checking for future collisions I can discard most of the droids/explosions by checking the route number only. That still leaves collisions on or near waypoints, but I have to start somewhere (and I hope I can forget more exact check later ;)

There are 433 waypoint exit directions in total so it was more efficient to write a subroutine to enumerate all routes on fly than including them in the data. That routine is less than 130 bytes long, static data plus depacking code would be at least twice the size. I also needed one 256-byte table to be able to look up the route number fast; 32 waypoints with 8 possible directions form an 8-bit index into that table. I can update route number with "lda waypoint_num; asl; asl; asl; ora dir; tay; lda routes,y; sta droidRoute,x" (that happens only when droid leaves waypoint) and check for impending collisions with "lda droidRoute,x; cmp droidRoute,y" - only if routes match I need to check for the distance between two objects. Nice and fast, now I need to play some games to check if I can see the difference.

Later I can use the same data to check if another droid is in a security droid's way, and if that's the case the security droids may decide to destroy a low-level droid to serve a greater good - to protect the ship.

A robot will guard its own existence with lethal antipersonnel weaponry, because a robot is bloody expensive.
- David Langford

Sunday, July 18, 2010

Not dead yet, part 2

It may have taken two years, but here is the newest and greatest version!

Both original and Metal Edition graphics are now in the same executable, droids have slightly modified AI, high score saving should work with most common expansions (you may have to disable your disk speeder cartridge though) and there is a new frontend. Can you name all the games from where I borrowed something?

Some minor changes including but not limited to

  • orange/red alert increases enemy fire probability half/full ship
  • competition mode - same droids every time, has separate high score file
  • no pacifist bonus if disruptor used
  • droid centered on lift when deck changes - no more exit through wall

File update: two bugfixes to eliminate crash on startup (hopefully one of them does the trick), one minor visual fix and adding disruptor to firing statistics. No more easy accuracy bonus by using 711/742 only!