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

3 comments:

battlecommand said...

Awesome work! I had no clue back in the days how much tech is in this game. One thing: the "deck offline" (all robots dead) in the elevator scene doesnt seem to work every time. And is it possible, that d016 is not centered when entering the transfer game? Still, this game is absolutely nasty to play if you got no Competition Pro at hand (damn usb pads). Anyways. Totally love the game. The way you smoothened stuff up is definetely adding to the feeling. And it feels so alive to read a relatively current build date. Currently working on my demo comeback. Learning from you. Thanks!

battlecommand said...

One more: energy bar in the top screen? Possible?

Zarkov said...

A new build! Splendid. Guess how I am spending these Christmas days?