This is an old revision of the document!


Laboratorul 06. Generare de NPCs, Items și Simulare de Lume

Generarea personajelor și a obiectelor este una dintre cele mai utilizate tehnici în jocurile moderne, de la RPG-uri care generează milioane de iteme unice până la simulări emergente, unde NPC-urile duc “vieți” organice bazate pe reguli simple.

Generarea procedurală de NPCs

Un NPC este definit printr-o combinație de atribute statice (nume, clasă, aspect etc.) și atribute dinamice (viață, damage, personalitate). Cheia unui sistem bun nu este generarea de atribute pur aleatorie, ci generare aleatorie controlată (valori generate în intervale cu sens, combinate prin reguli care produc personaje coerente).

Clase și distribuție ponderată

În general, clasele de NPC nu sunt echiprobabile (de exemplu, războinicii sunt mai comuni decât magicienii legendari). Distribuția ponderată permite controlul frecvenței fiecărei clase.

Atribute derivate din clasă

Fiecare clasă definește intervale de bază pentru atributele NPC-urilor. Randomizarea se aplică în interiorul acestor intervale, nu global — un Mage va fi mereu mai slab fizic decât un Warrior, indiferent de roll. Exemplu:

Class HP Damage Armor
Warrior 80–120 15–25 10–20
Mage 40–65 30–50 2–5
Rogue 55–80 20–35 5–10
Archer 60–85 18–30 4–8
Paladin 90–130 12–20 15–25

Personalitate și modificatori comportamentali

Trăsătura de personalitate nu este doar cosmetică; aceasta modifică valorile de bază și va influența comportamentul în simulare. Fiecare trăsătură aplică un multiplicator pe atribute. Exemplu:

Trăsătură Efect pe atribute Comportament în simulare
Aggressive Damage ×1.3, HP ×0.9 Atacă primul, preferă duelul direct
Coward HP ×0.8, Armor ×0.7 Fuge când HP < 40%
Brave HP ×1.1, Damage ×1.1 Nu fuge niciodată, protejează aliații
Cunning Damage ×1.2, Armor ×1.1 Atacă NPC-ul cu HP cel mai scăzut
Peaceful HP ×1.15, Damage ×0.7 Nu inițiază atacuri, ripostează doar

Generarea procedurală de items

Sistemul de raritate

Raritatea controlează atât puterea unui item (stat budget), cât și frecvența cu care apare. Sistemul clasic cu culori comunică vizual calitatea instantaneu. Exemplu:

Raritate Culoare Probabilitate Stat multiplier Abilitate specială
Common Alb 55% 1.0× Nu
Uncommon Verde 25% 1.3× Nu
Rare Albastru 12% 1.7× Nu
Epic Mov 6% 2.2× Da
Legendary Portocaliu 2% 3.0× Da (2 abilități)

Stat budget & balancing

Itemele de raritate mai mare nu au toate statisticile mai mari față de cele comune. În schimb, fiecare item primește un buget de putere total (calculat din raritate), iar acel buget este distribuit aleatoriu între atribute. Astfel, două iteme de aceeași raritate pot fi foarte diferite (de exemplu, unul poate fi axat pe damage, altul pe durabilitate).

Abilitățile speciale se adaugă peste budget pentru Epic și Legendary. A doua abilitate a unui Legendary este aleasă explicit diferit de prima: dacă prima e Poison, a doua e aleasă din restul listei (Lifesteal, FireDamage, IceSlow, Thunder).

GenerateItem(type, rarity):
    budget   = baseBudget * rarityMultiplier[rarity]
    damage   = Random(0.4, 0.7) * budget      // 40-70% din budget pe damage
    durabil  = budget - damage                // restul pe durabilitate
    
    if rarity >= Epic:
        ability = SelectRandom(specialAbilities)
    if rarity == Legendary:
        ability2 = SelectRandom(specialAbilities - {ability})

De ce se distribuie aleatoriu și nu este lăsat jucătorul să aleagă? Pentru că variabilitatea creează motivație de a continua să caute loot. Un Legendary cu distribuție nefavorabilă îl face pe player să mai joace o dată în speranța unui roll mai bun.

Abilități speciale

Abilitățile speciale sunt definite ca modificatori cu parametri proprii generați în intervale. Exemplu:

