Anbernic RG 55G1: Switch Lite o'xshashlikda yangi Snapdragon G1 Gen 2 bilan
Anbernic yangi RG 55G1 o'yin konsolini rasmiy ravishda ko'rsatdi: Snapdragon G1 Gen 2, 1080p ekran va PS2/Wii U emulyatsiyasi. Narx va sana hali yashirin.

2004-yilda ana telefon tarmog'i orqali internetga ulanib, RuneScape o'ynagan har qanday bolaning xotirasida ota-onasining telefonni ko'tarishi bilan ulanishning to'xtashi yaqiniy yaqin bo'lgan travma sifatida qolgan. Lekin bu travma orqa planda yurgan muhandislik dahosi yashirin edi: Java applet shaklida brauzerda ishlaydigan, serverda 2000 tagacha o'yinchi bo'ladigan, ekranda bir vaqtning o'zida yuzlab personajlar harakatlanadigan 3D MMORPG — 56 kilobitlik modemning haqiqiy 5 KB/s tezligida.
Zamonaviy o'yinlar gigabaytlik yuklamalar, UDP protokollari va CDN tarmoqlari bilan ishlaydi. RuneScape 2004 esa bitta TCP soketi, ISAAC shifrlash va har baytni hisoblab chiqadigan protokol ustida qurilgan edi. Bu — cheklovlar ostida samarali arxitektura qanday qurilishi haqidagi dars, u bugungi kunda ham mikroxizmatlar, IoT va past tarmoq kanallari uchun actual.
this.outboundCipher = new ISAAC(seed);
for (int index = 0; index < 4; index++) {
seed[index] += 50;
}
this.inboundCipher = new ISAAC(seed);
Jagex komanda uchta fizikal haqiqatga duch kelgan edi:
Bu cheklovlar o'zaro o'zlarini kuchaytirardi: TCP ning Nagle algoritmi kichik paketlarni to'plash uchun kechiktirishi, 600 ms tik o'z navbatida paketlarni jamlash va yuborish uchun juda qisqa vaqt qoldirishi.
public void putOpcode(int opcode) {
this.putByte(opcode + this.outboundCipher.value());
}
Kirish handshake tugagach, Jagex ISAAC oqim shifrini o'rnatadi. Diqqat: paket tanasi (body) shifrlanmaydi, faqat boshidagi opcode — bitta baytlik buyruq kodi. Ushbu opcode paketning qanday tahlil qilinishi va unda qayerda tugashi haqida ma'lumot beradi. Agar uchinchi shaxs opcode ni o'qiy olmasa, qolgan baytlar aniq tuzilmagan baytlar to'plamidan iborat qoladi.
Shifrlash quyidagicha ishlaydi: mijoz va server o'rtasida 4 ta butun sonli kalit bo'linadi. Mijoz o'ziga xos 2 tasini generatsiya qiladi, 2 tasi serverdan keladi. Har bir yo'nalish uchun alohida ISAAC oqimi: mijozdan serverga — outboundCipher, serverdan mijozga — inboundCipher (kalit so'zlariga 50 qo'shilgan holda). Opcode yuborilganda:
this.currentOpcode = (this.currentOpcode - this.inboundCipher.value()) & 0xFF;
putByte(opcode + outboundCipher.value())
Qabul qilinayotganda teskari amal bajariladi. Bu — eng arzon himoya: faqat bitta bayt shifrlanadi, lekin protokol tuzilishi yashirin qoladi.
Foydalanuvchi ekranda bir tomonga klik qiladi. Mijoz avval mahalliy to'siq qaramida (collision map) kenglikka birinchi qidiruv (BFS) bilan yo'l topib, keyin paketni tuzadi. Paket tarkibi:
this.outboundStream.putOpcode(ClientToServerOpcodes.WALK_TILE);
this.outboundStream.putByte(4 + 2 * (pathLength - 1) + 1);
WALK_TILE (shifrlangan holda).short — 2 baytlik butun son).signed byte, diapazon -128..127).Formula: 4 + 2 * (pathLength - 1) + 1 bayt. Agar yo'l 10 qadam bo'lsa, paket tanasi 23 baytdan iborat. Absolyut koordinatalar yuborilsa (har qadamda 4 bayt), bu 40 bayt bo'lardi — 50% tejash.
Delta yondashuvi — bu Jagex ning "bayt qimmat" falsafasining birinchi namunasidan tashqari emas. Har bir qo'shimcha waypoint 2 bayt orttiradi, 4 bayt emas. Uzoq masofaga yurish paketlari hammasi ham kichik, lekin uzoq yo'l har doim kam uchraydi.
int firstX = pathX[0];
int firstZ = pathZ[0];
this.outboundStream.putShort(this.playerPositionX + firstX);
this.outboundStream.putShort(this.playerPositionZ + firstZ);
for (int i = 1; i < pathLength; i++) {
this.outboundStream.putByte(this.pathX[i] - firstX);
this.outboundStream.putByte(this.pathZ[i] - firstZ);
}
Yo'l topish (pathfinding) serverda emas, mijozda amalga oshiriladi. Bu juda ahamiyati bor: server faqat natijani (waypointlar ketma-ketligini) qabul qiladi va tekshiradi. Agar har bir o'yinchi uchun server BFS ishlasa, 2000 o'yinchi uchun 600 ms ichida bu mahz kompyutatsiya to'qnashuvi yaratardi. Mijozga yukni o'tkazish — bu optimistik UI ning erta misollaridan biri: foydalanuvchi darhol harakatni ko'radi, server esa keyinroq tasdiqlaydi yoki bekor qiladi.
Bitta TCP ulanishi degani — barcha paketlar (harakat, so'ngi chat, interfeys yangilanishlari) bitta navbatda turadi. Agar katta paket (masalan, yangi hudud yuklanishi) kanalni to'ldirsa, harakat paketi kutib turishi shart. Jagex bunga uchta yechim bilan duch kelgan:
this.outboundStream.putByte(this.keyStatus[Keys.CTRL] == 1 ? 1 : 0);
600 ms tik — bu emas, 16.6 ms (60 FPS) emas. Bu juda katta oynadir, lekin TCP ning tartibga solish ta'minoti va kanal cheklovlari bilan mos keladi. Server har tikda "nima o'zgardi?" savoliga javob beradi va faqat o'zgarishlarni (delta) yuboradi.
Bugungi o'yinlar (masalan, World of Warcraft yoki Valorant) UDP asosida, maxsus kongruent protokollar (QUIC, ENet, Reliable UDP) va klient-ta'minot serverlari (CDN) ishlatadi. Ular paket yo'qotilishini o'zlari boshqaradi, TCP ning head-of-line blocking muammosi yo'q. Lekin 2004-yilda brauzer sandboksida UDP yo'q edi. Jagex TCP ning cheklovlari ichida eng samarali protokolni qurdi.
int opcode = player.inboundStream.takeOpcode();
if (opcode == ClientToServerOpcodes.WALK_TILE) {
int length = player.inboundStream.takeByte();
int deltaCount = (length - 4 - 1) / 2;
int[] firstWaypoint = new int[2];
firstWaypoint[0] = player.inboundStream.takeShort();
firstWaypoint[1] = player.inboundStream.takeShort();
int[][] waypointDeltas = new int[deltaCount][2];
for (int i = 0; i < deltaCount; i++) {
waypointDeltas[i][0] = player.inboundStream.takeByte();
waypointDeltas[i][1] = player.inboundStream.takeByte();
}
boolean holdingCtrl = player.inboundStream.takeByte() == 1;
player.processWalkTile(firstWaypoint, waypointDeltas, holdingCtrl);
}
Yaqinlashuv: Old School RuneScape bugungi kunda ham shu arxitekturaning modernlashtirilgan versiyasini ishlatadi. Opcode shifrlash, delta kodlash, 600 ms tik — hammasi saqlanib qolgan. Bu — arxitektura uzluksizligining ko'rinishi.
RuneScape 2004 — bu "qanday qilib" degan savolga javob bermay, "nima uchun shunday" degan savolga javob beruvchi misol. Har bir bayt uchun kurashish, protokol darajasida xavfsizlik (opcode shifrlash), mijozga yukni o'tkazish, server tikini muvofiqlashtirish — bularning har biri bugungi dasturlashda ham actual. Agar siz mikroxizmatlar, real-time tizimlar yoki past tarmoq kanallari (LoRa, NB-IoT, satellite) ustida ishlaysangiz, 2004-yildagi Jagex muhandislaridan o'rganish ko'p narsa bor.
if (opcode == ClientToServerOpcodes.USE_ITEM_ON_ITEM) {
int sourceItemId = player.inboundStream.takeShort();
int sourceInterfaceId = player.inboundStream.takeShort();
int sourceInterfaceSlot = player.inboundStream.takeShort();
int targetItemId = player.inboundStream.takeShort();
int targetInterfaceId = player.inboundStream.takeShort();
int targetInterfaceSlot = player.inboundStream.takeShort();
player.processUseItemOnItem(/* ... */);
}
Keyingi safar "lag" deb la'natlab yuborganingizda, esingizga tushsin: 20 yil avval 5 KB/s da 3D dunyo, 2000 o'yinchi va real-time janglar ishlatdi. Ular buni bayt bayt hisoblab, har birini qadrlab qilganlari uchun amalga oshirib bo'ldilar.
Asl manba: jkm.dev