Differences

This shows you the differences between two versions of the page.

Link to this comparison view

gp:laboratoare:06 [2026/03/28 15:08]
maria_anca.balutoiu [Simularea unei Lumi]
gp:laboratoare:06 [2026/04/08 09:07] (current)
maria_anca.balutoiu [Generarea procedurală de NPCs]
Line 11: Line 11:
  
 === Atribute derivate din clasă === === 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:+Fiecare clasă definește **intervale de bază** pentru atributele NPC-urilor. Randomizarea se aplică în interiorul acestor intervale, nu globalun Mage va fi mereu mai slab fizic decât un Warrior, indiferent de roll. Exemplu:
  
 ^ Class ^ HP ^ Damage ^ Armor ^ ^ Class ^ HP ^ Damage ^ Armor ^
Line 132: Line 132:
   - **Generatorul de NPC-uri:** Fiecare NPC se generează prin selecția ponderată a clasei și aplicarea multiplicatorilor de personalitate. Pentru început, se generează numele din două liste independente,​ apoi selectează clasa, apoi se selectează personalitatea uniform aleatoriu, iar în final se generează atributele de bază din intervalele clasei și se înmulțesc cu multiplicatorii de personalitate.   - **Generatorul de NPC-uri:** Fiecare NPC se generează prin selecția ponderată a clasei și aplicarea multiplicatorilor de personalitate. Pentru început, se generează numele din două liste independente,​ apoi selectează clasa, apoi se selectează personalitatea uniform aleatoriu, iar în final se generează atributele de bază din intervalele clasei și se înmulțesc cu multiplicatorii de personalitate.
   - **ItemGenerator:​** Pentru calculul rarității se urmează același model de selecție ponderată. După ce raritatea e determinată,​ se calculează bugetul total (''​BASE_BUDGET × rarityMultiplier''​),​ se generează un număr aleator dintr-un interval predefinit (de exemplu, [0.4, 0.7]) pentru damage, iar restul bugetului merge la durabilitate. Numele itemului se construiește procedural dintr-un prefix aleatoriu și un sufix dependent de tip. Abilitățile speciale se adaugă pentru Epic (una) și Legendary (două distincte).   - **ItemGenerator:​** Pentru calculul rarității se urmează același model de selecție ponderată. După ce raritatea e determinată,​ se calculează bugetul total (''​BASE_BUDGET × rarityMultiplier''​),​ se generează un număr aleator dintr-un interval predefinit (de exemplu, [0.4, 0.7]) pentru damage, iar restul bugetului merge la durabilitate. Numele itemului se construiește procedural dintr-un prefix aleatoriu și un sufix dependent de tip. Abilitățile speciale se adaugă pentru Epic (una) și Legendary (două distincte).
-<​hidden>​ +  - **Sistemul de Relații:** Relațiile sunt stocate ​ca valori float într-un ​anumit interval predefinit ​(de exempluintervalul [−100+100]). Relația directă se actualizează cu delta, iar relația inversă cu ''​delta × 0.7'',​ ambele cu clamp la intervalul predefinit. 
-=== Pasul 4RelationshipMatrix === +  - **NPC Agent:** Se implementează arborele de decizie din tabelul ​de relații, ținând cont și de lista vecinilor, modificatorul locației curente, în ordinea exactă a priorităților. ​Se calculează damage-ul ​primit ​și se verifică dacă NPC-ul a murit. 
-  +  - **Jurnal Narativ:** Se selectează aleatoriu ​din template-urile existente ​pentru ​a se afișa acțiunile NPC-urilor
-''​RelationshipMatrix''​ nu este ''​MonoBehaviour''​ — este o clasă C# simplă instanțiată de ''​WorldSimulator''​. Intern, relațiile sunt stocate într-un ​''​Dictionary<​(stringstring)float>''​ unde cheia este perechea ordonată de nume. Metoda ''​Initialize()''​ populează toate perechile posibile cu valoarea 0Metoda ''​Modify()''​ actualizează relația directă cu delta și relația inversă cu ''​delta × 0.7'',​ ambele cu clamp la [−100, 100]Metodele ''​GetEnemies()''​ și ''​GetAllies()''​ filtrează lista de NPC-uri dintr-o locație după pragul ​de relație. +  - **Main World Simulator:** Sistemul ​așteaptă ''​tickInterval''​ secunde între tick-uri. La fiecare ''​zi'' ​nouăse iterează ​printre ​toți agenții vii, aplică ​damge-ul agentului, ​aplică decizia ​luată de agent. Simularea se termină când rămâne cel mult un NPC în viață sau se epuizează zilele maxime.
-  +
-=== Pasul 5: NPCAgent === +
-  +
-''​NPCAgent''​ împachetează un ''​NPCData'' ​și expune două metode publice. ''​Decide()''​ primește contextul complet (lista vecinilor, matricea de relații, ID-urile locațiilor, modificatorul locației curente) și returnează o structură ''​Decision''​ cu tipul acțiunii, ținta opțională și locația destinație pentru Flee/Move. Logica implementează arborele de decizie din tabel, în ordinea exactă a priorităților. ​''​TakeDamage()'' ​calculează damage-ul ​real după reducerea de armor (''​Mathf.Max(1f,​ rawDamage - armor × 0.5f)''​) ​și returnează ''​true'' ​dacă NPC-ul a murit. +
-  +
-=== Pasul 6: NarrativeJournal === +
-  +
-''​NarrativeJournal''​ este o clasă C# simplă cu câte un array de template-uri per tip de acțiune. Fiecare metodă ''​Generate*Entry()'' ​selectează aleatoriu ​un template ​și aplică ''​string.Replace()''​ în lanț pentru ​fiecare variabilă. Metoda ''​GenerateSummary()''​ construiește sumarul final al simulării: câte zile durat, cine a supraviețuit, lista celor căzuți și inventarul supraviețuitorului. Intrările de tip ''​Idle''​ se înregistrează condiționat (''​Random.value < 0.2f''​) pentru a nu polua jurnalul+
-  +
-=== Pasul 7WorldSimulator === +
-  +
-''​WorldSimulator''​ este un ''​MonoBehaviour''​ care pornește o coroutine ''​SimulationLoop()''​ ce așteaptă ''​tickInterval''​ secunde între tick-uri. La fiecare ''​AdvanceDay()'',​ iterează ​prin toți agenții vii, aplică ​modificatorul locației pe damage-ul agentului ​(temporarrestaurat după tick), cere decizia ​prin ''​agent.Decide()'',​ execută acțiunea prin ''​ApplyDecision()''​ și aplică bonusul ​de co-prezență pentru toți din aceeași locație. ''​ApplyDecision()''​ gestionează toate cele 5 tipuri de acțiune, inclusiv notificarea martorilor la ucidere. Simularea se termină când rămâne cel mult un NPC în viață sau se epuizează zilele maxime. +
-  +
-Comunicarea cu UI-ul se face exclusiv prin evenimente C#: ''​OnJournalEntry'',​ ''​OnDayAdvanced'',​ ''​OnNPCDied''​ și ''​OnSimulationEnd''​ — astfel simularea nu știe nimic despre UI și poate fi testată independent. +
-  +
-<note tip>​Conectați evenimentele în ''​Awake()''​ din ''​SimulationPanel'',​ nu în ''​Start()'',​ pentru a garanta că nu pierdeți niciun eveniment dacă simularea pornește în același frame.</​note>​ +
-</​hidden>​+
 ==== Tasks ==== ==== Tasks ====
   - Creați un NPC generator simplist în care:    - Creați un NPC generator simplist în care: 
     * Un NPC este definit printr-o combinație aleatoare de nume, clasă, viață, damage.     * 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.+    ​* Clasa este selectată prin distribuție ponderată. 
 +    ​* Fiecare NPC va avea și o trasătură aleatoare de personalitate,​ care modifică numeric atributele de bază.
     * Pe baza clasei asociate, fiecare NPC va avea un portret afișat pe ecran.     * 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.     * Se generează un nou NPC și se afișează pe ecran la apăsarea unui buton.
   - Creați un generator de armură și arme în care:   - Creați un generator de armură și arme în care:
-    * Un item este definit printr-un tip, o raritate, damage și durabilitate. +    * Un item este definit printr-un tip, o raritate, damage și durabilitate ​generate din **stat budget**
-    * Item-ele mai rare au și câte o abilitate specială precum ​poison, lifesteal, fire damage, ice slow.+    * Itemele Epic și Legendary au abilități speciale cu parametri proprii generați în intervale (exemple abilități: ​poison, lifesteal, fire damage, ice slow).
     * Se generează un nou item și se afișează pe ecran la apăsarea unui buton.     * Se generează un nou item și se afișează pe ecran la apăsarea unui buton.
 +    * Numele itemului se generează procedural (prefix + tip).
     * În funcție de raritatea item-ului, scrisul de pe ecran va avea altă culoare.     * În funcție de raritatea item-ului, scrisul de pe ecran va avea altă culoare.
 +  - Implementați simularea unei lumi procedurale:​
 +    * Generați 4–6 NPC-uri și distribuiți-le aleatoriu în 5 locații predefinite.
 +    * La apăsarea butonului ''​Advance Day'',​ fiecare NPC execută o acțiune bazată pe personalitate,​ HP curent și relațiile cu vecinii din aceeași locație.
 +    * Sistemul de relații [−100, +100] se actualizează după fiecare interacțiune și influențează deciziile viitoare.
 +    * Fiecare acțiune generează o linie de text narativ din template-uri cu minim 3 variante per tip.
 +    * Simularea se oprește când rămâne un singur NPC în viață sau după 10 zile și afișează un sumar procedural.
   - **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.   - **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.
   - **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.   - **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.
 +  - **Bonus 3.** Adăugați o hartă vizuală simplă (grid sau icoane) care arată locația curentă a fiecărui NPC și se actualizează la fiecare tick.
gp/laboratoare/06.1774703325.txt.gz · Last modified: 2026/03/28 15:08 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