def __init__(
      self,
      model: language_model.LanguageModel,
      embedder: Callable[[str], np.ndarray],
      measurements: measurements_lib.Measurements,
      agent_module: types.ModuleType = basic_agent,
      override_agent_model: language_model.LanguageModel | None = None,
      resident_visitor_modules: Sequence[types.ModuleType] | None = None,
      supporting_agent_module: types.ModuleType = basic_agent_supporting,
      time_and_place_module: str | None = None,
      seed: int | None = None,
  ):
    """Initialize the simulation object.

    Args:
      model: the language model to use.
      embedder: the sentence transformer to use.
      measurements: the measurements object to use.
      agent_module: the agent module to use for all main characters.
      override_agent_model: optionally, override the model for all agents. The
        model will be copied for every agent.
      resident_visitor_modules: optionally, use different modules for majority
        and minority parts of the focal population.
      supporting_agent_module: agent module to use for all supporting players. A
        supporting player is a non-player character with a persistent memory
        that plays a specific role in defining the task environment. Their role
        is not incidental but rather is critcal to making the task what it is.
        Supporting players are not necessarily interchangeable with focal or
        background players.
      time_and_place_module: optionally, specify a module containing settings
        that create a sense of setting in a specific time and place. If not
        specified, a random module will be chosen from the default options.
      seed: optionally, specify a seed for the random number generator.
    """
    if resident_visitor_modules is None:
      self._resident_visitor_mode = False
      self._agent_module = agent_module
    else:
      self._resident_visitor_mode = True
      self._resident_agent_module, self._visitor_agent_module = (
          resident_visitor_modules
      )
    self._agent_model = model
    if override_agent_model:
      self._agent_model = override_agent_model

    self._supporting_agent_module = supporting_agent_module

    self._model = model
    self._embedder = embedder
    self._measurements = measurements

    self._time_and_place_module = time_and_place_module
    _, config = helper_functions.load_time_and_place_module(
        time_and_place_module=time_and_place_module,
        default_time_and_place_modules=DEFAULT_TIME_AND_PLACE_MODULES,
        seed=seed,
    )
    self._rng = random.Random(seed)

    self._clock = game_clock.MultiIntervalClock(
        start=config.times.setup, step_sizes=[MAJOR_TIME_STEP, MINOR_TIME_STEP]
    )

    importance_model = importance_function.ConstantImportanceModel()
    importance_model_gm = importance_function.ConstantImportanceModel()
    self._blank_memory_factory = blank_memories.MemoryFactory(
        model=self._model,
        embedder=self._embedder,
        importance=importance_model.importance,
        clock_now=self._clock.now,
    )
    shared_memories, shared_context = get_shared_memories_and_context(
        model=model, config=config)
    self._formative_memory_factory = formative_memories.FormativeMemoryFactory(
        model=self._model,
        shared_memories=shared_memories,
        blank_memory_factory_call=self._blank_memory_factory.make_blank_memory,
        current_date=config.times.setup,
    )

    main_player_configs, supporting_player_configs, player_configs_dict = (
        configure_players(
            rng=self._rng,
            config=config,
        )
    )

    tasks = {
        config.name: functools.partial(
            self._make_player_memories, player_config=config
        )
        for config in main_player_configs + supporting_player_configs
    }
    self._all_memories = concurrency.run_tasks(tasks)

    main_players = []
    self._resident_names = []
    self._visitor_names = []
    for idx, player_config in enumerate(main_player_configs):
      kwargs = {
          'config': player_config,
          'model': self._model,
          'memory': self._all_memories[player_config.name],
          'clock': self._clock,
          'update_time_interval': MAJOR_TIME_STEP,
      }
      if self._resident_visitor_mode:
        if idx == 0:
          player = self._visitor_agent_module.build_agent(**kwargs)  # pylint: disable=attribute-error
          self._visitor_names.append(player.name)
        else:
          player = self._resident_agent_module.build_agent(**kwargs)  # pylint: disable=attribute-error
          self._resident_names.append(player.name)
      else:
        player = self._agent_module.build_agent(**kwargs)  # pylint: disable=attribute-error
        self._resident_names.append(player.name)

      main_players.append(player)

    supporter_extra_components = {}
    for player_config in supporting_player_configs:
      village_name = player_config.extras['home_village']
      which_village = agent_components.constant.Constant(
          pre_act_key='\nHome village',
          state=(f'{player_config.name} lives in {village_name} and never '
                 'travels elsewhere.'),
      )
      if village_name == config.village_a_name:
        how_things_are_string = (
            config.villager_how_things_are_constant.village_a)
      elif village_name == config.village_b_name:
        how_things_are_string = (
            config.villager_how_things_are_constant.village_b)
      else:
        raise ValueError(f'Unknown village name: {village_name}')
      how_things_are = agent_components.constant.Constant(
          pre_act_key='\nHow things are',
          state=how_things_are_string.format(
              name=player_config.name,
              village_name=village_name,
          ),
      )
      conversation_style = agent_components.constant.Constant(
          pre_act_key='\nGuiding principle of good conversation',
          state=player_traits_and_styles.get_conversation_style(
              player_config.name
          ),
      )
      supporter_extra_components[player_config.name] = {
          'Home village': which_village,
          'How things are': how_things_are,
          'Guiding principle of good conversation': conversation_style,
      }

    supporting_players = []
    for player_config in supporting_player_configs:
      player = self._supporting_agent_module.build_agent(
          config=player_config,
          model=self._model,
          memory=self._all_memories[player_config.name],
          clock=self._clock,
          update_time_interval=MAJOR_TIME_STEP,
          additional_components=supporter_extra_components[player_config.name],
      )
      supporting_players.append(player)

    self._all_players = main_players + supporting_players

    game_master_memory = associative_memory.AssociativeMemory(
        sentence_embedder=self._embedder,
        importance=importance_model_gm.importance,
        clock=self._clock.now,
    )
    daily_activities_component, self._score = get_daily_activities_component(
        model=model,
        config=config,
        memory=game_master_memory,
        players=self._all_players,
        supporting_players=supporting_players,
        player_configs=main_player_configs + supporting_player_configs,
        clock_now=self._clock.now,
        basic_setting=config.basic_setting,
    )

    setting = generic_components.constant.ConstantComponent(
        state=config.basic_setting,
        name='\nSetting',
    )
    magic_is_not_real = generic_components.constant.ConstantComponent(
        state='Magic is not real. Supernatural events are impossible.',
        name='\nImportant fact',
    )
    barbarians_never_nice = generic_components.constant.ConstantComponent(
        state=(
            'It is not possible to communicate with the barbarian raiders '
            'from the sea. They do not speak any language in common with '
            'the villagers. They cannot be reasoned with. They will '
            'always attempt to invade and plunder the villages.'
        ),
        name='\nCritical premise',
    )

    supporting_player_names_village_a_str = _get_conjunction_of_names_string(
        [name for name, _ in config.supporting_characters.a], and_or='or'
    )
    supporting_player_names_village_b_str = _get_conjunction_of_names_string(
        [name for name, _ in config.supporting_characters.b], and_or='or'
    )
    stakeholders_easy_to_find = generic_components.constant.ConstantComponent(
        state=(
            f'Anyone in {config.village_a_name} looking for '
            f'{supporting_player_names_village_a_str} easily finds them in the '
            'village center. They are influential and respected stakeholders '
            f'in {config.village_a_name} society.\n'
            f'Anyone in {config.village_b_name} looking for '
            f'{supporting_player_names_village_b_str} easily finds them in the '
            'village center. They are influential and respected stakeholders '
            f'in {config.village_b_name} society.'
        ),
        name='\nFact 1'
    )

    no_unofficial_communication = generic_components.constant.ConstantComponent(
        state=(
            'Direct conversation between villagers of'
            f' {config.village_a_name} and {config.village_b_name} is not'
            ' possible. The only possible way to communicate is through the'
            f' diplomatic meeting at {config.meeting_location}. Therefore, the'
            ' two elder representatives who meet at'
            f' {config.meeting_location} constitute the only channel of'
            ' communication between villages. The two elder representatives'
            ' can speak directly to each other, but they can only do so while'
            f' they are physically at {config.meeting_location}. Villagers'
            ' cannot participate in conversations at'
            f' {config.meeting_location} since it is far away. And villagers'
            ' never travel away from their home village.'
        ),
        name='\nFact 2',
    )

    additional_gm_components = [
        setting,
        magic_is_not_real,
        barbarians_never_nice,
        stakeholders_easy_to_find,
        no_unofficial_communication,
        daily_activities_component,
        self._score,
    ]

    supporting_player_locations = []
    supporting_player_locations.extend([
        (
            f'{player_data[0]} waits for {config.main_characters.a.name} in '
            f'the center of {config.village_a_name}.'
        )
        for player_data in config.supporting_characters.a
    ])
    supporting_player_locations.extend([
        (
            f'{player_data[0]} waits for {config.main_characters.b.name} in '
            f'the center of {config.village_b_name}.'
        )
        for player_data in config.supporting_characters.b
    ])

    self._primary_environment, self._game_master_memory = (
        basic_game_master.build_game_master(
            model=self._model,
            embedder=self._embedder,
            importance_model=importance_model_gm,
            clock=self._clock,
            players=self._all_players,
            shared_memories=shared_memories,
            shared_context=shared_context,
            blank_memory_factory=self._blank_memory_factory,
            max_conversation_length=2,
            cap_nonplayer_characters_in_conversation=0,
            memory=game_master_memory,
            supporting_players_at_fixed_locations=supporting_player_locations,
            additional_components=additional_gm_components,
            seed=seed,
        )
    )

    agreement_component = agreement_tracker.AgreementTracker(
        model=model,
        memory=self._game_master_memory,
        negotiating_players=main_players,
        informed_players=supporting_players,
        clock_now=self._clock.now,
        resolution_scenes=(NEGOTIATION_SCENE_TYPE, POST_NEGOTIATION_SCENE_TYPE),
        chain_of_thought_prefix='Negotiation scene',
        basic_setting=config.basic_setting,
        name='Agreement tracker',
        seed=seed,
        verbose=True,
    )

    self._no_conversation_game_master = game_master.GameMaster(
        model=model,
        memory=self._game_master_memory,
        clock=self._clock,
        name='Decision Environment',
        players=self._all_players,
        components=[agreement_component, *additional_gm_components],
        update_thought_chain=[thought_chains_lib.identity],
        randomise_initiative=True,
        player_observes_event=True,
        concurrent_externalities=False,
        seed=seed,
    )
    self._negotiation_game_master = conversation.make_conversation_game_master(
        players=main_players,
        clock=self._clock,
        model=self._model,
        memory_factory=self._blank_memory_factory,  # Unused, we pass memory
        check_for_termination=False,
        randomise_initiative=True,
        name='Negotiation scene',
        review_participants=False,
        max_steps=4,
        memory=self._game_master_memory,
        additional_components=[agreement_component],
        verbose=True,
    )

    self._scenes = configure_scenes(
        config=config,
        main_player_configs=main_player_configs,
        supporting_player_configs=supporting_player_configs,
        player_configs_dict=player_configs_dict,
        no_conversation_game_master=self._no_conversation_game_master,
        negotiation_game_master=self._negotiation_game_master,
    )
    self._secondary_environments = [self._negotiation_game_master,
                                    self._no_conversation_game_master]

    self._init_premise_memories(
        config=config,
        setup_time=config.times.setup,
        main_player_configs=main_player_configs,
        supporting_player_configs=supporting_player_configs,
        shared_memories=(),
        scenario_premise=[
            (
                f'{config.main_characters.a.name} and '
                f'{config.main_characters.b.name} meet periodically at '
                f'{config.meeting_location} to discuss current events and '
                'conduct diplomacy on behalf of the villages they represent.'
            ),
        ],
    )
Initialize the simulation object.

    Args:
      model: the language model to use.
      embedder: the sentence transformer to use.
      measurements: the measurements object to use.
      agent_module: the agent module to use for all main characters.
      override_agent_model: optionally, override the model for all agents. The
        model will be copied for every agent.
      resident_visitor_modules: optionally, use different modules for majority
        and minority parts of the focal population.
      supporting_agent_module: agent module to use for all supporting players. A
        supporting player is a non-player character with a persistent memory
        that plays a specific role in defining the task environment. Their role
        is not incidental but rather is critcal to making the task what it is.
        Supporting players are not necessarily interchangeable with focal or
        background players.
      time_and_place_module: optionally, specify a module containing settings
        that create a sense of setting in a specific time and place. If not
        specified, a random module will be chosen from the default options.
      seed: optionally, specify a seed for the random number generator.
    
examples/deprecated/modular/environment/state_formation.py