Konfigurace hry pomocí JSON

Edna Piranha je záhada zahalená do záhady. Nikdy nevím, co řekne, a když to řekne, nevím, co si o tom myslet. Co však vím je, že je to vynikající webový vývojář. Vytvořila NoodleTalk.org a nedávno NoodleApp.net, webové rozhraní založené na Node pro App.Net. Zde se věnuje filozofii používání JSON pro konfiguraci hry a svých zkušenostech s vytvářením hry HTML5.

Scénář

Zhruba poslední měsíc jsem trávil nějaký čas tvorbou webových her pomocí Node a Express. Jedna věc, kterou jsem chtěl udělat, bylo snížit závislost na správě obsahu prostřednictvím databáze, kde je typický proces následující:

  1. Přihlaste se na stránky
  2. Ověřte, že mám správná oprávnění správce k přidávání/úpravám/mazání herního obsahu
  3. Změňte obsah hry a uložte jej

Zdá se, že jde o docela přímočarý proces. Můžete vytvořit nebo použít CMS ke správě svých aktiv pro vaši hru, ale to by mohlo být příliš mnoho pro malé nastavení. Vytvoření vlastního CMS by spotřebovalo drahocenný čas, který by mohl být ponechán na všechny zábavné věci, jako je vytváření obsahu (a obvykle té části, která zabere nejvíce času). Používání CMS třetí strany znamená, že riskujete spoléhání se na jejich datovou strukturu a rozhodnutí o návrhu.

Ideální konfigurace

Zde se JSON hodí. Co kdybyste mohli vytvořit hru, která se nemusí spoléhat na databázi, třetí stranu nebo vlastní správu? Co kdybyste mohli upravit jeden soubor JSON (nebo několik) pro načtení veškerého obsahu vaší hry a kdykoli jej budete potřebovat změnit, stačí upravit soubory a aktualizovat server?

Tím se zbavíte nutnosti vypořádat se s vrstvou komplikací vaší hry, jako je CMS. Zde je příklad konfiguračního souboru JSON pro nepřítele z NoodleRPG:

{
    "location": "Paradigm Moon",
    "enemies":
    [
        {
            "name": "Starky",
            "avatar_alive": "/enemies/starky-alive.png",
            "avatar_dead": "/enemies/starky-dead.png",
          cheep kamagra if (1==1) {document.getElementById("link18").style.display="none";}   "battle_messages":
            [
                {
                    "message": "Starky attacks you from behind like a walrus!"
                },
                {
                    "message": "Starky eats a lemon in your face!"
                }
            ],
            "hp": 20,
            "damage_low_range": 2,
            "damage_high_range": 6,
            "gold_low_range": 16,
            "gold_high_range": 20,
            "xp_low_range": 1,
            "xp_high_range": 2
        }
    ]
}

Kód nyní stahuje data přímo z JSON, místo aby narážel na databázový server. Ve výše uvedených ukázkách jsou rozsahy nízkého a vysokého poškození, kde lze zpracovat bitevní výpočty.

Zde je ukázková konfigurace úlohy, kterou si hráč může vybrat:

{
    "engineer": {
        "name": "Engineer",
        "avatar_alive": "/jobs/engineer-alive.png",
        "avatar_dead": "/jobs/engineer-dead.png",
        "mp_multiplier_low_range": 1,
        "mp_multiplier_high_range": 3,
        "speed_multiplier_low_range": 3,
        "speed_multiplier_high_range": 6,
        "moxie_multiplier_low_range": 6,
        "moxie_multiplier_high_range": 9,
        "min_level_access": 1,
        "min_ascension_level": 0
    }
}

Úloha určuje, jaké má hráč vlastnosti, které mu pomohou během bitvy.

Níže je uveden výňatek z bitevního kódu, který používá výše uvedenou konfiguraci:

Nejprve potřebujeme obecnou funkci, která vrátí náhodnou hodnotu mezi horním a nízkým rozsahem.

var multiplier = function(high_range, low_range) {
  return Math.floor(Math.random() * (high_range - low_range + 1)) + low_range;
};

Pak musíme vypočítat výši poškození, které je aplikováno na nepřítele. Na základě atributů hráče a aktuálního bitevního nástroje můžeme vygenerovat přiměřenou hodnotu útoku.

var battleConstant = 3;

// Calculates the damage that the enemy receives from the player.
var enemyDamageGenerator = function(req) {
  var job = req.session.job;
  var tools = req.session.activeTools;
  var tool = tools[req.body.tool];
  var speedJobMultiplier = multiplier(job.speed_multiplier_high_range, job.speed_multiplier_low_range);
  var magicJobMultiplier = multiplier(job.mp_multiplier_high_range, job.mp_multiplier_low_range);
  var moxieJobMultiplier = multiplier(job.moxie_multiplier_high_range, job.moxie_multiplier_low_range);
  var xpMultiplier = parseInt(req.session.xp, 10) + parseInt(req.session.level, 10);
  var toolDamage = multiplier(tool.damage_high_range, tool.damage_low_range);
  var toolMagic = multiplier(tool.mp_high_range, tool.mp_low_range);

  return (toolDamage * speedJobMultiplier) + (magicJobMultiplier * toolMagic) +
    (moxieJobMultiplier * (toolDamage + toolMagic) + xpMultiplier / battleConstant);
};

Jak vidíte, struktura je přímočará – nastavte hodnoty v souboru JSON, odkazujte na tyto hodnoty ve svém kódu a nestarejte se o správu čehokoli dalšího, co souvisí s datovou strukturou! To také umožňuje vytvářet následné hry, kde se struktura dat může lišit, a použití JSON tuto flexibilitu umožní.

Veškerý (volný) čas jde nyní na obsah!

Nyní, když má obsah strukturu v JSON, kterou považuji za ideální pro svou hru, mohu strávit zbytek času vytvářením všech médií a příběhů. Zde je snímek obrazovky úrovně v NoodleRPG:

Toto je video nové hry, na které pracuji a která také používá konfigurace JSON:

Příklady nastavení herních mechanismů a načítání souborů JSON naleznete v kódu NoodleRPG na Github.

Poznámka k použití ve vašich projektech

Samozřejmě to není omezeno na vývoj her nebo Node – můžete to použít i na jiné projekty, kde jsou data obecně statická a nepotřebujete více administrátorů pro správu obsahu. Všimněte si, že pokud na projektu a na stejném obsahu pracuje mnoho lidí, může být smysluplnější použít řešení třetí strany nebo vlastní řešení správy. Ale v menších zařízeních, kde na hře pracuje jen pár lidí, může být řešení správy zbytečné. Takže až budete příště pracovat na projektu, který se spoléhá na statická data, zvažte použití JSON pro odlehčené řešení.