> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Entity Groups

> Aprenda cómo los Entity Groups de PlayFab modelan hermandades, clanes, grupos y canales de chat, con roles de miembros, invitaciones y datos compartidos de objetos y archivos.

Supongamos que necesita hermandades, clanes, corporaciones, compañías, tribus, o como sea que su juego los llame: PlayFab puede satisfacer su necesidad de agrupación duradera de jugadores mediante el [Modelo de programación de entidades](/services/playfab/live-service-management/game-configuration/entities).

La entidad de grupo se puede usar para almacenar colecciones de otras entidades, incluidos jugadores o personajes, que pueden servir para muchos propósitos dentro de su juego.

## Ejemplos

* **Clanes/Hermandades**: los grupos de entidades se pueden usar para describir un conjunto de jugadores que juegan juntos con regularidad, sea cual sea el vínculo social que los mantiene unidos a largo plazo.

* **Grupos (parties)**: los grupos de entidades se pueden usar para grupos a corto plazo creados para permitir que jugadores individuales logren un objetivo inmediato y luego se disuelvan fácilmente.

* **Canales de chat**: los canales de chat a corto o largo plazo se pueden definir como un grupo de entidades.

* **Suscripción a información dentro del juego**: ¿tiene un objeto legendario de instancia única en su juego? ¿Los jugadores quieren actualizaciones constantes sobre lo que sucede con ese objeto? Cree un grupo de entidades centrado en ese objeto, con todas las entidades de jugador interesadas en el objeto como miembros.

En resumen, los grupos de entidades pueden ser *cualquier* colección de entidades (ya sean NPC o controladas por jugadores, reales o abstractas) que necesiten un estado persistente vinculado a ese grupo.

Además, dado que los grupos de entidades también son entidades en sí mismos, contendrán todas las características iniciales de las entidades:

* **Datos de objeto**
* **Datos de archivo**
* **Perfiles**

<Note>
  Los grupos tienen un límite predeterminado de 1000 miembros por grupo y solo admiten jugadores y personajes como miembros
</Note>

## Uso de grupos de entidades

Al crear un grupo, la primera entidad agregada al grupo se coloca en un rol de administrador (esta guía se refiere a esa entidad como el propietario, para simplificar). El propietario podrá entonces invitar a nuevos miembros, crear nuevos roles con una amplia variedad de permisos personalizables, modificar los roles de los miembros, expulsar miembros, etc.

Además, las mismas funciones de entidad que existen para las entidades *también funcionan para los grupos*, por lo que podrá guardar objetos JSON y archivos directamente en el grupo para almacenar datos arbitrarios específicos del juego.

El ejemplo de código que se proporciona a continuación debería darle una ventaja inicial en la interacción básica con hermandades.

Le permite crear grupos, agregar y quitar miembros, y eliminar el grupo. Está pensado como punto de partida y no demuestra ninguno de los roles ni permisos.

