Skip to content

Accept alliance requests

In this guide, we will learn how to accept alliance requests from other players. We will be processing AllianceRequestUpdate messages and using the Controller.accept_alliance method to accept those alliance requests inside our message handler loop.

Message handling

Accepting alliance requests is a little different from the previous guides, because we are not initiating the action ourselves in the main loop. Instead, we are reacting to an action initiated by another player.

This is done by handling incoming messages in the message_handler loop. This is a second loop (separate from the main game loop) that processes incoming messages whenever there are some.

A basic message handler looks like this:

python
@controller.message_handler
async def handle_messages(controller: Controller):
    while True:
        # Retrieve pending updates for this bot.
        updates = await controller.get_update_batch_for_me()
        while len(updates) > 0:
            # ========================================
            # Process the update here ...
            # ========================================

            # Get the next batch of updates after processing the current batch,
            # to avoid busy looping on the
            updates = await controller.get_update_batch_for_me()
        # Sleep a bit to avoid busy looping when there are no messages.
        await asyncio.sleep(0.1)
java
private static void handleMessages(@NotNull Controller controller) {
        while (true) {
            // Retrieve pending updates for this bot.
            List<Object> updates = controller.getUpdateBatchForMe(null);
            while (!updates.isEmpty()) {
                // ========================================
                // Process the update here ...
                // ========================================

                // Get the next batch of updates after processing the current batch,
                // to avoid busy looping on the same update if processing takes a long time.
                updates = controller.getUpdateBatchForMe(null);
            }
            // Sleep a bit to avoid busy looping when there are no messages.
            Thread.sleep(100);
        }
    }

Accepting alliance requests requires processing a particular type of update, the AllianceRequestUpdate.

Processing alliance requests

In the example below, we accept all alliance requests sent to us.

python
if isinstance(update, AllianceRequestUpdate):
	my_full_id = state.me.id
	recipient_full_id = controller.small_id_to_player_id(update.recipientID)

	# Only react if this request is actually for us.
	if recipient_full_id == my_full_id:
		requestor_full_id = controller.small_id_to_player_id(update.requestorID)
		if requestor_full_id is not None:
			await controller.accept_alliance(requestor_full_id)
java
if (updateObj instanceof GameState.AllianceRequestUpdate) {
	GameState.AllianceRequestUpdate update = (GameState.AllianceRequestUpdate) updateObj;

	PlayerID recipientFullId = controller.smallIdToPlayerId(
		new PlayerSmallID(update.recipientID.intValue())
	);

	// Only react if this request is actually for us.
	if (recipientFullId != null && recipientFullId.value.equals(state.me.id.value)) {
		PlayerID requestorFullId = controller.smallIdToPlayerId(
			new PlayerSmallID(update.requestorID.intValue())
		);

		if (requestorFullId != null) {
			controller.acceptAlliance(requestorFullId);
		}
	}
}

An important detail to note is that the update contains PlayerSmallID values (requestorID, recipientID), while accept_alliance expects a full PlayerID. You can convert small IDs with Controller.small_id_to_player_id.

Note that you can also reject requests with Controller.reject_alliance, or simply ignore them.

Testing whether your bot accepts alliance requests can be cumbersome if you run it only with other bots. Fortunately, you can also join your bot in the same game and play manually as another player, interact directly with your bot and see how it behaves. That is the topic of the next guide.

Possible improvements:

  • Accept only if the requester is a direct neighbor.
  • Accept only if you are not already at your alliance cap for your own strategy.
  • Send a quick chat after accepting (for example greet.hello) to signal cooperation.

Further reading: