Question: Detecting AI on Network Multiplayer

The place to post your WML questions and answers.

Moderators: Forum Moderators, Developers

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
User avatar
watbesh
Posts: 55
Joined: August 29th, 2012, 2:21 am
Location: Kanagawa, Japan

Question: Detecting AI on Network Multiplayer

Post by watbesh » November 28th, 2014, 3:40 pm

Hello.

I'm working on multiplayer modifications for 1.12, and I need to code an "AI detector" into the mod's code so I can use it for vs-AI games and survivals. The mods have to know whether the current side is controlled by an AI or a human player, to trigger events, for example, on recruiting a unit (if the side is AI-controlled, the AI always takes a certain option). I know two ways of doing this, but neither is likely to do well on online multiplayer. They seem to work when I play with AI locally.

Code: Select all

    [event]
        name=side turn
        first_time_only=no
        id=foo_sideturn
        {VARIABLE human_control[$side_number] yes}
    [/event]

    [event]
        name=ai turn
        first_time_only=no
        id=foo_aiturn
       {VARIABLE human_control[$side_number] no}
    [/event]

    # Then I can read the array "human_control" to get the controller. According to WML Reference, "ai turn" breaks replays or outright non-MP-safe.

Code: Select all

    [store_unit]
        [filter]
            canrecruit=yes
            side=$side_number
        [/filter]
        variable=side_leader
    [/store_unit]
    [if]
        [variable]
            name=side_leader.name
            not_equals={STR_RCA_AI} + " 1"
        [/variable]
        # {STR_RCA_AI} is a macro to call _"RCA AI" from "#textdomain wesnoth". Proceeds to other possible AI leader names.
        [then]
            # Event for a human player, but this is also triggered for humans who droid.
        [/then]
        [else]
            # Event for an AI, but this is also triggered for humans who are named "RCA AI".
        [/else]
    [/if]
Are there any to-go code for an AI detector? If you know one, please tell me!

Thank you.
My MP Eras and Mods with core units and unusual gameplay (version 1.3.1 for Wesnoth 1.12)

gfgtdf
Developer
Posts: 1203
Joined: February 10th, 2013, 2:25 pm

Re: Question: Detecting AI on Network Multiplayer

Post by gfgtdf » November 28th, 2014, 4:26 pm

you can read the [side]controller= value, for example like this:

Code: Select all

local side_number = ...
local is_ai_controlled = wesnoth.sides[side_number].controller == "ai" or  wesnoth.sides[side_number].controller == "network_ai"
the value of is_ai_controlled might be different on different clients, in order to prevent OOS you have to use wesnoth.syncronize_choice:

Code: Select all

local side_number = ...
local is_ai_controlled = wesnoth.synchronize_choice(
  function() 
    return { is_ai = wesnoth.sides[side_number].controller == "ai" or  wesnoth.sides[side_number].controller == "network_ai" }
  end
).is_ai
examples above are untested and might contain typos/bugs.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.

User avatar
watbesh
Posts: 55
Joined: August 29th, 2012, 2:21 am
Location: Kanagawa, Japan

Re: Question: Detecting AI on Network Multiplayer

Post by watbesh » November 29th, 2014, 2:15 pm

Thanks! :D
But I haven't seen that format in my WML... I guess it's a Lua code.

I'll learn some about that sort of coding. Possibly I can learn something more than an AI-detector.
My MP Eras and Mods with core units and unusual gameplay (version 1.3.1 for Wesnoth 1.12)

gfgtdf
Developer
Posts: 1203
Joined: February 10th, 2013, 2:25 pm

Re: Question: Detecting AI on Network Multiplayer

Post by gfgtdf » November 29th, 2014, 4:24 pm

yes it's lua code, the first code would also be possible to write in wml, but not the second code because wesnoth.syncronize_choice is only available in lua.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.

User avatar
watbesh
Posts: 55
Joined: August 29th, 2012, 2:21 am
Location: Kanagawa, Japan

Re: Question: Detecting AI on Network Multiplayer

Post by watbesh » December 5th, 2014, 1:47 pm

After a bunch of trial-and-error, I made a code that works locally. This is probably redundant, and possibly lacks something important, but I leave this here to help creators (if any) who want an MP-safe AI Detector... or to ask for further advice.

Code: Select all

#define CONTROL_ACTION HUMAN_ACTION_WML AI_ACTION_WML
    [lua]
        code = <<
          local current_side_number = wesnoth.get_variable("side_number")
          local side_control_human = wesnoth.synchronize_choice(
            function()
              return { is_human = wesnoth.sides[current_side_number].controller == "human" or wesnoth.sides[current_side_number].controller == "network" }
            end
          ).is_human
          local side_control_ai = wesnoth.synchronize_choice(
            function()
              return { is_ai = wesnoth.sides[current_side_number].controller == "ai" or wesnoth.sides[current_side_number].controller == "network_ai" }
            end
          ).is_ai
          wesnoth.set_variable("human_control", side_control_human)
          wesnoth.set_variable("ai_control", side_control_ai)
        >>
    [/lua]

    {IF_VAR human_control boolean_equals yes (
        [then]
            {HUMAN_ACTION_WML}
        [/then]
    )}

    {IF_VAR ai_control boolean_equals yes (
        [then]
            {AI_ACTION_WML}
        [/then]
    )}
#enddef
My MP Eras and Mods with core units and unusual gameplay (version 1.3.1 for Wesnoth 1.12)

gfgtdf
Developer
Posts: 1203
Joined: February 10th, 2013, 2:25 pm

Re: Question: Detecting AI on Network Multiplayer

Post by gfgtdf » December 5th, 2014, 2:07 pm

Yes that could work.
It's true that side not beeing human controlled doesn't imply a side beeing ai controlled becasue it might also be null-controlled. But turns of null-controlled sides are usually skipped, thats why you can assume that the currently playing side is never null-controlled. (unless you are in a start or a prestart event). So in this case one check would be enough and you could then put the the other case in the [else] block.


EDIT:
you can also put both checks in one sync_choice, that might make sense becasue sync choice implies netowrk traffic so you shouldn't use it if uneserary, that's why it can also make you wml slower, although it shouldnt matter it you use it one 2 times.
so instead of

Code: Select all

 
          local current_side_number = wesnoth.get_variable("side_number")
          local side_control_human = wesnoth.synchronize_choice(
            function()
              return { is_human = wesnoth.sides[current_side_number].controller == "human" or wesnoth.sides[current_side_number].controller == "network" }
            end
          ).is_human
          local side_control_ai = wesnoth.synchronize_choice(
            function()
              return { is_ai = wesnoth.sides[current_side_number].controller == "ai" or wesnoth.sides[current_side_number].controller == "network_ai" }
            end
          ).is_ai
          wesnoth.set_variable("human_control", side_control_human)
          wesnoth.set_variable("ai_control", side_control_ai)
you could write:

Code: Select all

 
          local choice = wesnoth.synchronize_choice(
            function()
              local side = wesnoth.sides[wesnoth.current.side]
              return {
                is_human = side.controller == "human" or side.controller == "network", 
                is_ai = side.controller == "ai" or side.controller == "network_ai",
              }
            end
          )
          wesnoth.set_variable("human_control", choice.is_human)
          wesnoth.set_variable("ai_control", choice.is_ai)
again, this is untested code.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.

Post Reply