```csharp theme={null}
using PlayFab;
using PlayFab.GroupsModels;
using System;
using System.Collections.Generic;
using UnityEngine;

namespace TestGuildController
{
    /// <summary>
    /// Assumptions for this controller:
    /// + Entities can be in multiple groups
    ///   - This is game specific, many games would only allow 1 group, meaning you'd have to perform some additional checks to validate this.
    /// </summary>
    [Serializable]
    public class GuildTestController
    {
        // A local cache of some bits of PlayFab data
        // This cache pretty much only serves this example , and assumes that entities are uniquely identifiable by EntityId alone, which isn't technically true. Your data cache will have to be better.
        public readonly HashSet<KeyValuePair<string, string>> EntityGroupPairs = new HashSet<KeyValuePair<string, string>>();
        public readonly Dictionary<string, string> GroupNameById = new Dictionary<string, string>();

        public static EntityKey EntityKeyMaker(string entityId)
        {
            return new EntityKey { Id = entityId };
        }

        private void OnSharedError(PlayFab.PlayFabError error)
        {
            Debug.LogError(error.GenerateErrorReport());
        }

        public void ListGroups(EntityKey entityKey)
        {
            var request = new ListMembershipRequest { Entity = entityKey };
            PlayFabGroupsAPI.ListMembership(request, OnListGroups, OnSharedError);
        }
        private void OnListGroups(ListMembershipResponse response)
        {
            var prevRequest = (ListMembershipRequest)response.Request;
            foreach (var pair in response.Groups)
            {
                GroupNameById[pair.Group.Id] = pair.GroupName;
                EntityGroupPairs.Add(new KeyValuePair<string, string>(prevRequest.Entity.Id, pair.Group.Id));
            }
        }

        public void CreateGroup(string groupName, EntityKey entityKey)
        {
            // A player-controlled entity creates a new group
            var request = new CreateGroupRequest { GroupName = groupName, Entity = entityKey };
            PlayFabGroupsAPI.CreateGroup(request, OnCreateGroup, OnSharedError);
        }
        private void OnCreateGroup(CreateGroupResponse response)
        {
            Debug.Log("Group Created: " + response.GroupName + " - " + response.Group.Id);

            var prevRequest = (CreateGroupRequest)response.Request;
            EntityGroupPairs.Add(new KeyValuePair<string, string>(prevRequest.Entity.Id, response.Group.Id));
            GroupNameById[response.Group.Id] = response.GroupName;
        }
        public void DeleteGroup(string groupId)
        {
            // A title, or player-controlled entity with authority to do so, decides to destroy an existing group
            var request = new DeleteGroupRequest { Group = EntityKeyMaker(groupId) };
            PlayFabGroupsAPI.DeleteGroup(request, OnDeleteGroup, OnSharedError);
        }
        private void OnDeleteGroup(EmptyResponse response)
        {
            var prevRequest = (DeleteGroupRequest)response.Request;
            Debug.Log("Group Deleted: " + prevRequest.Group.Id);

            var temp = new HashSet<KeyValuePair<string, string>>();
            foreach (var each in EntityGroupPairs)
                if (each.Value != prevRequest.Group.Id)
                    temp.Add(each);
            EntityGroupPairs.IntersectWith(temp);
            GroupNameById.Remove(prevRequest.Group.Id);
        }

        public void InviteToGroup(string groupId, EntityKey entityKey)
        {
            // A player-controlled entity invites another player-controlled entity to an existing group
            var request = new InviteToGroupRequest { Group = EntityKeyMaker(groupId), Entity = entityKey };
            PlayFabGroupsAPI.InviteToGroup(request, OnInvite, OnSharedError);
        }
        public void OnInvite(InviteToGroupResponse response)
        {
            var prevRequest = (InviteToGroupRequest)response.Request;

            // Presumably, this would be part of a separate process where the recipient reviews and accepts the request
            var request = new AcceptGroupInvitationRequest { Group = EntityKeyMaker(prevRequest.Group.Id), Entity = prevRequest.Entity };
            PlayFabGroupsAPI.AcceptGroupInvitation(request, OnAcceptInvite, OnSharedError);
        }
        public void OnAcceptInvite(EmptyResponse response)
        {
            var prevRequest = (AcceptGroupInvitationRequest)response.Request;
            Debug.Log("Entity Added to Group: " + prevRequest.Entity.Id + " to " + prevRequest.Group.Id);
            EntityGroupPairs.Add(new KeyValuePair<string, string>(prevRequest.Entity.Id, prevRequest.Group.Id));
        }

        public void ApplyToGroup(string groupId, EntityKey entityKey)
        {
            // A player-controlled entity applies to join an existing group (of which they are not already a member)
            var request = new ApplyToGroupRequest { Group = EntityKeyMaker(groupId), Entity = entityKey };
            PlayFabGroupsAPI.ApplyToGroup(request, OnApply, OnSharedError);
        }
        public void OnApply(ApplyToGroupResponse response)
        {
            var prevRequest = (ApplyToGroupRequest)response.Request;

            // Presumably, this would be part of a separate process where the recipient reviews and accepts the request
            var request = new AcceptGroupApplicationRequest { Group = prevRequest.Group, Entity = prevRequest.Entity };
            PlayFabGroupsAPI.AcceptGroupApplication(request, OnAcceptApplication, OnSharedError);
        }
        public void OnAcceptApplication(EmptyResponse response)
        {
            var prevRequest = (AcceptGroupApplicationRequest)response.Request;
            Debug.Log("Entity Added to Group: " + prevRequest.Entity.Id + " to " + prevRequest.Group.Id);
        }
        public void KickMember(string groupId, EntityKey entityKey)
        {
            var request = new RemoveMembersRequest { Group = EntityKeyMaker(groupId), Members = new List<EntityKey> { entityKey } };
            PlayFabGroupsAPI.RemoveMembers(request, OnKickMembers, OnSharedError);
        }
        private void OnKickMembers(EmptyResponse response)
        {
            var prevRequest= (RemoveMembersRequest)response.Request;
            
            Debug.Log("Entity kicked from Group: " + prevRequest.Members[0].Id + " to " + prevRequest.Group.Id);
            EntityGroupPairs.Remove(new KeyValuePair<string, string>(prevRequest.Members[0].Id, prevRequest.Group.Id));
        }
    }
}
```

