Las solicitudes que realizas a los almacenes de datos pueden fallar debido a una mala conectividad u otros problemas. Para manejar errores y devolver mensajes con un código de error, envuelve las funciones del almacén de datos en pcall().
Una llamada de escritura fallida, como UpdateAsync(), significa que el servidor del juego no recibió una respuesta exitosa. No siempre garantiza que la escritura en el backend no haya ocurrido. En algunos escenarios de falla, el estado final de la escritura puede ser desconocido para el llamador hasta que se verifique con una lectura de seguimiento sin caché.
Referencia de códigos de error
| Código de error | Nombre del error | Mensaje de error | Notas | |
|---|---|---|---|---|
| 101 | KeyNameEmpty | El nombre de la clave no puede estar vacío. | Verifica si la clave ingresada en la función del almacén de datos es una cadena vacía. | |
| 102 | KeyNameLimit | El nombre de la clave excede el límite de 50 caracteres. | Verifica si la clave ingresada en la función del almacén de datos excede una longitud de 50. | |
| 103 | ValueNotAllowed | No se puede permitir X en DataStore. | Una función de actualización incorrecta devolvió un valor de tipo X. | |
| 104 | CantStoreValue | No se puede almacenar X en DataStore. | La función de actualización devolvió un valor de tipo X que no se pudo serializar. | |
| 105 | ValueTooLarge | El valor serializado excede el límite de X. | Si estás configurando un valor con SetAsync() o UpdateAsync(), la longitud serializada del valor no puede exceder el tamaño X. Para verificar la longitud serializada de los datos, usa JSONEncode(). | |
| 106 | MaxValueInvalid | MaxValue debe ser un número entero. | Si estás pasando un valor máximo a GetSortedAsync() para un OrderedDataStore, debe ser un número entero. | |
| 106 | MinValueInvalid | MinValue debe ser un número entero. | Si estás pasando un valor mínimo a GetSortedAsync() para un OrderedDataStore, debe ser un número entero. | |
| 106 | PageSizeGreater | PageSize debe estar dentro de un rango predefinido. | El tamaño mínimo de página para un OrderedDataStore es 1. | |
| 106 | PageSizeLesser | PageSize debe estar dentro de un rango predefinido. | El tamaño máximo de página para un OrderedDataStore es 100. | |
| 107 | MinMaxOrderInvalid | MaxValue debe ser mayor o igual a MinValue. | El valor máximo debe ser mayor o igual al valor mínimo para GetSortedAsync(). | |
| 301 | GetAsyncThrottle | Solicitud GetAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud GetAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 302 | SetAsyncThrottle | Solicitud SetAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud SetAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 303 | IncreAsyncThrottle | Solicitud IncrementAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud IncrementAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 304 | UpdateAsyncThrottle | Solicitud UpdateAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud UpdateAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 304 | TransformThrottle | Solicitud UpdateAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud UpdateAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 305 | GetSortedThrottle | Solicitud GetSorted descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud GetSortedAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 306 | RemoveAsyncThrottle | Solicitud RemoveAsync descartada. La solicitud fue limitada pero la cola estaba llena. | La solicitud RemoveAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | |
| 401 | DataModelNoAccess | La solicitud falló. DataModel es inaccesible mientras la experiencia se está cerrando. | DataModel no está inicializado porque la experiencia se está cerrando. | |
| 402 | LuaWebSrvsNoAccess | La solicitud falló. LuaWebService es inaccesible mientras la experiencia se está cerrando. | LuaWebService no está inicializado porque la experiencia se está cerrando. | |
| 403 | StudioAccessToApisNotAllowed | No se puede escribir en DataStore desde Studio porque el acceso a la API no está habilitado. | El acceso a la API debe estar activo para usar almacenes de datos en Studio. | |
| 404 | InternalError | OrderedDataStore no existe. | El OrderedDataStore asociado con esta solicitud no fue encontrado. Esto podría ser un signo de corrupción de datos. Intenta de nuevo más tarde. | |
| 501 | InternalError | No se puede analizar la respuesta porque los datos pueden estar corruptos. | El servidor no pudo analizar la respuesta a tu solicitud. Esto podría ser un signo de corrupción de datos. Intenta de nuevo más tarde. | |
| 502 | RequestRejected | Los servicios de API rechazaron la solicitud con el error X. | Ocurrió el error X al procesar en los servidores de Roblox. Intenta de nuevo más tarde. | |
| 503 | InternalError | La solicitud del almacén de datos fue exitosa, pero la clave no fue encontrada. | La clave solicitada no fue encontrada en el almacén de datos. Esto podría ser un signo de corrupción de datos. Intenta de nuevo más tarde. | |
| 504 | InternalError | La solicitud del almacén de datos fue exitosa, pero la respuesta no fue formateada correctamente. | El servidor no pudo analizar la respuesta a tu solicitud. Esto podría ser un signo de corrupción de datos. Intenta de nuevo más tarde. | |
| 505 | InternalError | La solicitud de OrderedDataStore fue exitosa, pero la respuesta no fue formateada correctamente. | El servidor no pudo analizar la respuesta a tu solicitud de OrderedDataStore. Esto podría ser un signo de corrupción de datos. Intenta de nuevo más tarde. | |
| 509 | OperationNotAllowed | Las operaciones del almacén de datos están bloqueadas mientras se ejecuta en un RCC Personal para prevenir posible corrupción de datos. | Las escrituras en el almacén de datos están bloqueadas en canales RCC privados. | |
| 511 | AttributeSizeTooLarge | El tamaño del atributo de metadatos excede el límite de X. | El tamaño de los metadatos serializados excede el límite de X. El valor X es dinámico. Si el tamaño cambia, el valor también cambia. | |
| 512 | UserIdLimitExceeded | El tamaño de UserID excede el límite de X. | La longitud del array de IDs de usuario proporcionado por el usuario excede el límite de X. | |
| 513 | AttributeFormatError | El formato del atributo userId es inválido. | El ID de usuario proporcionado no es un número. | |
| 513 | AttributeFormatError | El formato de los metadatos del atributo es inválido. | Los metadatos no son una tabla. | |
| GetVersionAsyncThrottle | Solicitud GetVersionAsync descartada. La solicitud fue limitada. | La solicitud GetVersionAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | ||
| GetVersionAtTimeAsyncThrottle | Solicitud GetVersionAtTimeAsync descartada. La solicitud fue limitada. | La solicitud GetVersionAtTimeAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | ||
| ListDataStoresAsyncThrottle | Solicitud ListDataStoresAsync descartada. La solicitud fue limitada. | La solicitud ListDataStoresAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | ||
| ListKeysAsyncThrottle | Solicitud ListKeysAsync descartada. La solicitud fue limitada. | La solicitud ListKeysAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | ||
| ListVersionsAsyncThrottle | Solicitud ListVersionsAsync descartada. La solicitud fue limitada. | La solicitud ListVersionsAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | ||
| RemoveVersionAsyncThrottle | Solicitud RemoveVersionAsync descartada. La solicitud fue limitada. | La solicitud RemoveVersionAsync() ha excedido el tamaño máximo de la cola y Roblox no puede procesar las solicitudes a la tasa actual. | ||
| InvalidTimestamp | La marca de tiempo debe ser positiva y no más de diez minutos en el futuro. | La marca de tiempo proporcionada a GetVersionAtTimeAsync() no era válida. | ||
| StandardReadExperienceThrottled | La solicitud StandardRead fue limitada por los límites de experiencia. | Una solicitud a GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), o la lectura de UpdateAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de experiencia StandardRead. | ||
| StandardWriteExperienceThrottled | La solicitud StandardWrite fue limitada por los límites de experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de experiencia StandardWrite. | ||
| StandardListExperienceThrottled | La solicitud StandardList fue limitada por los límites de experiencia. | Una solicitud a ListKeysAsync(), ListVersionsAsync(), o ListDataStoresAsync() en almacenes de datos estándar excedió el límite de tasa de nivel de experiencia StandardList. | ||
| StandardRemoveExperienceThrottled | La solicitud StandardRemove fue limitada por los límites de experiencia. | Una solicitud a RemoveAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de experiencia StandardRemove. | ||
| OrderedReadExperienceThrottled | La solicitud OrderedRead fue limitada por los límites de experiencia. | Una solicitud a GetAsync(), BatchGetAsync(), o la lectura de UpdateAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedRead. | ||
| OrderedWriteExperienceThrottled | La solicitud OrderedWrite fue limitada por los límites de experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedWrite. | ||
| OrderedListExperienceThrottled | La solicitud OrderedList fue limitada por los límites de experiencia. | Una solicitud a GetSortedAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedList. | ||
| OrderedRemoveExperienceThrottled | La solicitud OrderedRemove fue limitada por los límites de experiencia. | Una solicitud a RemoveAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedRemove. | ||
| StandardReadGameServerThrottled | La solicitud StandardRead fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), o la lectura de UpdateAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de servidor del juego StandardRead. | ||
| StandardWriteGameServerThrottled | La solicitud StandardWrite fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de servidor del juego StandardWrite. | ||
| StandardListGameServerThrottled | La solicitud StandardList fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a ListKeysAsync(), ListVersionsAsync(), o ListDataStoresAsync() en almacenes de datos estándar excedió el límite de tasa de nivel de servidor del juego StandardList. | ||
| StandardRemoveGameServerThrottled | La solicitud StandardRemove fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a RemoveAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de servidor del juego StandardRemove. | ||
| OrderedReadGameServerThrottled | La solicitud OrderedRead fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a GetAsync(), BatchGetAsync(), o la lectura de UpdateAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de servidor del juego OrderedRead. | ||
| OrderedWriteGameServerThrottled | La solicitud OrderedWrite fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de servidor del juego OrderedWrite. | ||
| OrderedListGameServerThrottled | La solicitud OrderedList fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a GetSortedAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de servidor del juego OrderedList. | ||
| OrderedRemoveGameServerThrottled | La solicitud OrderedRemove fue limitada por los límites del servidor del juego o la cola de solicitudes estaba llena. | Una solicitud a RemoveAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de servidor del juego OrderedRemove. |
Códigos de error del servidor
| Nombre del error | Mensaje de error | Notas |
|---|---|---|
| DatastoreDeleted | El almacén de datos ha sido eliminado. | No se pudo realizar una operación en el almacén de datos porque el almacén de datos fue eliminado previamente. |
| DatastoreThrottled | La tasa de solicitudes excede el máximo permitido para el datastore. | Se enviaron demasiadas solicitudes a un solo almacén de datos. |
| InternalServerError | Ocurrió un error interno del servidor. | Error ocasional en los servidores de Roblox. Intenta de nuevo, idealmente con retroceso exponencial. |
| InvalidExclusiveStartKey | La clave de inicio exclusiva proporcionada no es válida. | La clave de inicio exclusiva (cursor) proporcionada a una operación de lista como ListKeysAsync() no es válida. |
| InvalidPlace | El lugar proporcionado es inválido. | No hay un ID de universo coincidente para el lugar. Intenta de nuevo más tarde. |
| InvalidTarget | El objetivo proporcionado es inválido. | El nombre de la clave del almacén de datos ordenados excede el límite de 50 caracteres. |
| InvalidUniverse | El universo proporcionado es inválido. | No hay un ID de lugar coincidente para el universo. Intenta de nuevo más tarde. |
| InvalidUserIds | Los IDs de usuario proporcionados tienen un formato inválido. | No se pudo analizar los IDs de usuario. |
| KeyThrottled | La tasa de solicitudes excede el máximo permitido para la clave. | La tasa de solicitudes excede la tasa máxima permitida para una sola clave. |
| KeyNotFound | La clave solicitada no existe. | La clave no existe. |
| N/A | No hay páginas a las que avanzar. | Este error ocurre cuando llamas a Pages:AdvanceToNextPageAsync() en la última página. |
| StandardReadExperienceThrottled | La tasa de solicitudes de lectura estándar excede el máximo permitido para la experiencia. | Una solicitud a GetAsync(), GetVersionAsync(), GetVersionAtTimeAsync(), o la lectura de UpdateAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de experiencia StandardRead. |
| StandardWriteExperienceThrottled | La tasa de solicitudes de escritura estándar excede el máximo permitido para la experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de experiencia StandardWrite. |
| StandardListExperienceThrottled | La tasa de solicitudes de lista estándar excede el máximo permitido para la experiencia. | Una solicitud a ListKeysAsync(), ListVersionsAsync(), o ListDataStoresAsync() en almacenes de datos estándar excedió el límite de tasa de nivel de experiencia StandardList. |
| StandardRemoveExperienceThrottled | La tasa de solicitudes de eliminación estándar excede el máximo permitido para la experiencia. | Una solicitud a RemoveAsync() en un almacén de datos estándar excedió el límite de tasa de nivel de experiencia StandardRemove. |
| OrderedReadExperienceThrottled | La tasa de solicitudes de lectura ordenada excede el máximo permitido para la experiencia. | Una solicitud a GetAsync(), BatchGetAsync(), o la lectura de UpdateAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedRead. |
| OrderedWriteExperienceThrottled | La tasa de solicitudes de escritura ordenada excede el máximo permitido para la experiencia. | Una solicitud a SetAsync(), IncrementAsync(), o la escritura de UpdateAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedWrite. |
| OrderedListExperienceThrottled | La tasa de solicitudes de lista ordenada excede el máximo permitido para la experiencia. | Una solicitud a GetSortedAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedList. |
| OrderedRemoveExperienceThrottled | La tasa de solicitudes de eliminación ordenada excede el máximo permitido para la experiencia. | Una solicitud a RemoveAsync() en un almacén de datos ordenados excedió el límite de tasa de nivel de experiencia OrderedRemove. |
Límites
Los modelos de datos tienen límites. Si una experiencia excede estos límites, el servicio limita automáticamente el uso del almacén de datos de la experiencia y provoca que las solicitudes futuras se coloquen en una de las siguientes colas:
- Establecer
- Establecer ordenado
- Obtener
- Obtener ordenado
Las solicitudes en una cola se manejan en el orden en que se reciben. La función llamada continúa cediendo mientras su solicitud aún esté en cola. Si la clave del almacén de datos en sí está limitada, la solicitud se coloca en una cola pero se omite temporalmente.
Cada cola tiene un límite de 30 solicitudes. Cuando se alcanza el límite de una cola, las solicitudes fallan con un código de error en el rango 301-306, indicando que las solicitudes han sido descartadas por completo.
Límites de acceso
Los almacenes de datos están sujetos a límites de experiencia y de nivel de servidor. Los límites de nivel de experiencia escalan con el número total de usuarios concurrentes en la experiencia, mientras que los límites de nivel de servidor son configurables y están destinados a ser utilizados como una herramienta por el creador.
Límites de experiencia
Cada experiencia tiene permitido un cierto número de solicitudes de almacén de datos según el tipo de almacén de datos, el tipo de solicitud y el número de usuarios concurrentes. Para cada tipo de almacén de datos y tipo de solicitud, el límite se comparte entre todas las funciones enumeradas.
- UpdateAsync() consume tanto del presupuesto de solicitudes de lectura como de escritura. Una sola llamada disminuirá ambos límites.
- El servidor del juego y Open Cloud comparten un presupuesto; el tráfico de Open Cloud puede ser limitado por el uso en la experiencia (y viceversa). Consulta Controlar límites de tasa para obtener más orientación.
Almacenes de datos estándar
| Tipo de solicitud | API del servidor del juego | API de Open Cloud | Límites compartidos (solicitudes por minuto) |
|---|---|---|---|
| Leer | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | Obtener entrada del almacén de datos | 300 + concurrentUsers × 40 |
| Escribir | SetAsync() IncrementAsync() UpdateAsync() | Crear, actualizar, incrementar entrada del almacén de datos | 300 + concurrentUsers × 20 |
| Listar | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | Listar almacenes de datos, listar entradas del almacén de datos, listar revisiones de entradas del almacén de datos | 300 + concurrentUsers × 2 |
| Eliminar | RemoveAsync() | Eliminar entrada del almacén de datos, eliminar almacén de datos, restaurar almacén de datos | 300 + concurrentUsers × 40 |
Almacenes de datos ordenados
| Tipo de solicitud | API del servidor del juego | API de Open Cloud | Límites compartidos (solicitudes por minuto) |
|---|---|---|---|
| Leer | GetAsync() BatchGetAsync() UpdateAsync() | Obtener entrada del almacén de datos ordenados | 300 + concurrentUsers × 40 |
| Escribir | SetAsync() IncrementAsync() UpdateAsync() | Crear, actualizar, incrementar entrada del almacén de datos ordenados | 300 + concurrentUsers × 20 |
| Listar | GetSortedAsync() | Listar entradas del almacén de datos ordenados | 300 + concurrentUsers × 2 |
| Eliminar | RemoveAsync() | Eliminar entrada del almacén de datos ordenados | 300 + concurrentUsers × 40 |
Controlar límites de tasa
Debido a que las solicitudes de Open Cloud y del servidor del juego son compartidas, es importante controlar de manera independiente cuánto puede consumir cada una del presupuesto.
Servidor del juego
Los servidores individuales tienen límites incorporados, como se describió anteriormente. Usa una combinación de SetRateLimitForRequestType() y GetRequestBudgetForRequestType() para mantener un control detallado sobre la contribución de los servidores individuales al presupuesto total.
Open Cloud
Las solicitudes de Open Cloud requieren una solución externa de limitación de tasa. Recomendamos uno de los siguientes enfoques:
- (Simple) Agrega un breve tiempo de espera después de cada solicitud, especialmente si llamas a la misma API en un bucle continuo. Establece este tiempo de espera igual a 60 / (consumo de presupuesto deseado por minuto) segundos, como un límite superior. Ten en cuenta que este enfoque no permite enviar solicitudes en ráfagas.
- (Robusto) Implementa un limitador de tasa local utilizando la estrategia de cubo con fugas.
Los siguientes ejemplos de código en Node.js incluyen implementaciones de referencia.
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('La variable de entorno API_KEY no está configurada.');
}
const apiHeaderKey = 'x-api-key';
const universeId = '';
const dataStoreId = 'Inventario';
const baseUrl = 'https://apis.roblox.com/cloud/v2/';
// --- Configuración de limitación de tasa por operación (solicitudes por minuto) ---
const LIST_RATE_PER_MIN = 60;
const GET_RATE_PER_MIN = 120;
const UPDATE_RATE_PER_MIN = 60;
// Espaciado superior por operación: 60 / (solicitudes por min) segundos.
const LIST_INTERVAL_MS = (60 / LIST_RATE_PER_MIN) * 1000;
const GET_INTERVAL_MS = (60 / GET_RATE_PER_MIN) * 1000;
const UPDATE_INTERVAL_MS = (60 / UPDATE_RATE_PER_MIN) * 1000;
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
// Realiza la solicitud, luego espera el intervalo de esta operación antes de devolver.
async function throttledFetch(url, options, intervalMs) {
const response = await fetch(url, options);
await sleep(intervalMs);
return response;
}
async function listEntries(universe, dataStore) {
const listPath = `universes/${universe}/data-stores/${dataStore}/entries`;
const url = baseUrl + listPath;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, LIST_INTERVAL_MS);
return response.json();
}
async function getEntry(path) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
headers: { [apiHeaderKey]: apiKey }
}, GET_INTERVAL_MS);
return response.json();
}
async function updateEntry(path, payload) {
const url = baseUrl + path;
const response = await throttledFetch(url, {
method: 'PATCH',
headers: {
[apiHeaderKey]: apiKey,
'Content-Type': 'application/json'
},
body: JSON.stringify(payload) // El cuerpo debe ser una cadena
}, UPDATE_INTERVAL_MS);
return response;
}
(async () => {
try {
const entries = await listEntries(universeId, dataStoreId);
for (const entry of entries.dataStoreEntries) {
const path = entry.path;
console.log(`\nProcesando entrada: ${path}`);
const currentData = await getEntry(path);
currentData.value.currency += 10;
const payload = { value: currentData.value };
const updateResponse = await updateEntry(path, payload);
console.log(`Estado: ${updateResponse.status}`);
console.log(`Respuesta: ${await updateResponse.text()}`);
}
} catch (error) {
console.error('Ocurrió un error durante la ejecución:', error);
}
})();Límites del servidor
Cada servidor tiene un límite de tasa configurable para cada tipo de solicitud, basado en el número de jugadores en ese servidor. Los servidores reciben un aumento de presupuesto de solicitudes adicional único cuando se crean por primera vez. Usa GetRequestBudgetForRequestType() para confirmar el número de solicitudes de almacén de datos que el servidor actual puede realizar en cualquier momento.
Estos límites son configurables por el creador utilizando la API SetRateLimitForRequestType(). Usando esta API, un creador puede configurar sus propios límites de tasa de almacenes de datos para cada tipo de solicitud.
Los siguientes límites de tasa predeterminados se aplican si no se llama a la API:
Almacenes de datos estándar
| Tipo de solicitud | Enum DataStoreRequestType | API del servidor del juego | Solicitudes por minuto |
|---|---|---|---|
| Leer | StandardRead | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Escribir | StandardWrite | SetAsync() IncrementAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Listar | StandardList | ListDataStoresAsync() ListKeysAsync() ListVersionsAsync() | 5 + numPlayers × 2 |
| Eliminar | StandardRemove | RemoveAsync() | 60 + numPlayers × 40 |
| EliminarVersión (Obsoleto) | RemoveVersionAsync | RemoveVersionAsync() | 5 + numPlayers × 2 |
Almacenes de datos ordenados
| Tipo de solicitud | Enum DataStoreRequestType | API del servidor del juego | Solicitudes por minuto |
|---|---|---|---|
| Leer | OrderedRead | GetAsync() BatchGetAsync() UpdateAsync() | 60 + numPlayers × 40 |
| Escribir | OrderedWrite | SetAsync() IncrementAsync() UpdateAsync() | 30 + numPlayers × 5 |
| Listar | OrderedList | GetSortedAsync() | 5 + numPlayers × 2 |
| Eliminar | OrderedRemove | RemoveAsync() | 30 + numPlayers × 5 |
Límites de datos
Los almacenes de datos limitan cuánto se puede usar por entrada.
El nombre del almacén de datos, el nombre de la clave y el alcance deben estar todos bajo una cierta longitud de caracteres. Usa string.len() para verificar su longitud.
Los datos (valor de clave) también se almacenan como una cadena, independientemente de su tipo inicial. Puedes verificar el tamaño de los datos con la función JSONEncode(), que convierte datos de Luau en una tabla JSON serializada.
| Componente | Número máximo de caracteres |
|---|---|
| Nombre del almacén de datos | 50 |
| Nombre de la clave | 50 |
| Alcance | 50 |
| Datos (valor de clave) | 4,194,304 por clave |
Límites de metadatos
Límites al número de caracteres en los metadatos definidos por el usuario.
| Componente | Número máximo de caracteres |
|---|---|
| Nombre de la clave | 50 |
| Valor | 250 |
| Pares clave-valor | 300 |
Límites de rendimiento
Los límites de rendimiento por clave aseguran que el rendimiento sea óptimo en los servidores de Roblox. Cada límite se aplica a cada clave individual en todos los servidores de una experiencia y se actualiza con el tiempo.
Roblox examina el uso de la cuota asociada con la clave durante los últimos 60 segundos. Si el uso, incluida la solicitud actual, está dentro del límite de rendimiento, la solicitud es aprobada. Si el uso excede el límite, la solicitud es denegada.
| Tipo de solicitud | API del servidor del juego | API de Open Cloud | Límite |
|---|---|---|---|
| Leer | GetAsync() GetVersionAsync() GetVersionAtTimeAsync() ListVersionsAsync() UpdateAsync() | Obtener entrada del almacén de datos | 25 MB por minuto |
| Escribir | SetAsync() IncrementAsync() UpdateAsync() RemoveAsync() | Crear, actualizar, incrementar, eliminar entrada del almacén de datos | 4 MB por minuto |
Además de los límites de rendimiento anteriores, Roblox organiza los datos en particiones basadas en un esquema interno. Como resultado, cuando el servidor backend recibe un alto volumen de solicitudes al mismo almacén de datos, puede resultar en una limitación adicional. Independientemente de la causa, la limitación se manifiesta como errores DatastoreThrottled o KeyThrottled, dependiendo de si se excedió el límite de rendimiento para un solo almacén de datos o una clave. Estos mensajes de error se aplican tanto a almacenes de datos ordenados como estándar.
Límites de almacenamiento
Para mantener el almacenamiento estable y escalable, los almacenes de datos utilizan un límite de nivel de juego en tu uso de almacenamiento.
Este límite consiste en una asignación base para cada juego más una asignación adicional basada en el número de usuarios de por vida. Un usuario de por vida es cualquier usuario que se haya unido a tu juego al menos una vez.
El límite de almacenamiento se calcula utilizando la siguiente fórmula Límite total de almacenamiento de la última versión = 500 MB + 1 MB × número de usuarios de por vida.
El uso de almacenamiento se mide utilizando el tamaño comprimido de la última versión de cada clave. Los almacenes de datos comprimen automáticamente tus datos antes del almacenamiento, así que evita comprimirlos tú mismo. La precompresión agrega una sobrecarga innecesaria de CPU y puede reducir la efectividad de la compresión incorporada de los almacenes de datos. Al almacenar datos sin comprimir, te beneficias automáticamente de las mejoras en los algoritmos de compresión de Roblox y de futuras optimizaciones basadas en esquemas.
Solo la última versión de cada clave cuenta para tu uso de almacenamiento. Las claves eliminadas y las versiones superadas, aunque aún son accesibles a través de las API de versiones durante su período de retención, no cuentan para tu uso de almacenamiento. Sin embargo, los almacenes de datos eliminados a través del método Open Cloud DeleteDataStore continúan contando para el uso de almacenamiento durante su período de procesamiento de eliminación de 30 días, hasta que sean eliminados permanentemente.