Geliştirici Portalı
Deneysel Bot ve uygulama platformu aktif olarak geliştiriliyor. Kendi barındırdığın sunucu desteği 13.08.2026'da yayınlandı ve buluta göre daha az özellik sunuyor. Nelerin desteklendiğine bak.
← Dokümanlar

Snowflake'ler

GameVox, Discord API'sinin döndüreceği her yerde ID'leri Discord'un 64 bitlik snowflake formatında döndürür. Bit düzeni, sıralama ve zaman damgası çıkarma hesabı aynıdır: mevcut snowflake ayrıştırma kodun değişiklik olmadan çalışır.

Format

Discord'unkiyle aynı: 64 bitlik işaretsiz bir tam sayı içinde big-endian olarak 42 bit zaman damgası + 5 bit worker + 5 bit process + 12 bit artış.

┌─ 42 bits ─────────────────┬─ 5 ─┬─ 5 ─┬─ 12 ────────┐
│ GameVox epoch'undan bu ya │ wkr │ prc │ increment   │
└───────────────────────────┴─────┴─────┴─────────────┘
 63                       22  21 17 16 12 11           0

Her bölüm Discord ile eşleşir:

  • Zaman damgası (42 bit): GameVox epoch'undan bu yana geçen milisaniye, aşağıya bak.
  • Worker ID (5 bit): çalışan her api görevine başlangıçta Redis atomik sayacıyla atanır.
  • Process ID (5 bit): benzersiz bir üretim havuzu için worker ile eşleştirilir.
  • Artış (12 bit): her (worker, process) için milisaniye başına sıra numarası.

Epoch

GameVox, Discord ile aynı epoch'u kullanır: 1420070400000 (2015-01-01 00:00:00 UTC). Discord için yazılmış bir snowflake ayrıştırıcısı GameVox ID'lerinde değişiklik olmadan çalışır: değiştirilecek bir sabit yok.

const SNOWFLAKE_EPOCH = 1420070400000n;

Veri formatı

REST / gateway üzerinden giden her snowflake bir sayı olarak değil, JSON string olarak serileştirilir. JavaScript Number.MAX_SAFE_INTEGER (253-1) üzerindeki değerlerde hassasiyet kaybeder ve bir snowflake bunu düzenli olarak aşar. Hesaplama yapman gerektiğinde her zaman BigInt ile ayrıştır, diğer her yerde string olarak sakla.

// Doğru
const id = BigInt(message.id);

// Yanlış: sessizce hassasiyet kaybı
const id = Number(message.id);

Zaman damgasını çıkarma

JavaScript

function snowflakeToDate(snowflake) {
  const EPOCH = 1420070400000n;          // Discord ile aynı
  const ms = Number((BigInt(snowflake) >> 22n) + EPOCH);
  return new Date(ms);
}

console.log(snowflakeToDate('182955831900192769'));
// → Date nesnesi: bu snowflake'in üretildiği an

Python

from datetime import datetime, timezone

SNOWFLAKE_EPOCH = 1420070400000

def snowflake_to_dt(snowflake):
    ms = (int(snowflake) >> 22) + SNOWFLAKE_EPOCH
    return datetime.fromtimestamp(ms / 1000, tz=timezone.utc)

Java

long SNOWFLAKE_EPOCH = 1420070400000L;
long ms = (Long.parseUnsignedLong(snowflake) >>> 22) + SNOWFLAKE_EPOCH;
Instant when = Instant.ofEpochMilli(ms);

Sıralama

Zaman damgası yüksek bitlerde olduğu için iki snowflake'in sözlük sırasına göre string karşılaştırması onları kronolojik olarak sıralar, tıpkı Discord'daki gibi. Mesajlar endpoint'indeki before / after / around sayfalamasının ayrı bir zaman damgası alanı olmadan çalışmasının nedeni budur.

// Bir mesaj dizisinde, en eskiden → en yeniye:
messages.sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0);

Yerel veriler ve takma ad tablosu

Arka planda GameVox'un yerel nesneleri (sunucular, kanallar, kullanıcılar, mesajlar vb.) UUIDv4 kullanır. Bot uyumluluk katmanı, bir nesne bir bota ilk kez gösterildiğinde kalıcı bir snowflake üretir ve bu eşleşmeyi snowflake_aliases tablosunda saklar. O nesneye yapılan sonraki her başvuru (REST veya gateway üzerinden) aynı snowflake'i kullanır.

Mesajlar için snowflake'leri, kaynak zaman damgası olarak mesajın created_at değeriyle geriye dönük dolduruyoruz; böylece bir bot bir kanala ilk katıldığında geçmiş mesajlar doğru sıralanır. Diğer her şey için takma ad, ilk gösterimde zaman damgası olarak NOW() ile tembel biçimde üretilir; yani snowflake, nesnenin oluşturulduğu anı değil, botun nesneyi gördüğü anı yansıtır.

Sharding hash'i

Standart Discord shard formülü olduğu gibi çalışır:

shardId = (BigInt(guildId) >> 22n) % BigInt(numShards);

2.500'den az sunucudaki botlar tek bir shard üzerinde ([0, 1]) çalışır ve bunu hiç düşünmek zorunda kalmaz. Daha büyük botlar, Discord'un sağladığı yaklaşık eşit hash dağılımının aynısını alır, çünkü en üstteki 42 bit rastgele değil, zamanla monoton artar.

Dikkat edilmesi gerekenler

  • Snowflake'leri bir sayı sabitiyle == kullanarak karşılaştırma. Bunlar veri formatında string'dir: bir string ile karşılaştır ya da ikisini de BigInt'e çevir.
  • 42 bitlik zaman damgası, epoch'tan yaklaşık 139 yıl sonra başa döner. GameVox'un snowflake'leri 2165'e kadar geçerlidir.
  • Bir sunucunun / kanalın / rolün oluşturulma zamanını snowflake'inden çıkarmaya çalışma. Bot platformundan önce var olan yerel nesneler snowflake'lerini oluşturulduklarında değil, bir bota ilk gösterildiklerinde aldı. Mesajlar istisnadır (created_at ile geriye dönük doldurulur).

← Dokümanlara dön