## Análisis del ejemplo

Este ejemplo está construido como un controlador, que guarda una cantidad mínima de datos en una caché local (siendo PlayFab la capa de datos autoritativa) y proporciona una manera de realizar operaciones CRUD en los grupos.

Veamos algunas de las funciones del ejemplo proporcionado:

* `OnSharedError`: este es un patrón típico en los ejemplos de PlayFab. La manera más sencilla de controlar un error es notificarlo. Es probable que el cliente de su juego tenga una lógica de control de errores mucho más sofisticada.

* `ListMembership`: llama a `ListMembership` para determinar todos los grupos a los que pertenece la entidad dada. Los jugadores quieren conocer los grupos a los que ya se han unido.

* `CreateGroup`/`DeleteGroup`: en su mayoría, se explican por sí solos. Este ejemplo demuestra la actualización de la caché local de información de grupos cuando estas llamadas se ejecutan correctamente.

* `InviteToGroup`/`ApplyToGroup`: unirse a un grupo es un proceso de dos pasos, y puede activarse en ambas direcciones:
  * Un jugador puede solicitar unirse a un grupo.
  * Un grupo puede invitar a un jugador.

* `AcceptGroupInvitation`/`AcceptGroupApplication`: el segundo paso del proceso de unión. La entidad que responde acepta la invitación, completando el proceso de hacer que el jugador forme parte del grupo.

* `RemoveMembers`: los miembros con autoridad para hacerlo (definida por los permisos de su rol) podrán expulsar miembros de un grupo.

## Servidor frente a cliente

Como en todos los métodos nuevos de la API de entidades, no hay distinción entre la API de servidor y la API de cliente.

La acción la realiza el autor de la llamada, según cómo se haya autenticado el proceso. Un cliente se identificará como tal y llamará a estos métodos como una entidad de jugador del título, y sus roles y permisos dentro del grupo se evaluarán con cada llamada, garantizando que tenga permiso para realizar esta acción.

Un servidor se autentica con la misma `developerSecretKey`, que identifica ese proceso como una entidad de título. Un título omite las comprobaciones de roles, y las llamadas a la API ejecutadas por un título solo fallarán si la acción es imposible de realizar, por ejemplo, si una entidad no se puede quitar cuando no es miembro.

## Consulte también

Para almacenar datos de sus grupos, hermandades o clanes:

* [Objetos](/services/playfab/live-service-management/game-configuration/entities/entity-objects)
* [Archivos](/services/playfab/live-service-management/game-configuration/entities/entity-files)


## Related topics

- [PFGroupsEntityWithLineage](/es/services/playfab/api-references/c/pfgroupstypes/structs/pfgroupsentitywithlineage.md)
- [PFGroupsEntityMemberRole](/es/services/playfab/api-references/c/pfgroupstypes/structs/pfgroupsentitymemberrole.md)
- [PFGroupsBlockEntityAsync](/es/services/playfab/api-references/c/pfgroups/functions/pfgroupsblockentityasync.md)
- [PFGroupsUnblockEntityAsync](/es/services/playfab/api-references/c/pfgroups/functions/pfgroupsunblockentityasync.md)
- [PFGroupsUnblockEntityRequest](/es/services/playfab/api-references/c/pfgroupstypes/structs/pfgroupsunblockentityrequest.md)
