I'm making a simple IRC bot in Perl that can be used to "hunt ducks" in response to [this IRC game bot](https://github.com/jnmtx/CloudBot/blob/gonzobot/plugins/duckhunt.py). I'm doing this on a private scripting channel, `irc.freenode.net ##duckhunt2` so as not to interfere with real people playing the game.

So far I've tried making a Perl bot using [`Net::IRC`](https://metacpan.org/pod/Net::IRC) and a plugin for XChat, [with my code here](https://github.com/pr1m4zu1/IRCHunterBot). The duck source bot sends a message like

```
・゜゜・。。・゜゜\_O< quack!

```

a random amount of time in between 8-60 minutes since the last duck was shot to let you know that a duck has arrived. You can then reply with `.bang` to shoot the duck and get one point added to your score. However, if you reply too quickly (within one second), it puts you in a 2 hour cooldown mode where you can't shoot any ducks. Sometimes it also throws in 7 second cooldowns because of "jammed guns" and such, as shown in line 272 of the game bot code.

### Perl code

```
use Net::IRC;
use Time::HiRes qw(usleep nanosleep);

$ducksource = 'DUCK_SOURCE';
$server     = 'IRC_SERVER';
$channel    = 'IRC_CHANNEL';
$botnick    = 'BOT_NICKNAME';
$botnick2   = 'BOT_BACKUP_NICKNAME';
$password   = 'BOT_PASSWORD';
$botadmin   = 'BOT_ADMIN_NICKNAME';

$irc = new Net::IRC;

$conn = $irc->newconn(
    Nick     => $botnick,
    Server   => $server,
    Port     => IRC_SERVER_PORT,
    Username => $botnick
);

$conn->add_global_handler('376',        \&on_connect);
$conn->add_global_handler('disconnect', \&on_disconnect);
$conn->add_global_handler('kick',       \&on_kick);
$conn->add_global_handler('msg',        \&on_msg);
$conn->add_global_handler('public',     \&on_public);

$irc->start;

sub on_connect {

    $self = shift;

    $self->privmsg('nickserv', "identify $password");
    $self->join($channel);

    print "Connected\n";
}

sub on_disconnect {

    $self = shift;

    print "Disconnected, attempting to reconnect\n";
    $self->connect();
}

sub on_kick {

    $self = shift;

    $self->join($channel);
    $self->privmsg('nickserv', "/nick $botnick");
}

sub on_msg {

    $self  = shift;
    $event = shift;

    if ($event->nick eq $botadmin) {

        foreach $arg ($event->args) {

            if ($arg =~ m/uptime/) {
                $self->privmsg($botadmin, `uptime`);
            }
        }
    }
}

sub on_public {

    $self  = shift;
    $event = shift;

    if ($event->nick eq $ducksource) {

        foreach $arg ($event->args) {

            if (($arg =~ m/</) && ($arg !~ m/>/)) {
                usleep(250000);
                $self->privmsg($channel, ".bang");
            }

            if (   ($arg =~ m/missed/)
                || ($arg =~ m/jammed/)
                || ($arg =~ m/luck/)
                || ($arg =~ m/WTF/)) {
                $self->privmsg('nickserv', "/nick $botnick2");
                $self->privmsg($channel,   ".bang");
                $self->privmsg('nickserv', "/nick $botnick");
            }

            if (($arg =~ m/script/) || ($arg =~ m/period/)) {
                $self->privmsg('nickserv', "/nick $botnick2");
                $self->privmsg($channel,   ".bang");
            }
        }
    }
}

```

The Perl bot connects to the server, joins the chat room, and responds to a duck appearing, but I can't get it to delay the sending of the command `.bang` so that the game bot receives it after 1 second has passed and I don't go into the two-hour cooldown mode.

I know that the Perl `sleep` command only accept multiples of one second. I need to delay 0.25 seconds because it takes about 0.75 seconds for the message to reach the game bot, so I've tried using Time::HiRes and the `usleep` command, which uses microseconds (1,000 microseconds = 1 millisecond).

On line 61 of my code, I added `usleep(250000)` which should make the script pause for 0.25s before sending the message on the next line

```
$self->privmsg($channel, ".bang")

```

But the script does not wait -- it just sends the message as normal. It acts like it is ignoring the `usleep` command.

How can I fix this and make the bot wait before it sends the message?

Secondly, I'm confused over how to change nicknames. If the game bot gives me a 7 second cooldown, I'd like to quickly change my nick to another nick (e.g. `HunterBot6000` to `HunterBot6000_`) shoot the duck (`.bang`), and change my nick back before another bot gets the duck. Typically you accomplish a nick change through the `/nick NEWNICK` command. However, I've tried sending this command to the channel and *NickServ*, and this doesn't change my nickname. How should I accomplish this?

I also tried writing an XChat plugin for the script to see if that would get rid of the timing issue, but that doesn't work either. After connecting to the server and joining the chat room in XChat, I load the plugin, and I have the same issue -- it responds to ducks with `.bang` but I cannot get it to wait before sending.

You can see the documentation [*Writing a simple XChat Perl Script*](http://xchatdata.net/Scripting/BasicPerlScript). What am I doing wrong?