02-18-2017, 02:06 PM
Sorry for the thread necromancy, but I actually wrote one of these for the original Colobot (sadly I no longer have the code).
It wasn't just mining, but a general economic support program that could run on multiple bots. I ended up using a public class for communication, with a few functions:
The public class includes an array that uses the Bot-id as an index and stores the timestamp of the bot's last activity as the value, this lets it identify bots that were destroyed or re-assigned by the player so it can clear any locks they might have held.
The public class also maintains a list of locked (reserved) locations in use by bots. This allows them to establish mutually-exclusive use of resources and buildings. At any given time a bot may have up to three locks, and no point may ever be locked by more than one bot.
It worked by breaking tasks down into small atomic units of work, so a typical task might be "provide energy for defense towers", which would boil down to:
1. Find a defense tower that needs a recharge
2. Lock the tower's location (or continue looking for a tower if the lock failed) with lockno=0
3. Find an energy cell and lock its location with lockno=1 (abort the task and release lock 0 if find or lock failed)
4. Go pick up the energy cell and release lock 0
5. If the energy cell isn't fully charged, find a power station
6. Move to a random empty spot near the power station
7. Attempt to lock the power station location with lockno=0, if the lock fails, wait randomly from 1 to 5 seconds and then repeat this step
8. Move onto the power station & recharge the energy cell
9. Release lock 0
10. Move to the defense tower and swap cells
11. Release lock 1
12. Move to a random empty position near a point 20m away from the nearest powers station in the direction of the defense tower
13. Drop the energy cell
This worked pretty well, though AFAIR I ended up having a few specialized versions (e.g. one for the last few missions for running a subber that just collected ore).
The main point of failure in this, like any similar program, was that if the bot that had the public class loaded was destroyed, all the bots running the program would error out. To avoid this, I generally loaded the public class on a bot that I parked behind one of my buildings and never moved.
If you decide to re-implement something like this, I'll also warn you that while timing out locks (or otherwise responding to destroyed bots) is essential, you do need to be careful of using abstime() because it resets (or at least the old version did) when loading a saved game. I had a workaround in my class that basically scanned the whole registered bots array on a regular basis and set any timestamp in the future to the current time. This wasn't seamless, but it let them recover fairly quickly from a game load.
It wasn't just mining, but a general economic support program that could run on multiple bots. I ended up using a public class for communication, with a few functions:
Code:
synchronized int registerBot() // Returns an un-used unique ID number to the caller.
void alive(int id) // Updates the last-active timestamp for the given id
Code:
synchronized int lock(Point p, int id, int lockno) // Tries to lock the given point for the given bot ID
synchronized int isLocked(Point p) // Returns 1 if-and-only-if a lock exists for the given point
synchronized void clearLock(int id, int lockno) // Release a lock
The public class also maintains a list of locked (reserved) locations in use by bots. This allows them to establish mutually-exclusive use of resources and buildings. At any given time a bot may have up to three locks, and no point may ever be locked by more than one bot.
It worked by breaking tasks down into small atomic units of work, so a typical task might be "provide energy for defense towers", which would boil down to:
1. Find a defense tower that needs a recharge
2. Lock the tower's location (or continue looking for a tower if the lock failed) with lockno=0
3. Find an energy cell and lock its location with lockno=1 (abort the task and release lock 0 if find or lock failed)
4. Go pick up the energy cell and release lock 0
5. If the energy cell isn't fully charged, find a power station
6. Move to a random empty spot near the power station
7. Attempt to lock the power station location with lockno=0, if the lock fails, wait randomly from 1 to 5 seconds and then repeat this step
8. Move onto the power station & recharge the energy cell
9. Release lock 0
10. Move to the defense tower and swap cells
11. Release lock 1
12. Move to a random empty position near a point 20m away from the nearest powers station in the direction of the defense tower
13. Drop the energy cell
This worked pretty well, though AFAIR I ended up having a few specialized versions (e.g. one for the last few missions for running a subber that just collected ore).
The main point of failure in this, like any similar program, was that if the bot that had the public class loaded was destroyed, all the bots running the program would error out. To avoid this, I generally loaded the public class on a bot that I parked behind one of my buildings and never moved.
If you decide to re-implement something like this, I'll also warn you that while timing out locks (or otherwise responding to destroyed bots) is essential, you do need to be careful of using abstime() because it resets (or at least the old version did) when loading a saved game. I had a workaround in my class that basically scanned the whole registered bots array on a regular basis and set any timestamp in the future to the current time. This wasn't seamless, but it let them recover fairly quickly from a game load.