Abilitate Efect Parametru generat
Poison Damage over time 3–8 damage/tick, 3–5 tick-uri
Lifesteal Regenerare HP la hit 15–30% din damage ca HP
Fire Damage Bonus damage + burn +5–15 damage, 2 tick-uri burn
Ice Slow Reduce viteza țintei 20–50% slow, 2–4 secunde
Thunder Șansă de stun 15–35% șansă, 1 secundă stun

Simularea unei Lumi

Simularea unei lumi este un exemplu de emergent storytelling. Pe baza unor reguli simple, se crează comportamente complexe și povești unice. Fiecare zi (tick) de simulare aplică regulile tuturor NPC-urilor în ordine, iar rezultatele se acumulează într-un jurnal narativ.

La nivelul acestui laborator, simularea poate fi împărțită în patru componente independente:

  • World Simulator: Componenta centrală a aplicației, gestionează tick-urile, crează NPC și îi poziționează în lume la începutul simulării, gestionează sfârșitul simulării
  • NPC Agent: Conține toate informațiile despre fiecare NPC; gestionează logica de decizie pentru fiecare NPC (la fiecare tick primește contextul (vecini, relații, locație) și alege o acțiune)
  • Sistemul de Relații: Stochează relațiile dintre toate perechile de NPC-uri
  • Jurnal Narativ: Toate acțiunile alese de NPC-uri sunt transformate în text prin intermediul unor template-uri

Logica de decizie per tick

La fiecare tick, fiecare NPC parcurge în ordine un arbore de decizie cu un anumit număr de priorități. Prima condiție adevărată câștigă, restul nemaifiind evaluate.

Prioritate Nume Acțiune Condiție Descriere Acțiune
1 Supraviețuire Personalitate Coward și HP < 30% Fuge la o locație aleatoare
2 Atac Personalitate Aggressive sau Cunning și există dușmani în locație Atacă: Cunning alege ținta cu HP minim, Aggressive alege aleatoriu
3 Trade Există aliați în locație și NPC-ul are iteme 25% șansă de a da un item unui aliat
4 Explorare 20% șansă de a se muta în altă locație
5 Idle Nicio acțiune; relațiile cresc pasiv prin co-prezență

Ordinea priorităților determină caracterul lumii simulate. Dacă Trade se verifică înaintea Attack, NPC-urile vor prefera alianțele în fața conflictului și simularea va produce povești cu mai puțini morți și mai multă acumulare de relații pozitive.

Sistemul de relații

Relațiile sunt stocate ca valori float într-un anumit interval predefinit (de exemplu, intervalul [−100, +100]), unde valoarea minimă înseamnă dușmănie absolută și valoarea maximă alianță puternică. Toate relațiile dintre NPC-uri pornesc de la 0 și se modifică prin interacțiuni:

Eveniment Modificare relație
Atac reușit −20 pentru cel atacat față de atacant
Schimb de iteme +10 pentru ambii participanți
Ucidere (martori prezenți) −30 față de ucigaș pentru toți martorii
Fără conflict sau orice altă interacține +2 per tick (familiaritate pasivă)

Relațiile sunt asimetrice. Când primul NPC modifică relația față de al doilea NPC cu un delta, relația inversă se modifică cu doar un anumit procent din acel delta.

Tasks

  1. Creați un NPC generator simplist în care:
    • Un NPC este definit printr-o combinație aleatoare de nume, clasă, viață, damage.
    • Fiecare NPC va avea și o trasătură aleatoare de personalitate, care îi va afecta comportamentul.
    • Pe baza clasei asociate, fiecare NPC va avea un portret afișat pe ecran.
    • Se generează un nou NPC și se afișează pe ecran la apăsarea unui buton.
  2. Creați un generator de armură și arme în care:
    • Un item este definit printr-un tip, o raritate, damage și durabilitate.
    • Item-ele mai rare au și câte o abilitate specială precum poison, lifesteal, fire damage, ice slow.
    • Se generează un nou item și se afișează pe ecran la apăsarea unui buton.
    • În funcție de raritatea item-ului, scrisul de pe ecran va avea altă culoare.
  3. Bonus 1. Creați un meniu prin care să puteți scrola prin toate personajele și obiectele generate. Rezultatele generări se vor salva pentru a fi accesibile și la rulări ulterioare ale aplicației. Jucătorul va putea redenumi NPCs și item-urile generate.
  4. Bonus 2. Pentru fiecare item afișați “rarity stars” în dreptul numelui. Adăugați un efect de animație pentru cel mai rar tip de item.
gp/laboratoare/06.1774701915.txt.gz · Last modified: 2026/03/28 14:45 by maria_anca.balutoiu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0