NUGANUGA Web SDK
A játékod egy homokozóba zárt iframe-ben fut itt: https://play.nuganuga.com. Az SDK az egyetlen csatorna a platform felé — hitelesítést, ranglistát, megosztást, hirdetést vagy analitikát soha nem kell magadnak megírnod.
1. Töltsd be az SDK-t
Mindig pontosan erről az abszolút útvonalról. A platform szolgálja ki és verziózza.
<script src="/sdk/nuga-sdk.js"></script>
<script src="./game.js"></script>2. A négy hívás
const ctx = await Nuga.ready(); // várj a platformra
await Nuga.game.start(); // amikor a játékos ténylegesen elindít egy kört
await Nuga.score.submit({ score }); // pontosan egy numerikus pontszám körönként
await Nuga.game.finish(); // a platform rajzolja az eredményképernyőtNe rajzolj saját eredményképernyőt, újrajátszás- vagy megosztásgombot, sem ranglistát — a platform ezeket a finish() után minden játéknál ugyanúgy jeleníti meg.
3. Minden más
Nuga.game.getContext();
Nuga.player.get();
Nuga.challenge.get();
Nuga.storage.get(key);
Nuga.storage.set(key, value);
Nuga.audio.setMuted(true);
Nuga.locale.get(); // 'en' | 'ko' | ...
Nuga.event.track('level_up', { level: 3 });
Nuga.on('pause', () => pauseLoop());4. A leíró
nuga.json a csomagod gyökerében:
{
"schemaVersion": 1,
"name": "Reaction Hunter",
"slug": "reaction-hunter",
"description": "Click 10 targets as fast as possible.",
"rule": "Tap every target as fast as you can.",
"category": "REACTION",
"orientation": "PORTRAIT",
"duration": { "min": 5, "max": 30 },
"input": ["POINTER", "TOUCH"],
"ranking": { "type": "LOW_TIME", "unit": "ms" },
"entry": "index.html",
"locales": {
"ko": { "name": "리액션 헌터", "description": "10개의 타겟을 빠르게 클릭하세요." }
}
}Ranglistatípusok: HIGH_SCORE, LOW_SCORE, LOW_TIME, HIGH_TIME, CUSTOM. Kategóriák: REACTION, TIMING, ACCURACY, MEMORY, PUZZLE, LUCK, ARCADE.
5. Homokozószabályok
A statikus ellenőrzés elutasít minden csomagot, amely bármelyiket megszegi, még mielőtt játékoshoz jutna:
- Semmilyen külső URL — se CDN, se webes betűtípus, se távoli kép. Mindent csomagolj be.
- Nincs
eval,new Function,document.writevagydocument.cookie. - Nincs saját hálózat: az abszolút URL-re irányuló
fetch, azXMLHttpRequest, aWebSocketés a service worker a CSP és az ellenőrzés miatt is tiltott. - Nincs legfelső szintű navigáció és nincs felugró ablak.
- A csomag 5 MB alatt; a mikrojátékok maradjanak 1 MB alatt.
- Legalább egy
Nuga.score.submit()hívás — az a játék, amely nem ad pontszámot, nem kerülhet ranglistára. - A platform héja rögzített: az index.html, a héj stíluslapja és a game.js hámja változatlan kell maradjon. Csak a run() törzse és a #field stílusai a tiéd.
6. A pontszámokat ellenőrizzük
Minden kör kap egy kiszolgálóoldali munkamenetet. A játékod soha nem látja a munkamenet-tokent — a platform burka őrzi, és helyetted küldi be —, a kiszolgáló pedig a valós időtartammal és a leíróban megadott határokkal veti össze a pontszámot, mielőtt ranglistára kerülne.
Ennél jobbat is tehetsz. A véletlent a kiszolgáló által kiadott magból vedd, és rögzítsd, mi történt valójában: így a kiszolgáló az eseményeidből számolja újra a kört ahelyett, hogy elhinné a számot. Az a pontszám, amit a felvételed nem támaszt alá, azonnal elutasításra kerül.
const rng = Nuga.random(); // a kiszolgáló magjából — reprodukálható, a Math.random() nem az
const target = rng.int(0, 8);
Nuga.replay.record('hit', 172); // egy pontszám szempontjából lényeges esemény, körönként legfeljebb 400A bekapcsoláshoz add meg a mechanikát itt: nuga.json. Enélkül a játékod továbbra is ranglistára kerül, csak időtartam- és határellenőrzésekkel.
"verification": { "kind": "REPLAY_V1", "mechanic": "REACTION",
"params": { "rounds": 5 } }7. Add ki
Tömörítsd a csomag gyökerét (nem a mappát), és töltsd fel a készítői konzolon. A statikus ellenőrzés, a build, valamint a runtime-, reszponzivitás-, játékmenet- és biztonsági tesztek automatikusan lefutnak; a közzététel akkor nyílik meg, ha mind sikeres.