NUGANUGAn web-SDK
Pelisi pyörii eristetyssä iframessa osoitteessa https://play.nuganuga.com. SDK on ainoa kanava alustalle — et koskaan toteuta itse tunnistautumista, sijoituksia, jakamista, mainoksia tai analytiikkaa.
1. Lataa SDK
Aina täsmälleen tästä absoluuttisesta polusta. Alusta jakelee ja versioi sen.
<script src="/sdk/nuga-sdk.js"></script>
<script src="./game.js"></script>2. Neljä kutsua
const ctx = await Nuga.ready(); // odota alustaa
await Nuga.game.start(); // kun pelaaja oikeasti aloittaa kierroksen
await Nuga.score.submit({ score }); // täsmälleen yksi numeerinen tulos kierrosta kohden
await Nuga.game.finish(); // alusta piirtää tulosnäkymänÄlä piirrä omaa tulosnäkymää, uudelleenyritys- tai jakopainiketta tai tulostaulua — alusta piirtää ne finish()-kutsun jälkeen samalla tavalla joka pelille.
3. Kaikki muu
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. Manifesti
nuga.json pakettisi juuressa:
{
"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개의 타겟을 빠르게 클릭하세요." }
}
}Sijoitustyypit: HIGH_SCORE, LOW_SCORE, LOW_TIME, HIGH_TIME, CUSTOM. Kategoriat: REACTION, TIMING, ACCURACY, MEMORY, PUZZLE, LUCK, ARCADE.
5. Hiekkalaatikon säännöt
Staattinen tarkistus hylkää paketin, joka rikkoo yhtäkin näistä, ennen kuin se päätyy pelaajalle:
- Ei ulkoisia URL-osoitteita — ei CDN:ää, verkkofonttia tai etäkuvaa. Paketoi kaikki mukaan.
- Ei
eval,new Function,document.writetaidocument.cookie. - Ei omaa verkkoliikennettä:
fetchabsoluuttiseen osoitteeseen,XMLHttpRequest,WebSocketja service workerit estetään sekä CSP:llä että tarkistuksessa. - Ei ylimmän tason navigointia eikä ponnahdusikkunoita.
- Paketti alle 5 Mt; mikropelien kannattaa pysyä alle 1 Mt:ssa.
- Vähintään yksi
Nuga.score.submit()-kutsu — peli, joka ei tuota tulosta, ei voi sijoittua. - Alustan kuori on kiinteä: index.html, kuoren tyylitiedosto ja game.js:n valjaat on jätettävä ennalleen. Vain run()-runko ja #field-tyylit ovat sinun.
6. Tulokset varmennetaan
Jokainen kierros saa palvelinpuolen istunnon. Pelisi ei näe istuntotunnistetta — alustan kuori pitää sitä ja lähettää puolestasi — ja palvelin vertaa tulosta kierroksen todelliseen kestoon ja manifestissa ilmoitettuihin rajoihin ennen kuin se päätyy tulostaululle.
Voit tehdä paremmin. Ota satunnaisuus palvelimen antamasta siemenestä ja tallenna, mitä oikeasti tapahtui: silloin palvelin laskee kierroksen uudelleen tapahtumistasi sen sijaan että uskoisi lukua. Tulos, jota tallenne ei tue, hylätään suoraan.
const rng = Nuga.random(); // palvelimen siementämä — toistettava, toisin kuin Math.random()
const target = rng.int(0, 8);
Nuga.replay.record('hit', 172); // yksi tulokseen vaikuttava tapahtuma, enintään 400 kierrosta kohdenIlmoita mekaniikka tiedostossa nuga.json kytkeäksesi tämän päälle. Ilman sitä pelisi sijoittuu silti, mutta vain keston ja rajojen tarkistuksilla.
"verification": { "kind": "REPLAY_V1", "mechanic": "REACTION",
"params": { "rounds": 5 } }7. Julkaise
Pakkaa paketin juuri (ei kansiota) ja lataa se tekijäkonsolissa. Staattinen tarkistus, käännös sekä runtime-, responsiivisuus-, pelattavuus- ja tietoturvatestit ajetaan automaattisesti; julkaisu avautuu, kun ne menevät läpi.