radekmie / h3mapgen

An attempt to build a comprehensive map generator for Heroes of Might and Magic III
6 stars 2 forks source link

Opracować, zakodować i udokumentować pełną fazę MultiLML #41

Open acatai opened 6 years ago

acatai commented 6 years ago

Po skończeniu #17, można będzie na nowo wrócić do MultiLML'a. Dotychczas było zrobione na szybko i o ile pamiętam, nie wszystkie rzeczy działają jeszcze tak jak ostatecznie byśmy tego chcieli.

Oczywiście komponent powinien być również porządnie udokumentowany, podobnie jak bazowy LML.

Edit: Notka żeby pamiętać skoro wprowadzamy teamy: symetryczność Multi'LMLa powinna być tak naprawdę wyznaczona przez obroty względem teamów nie graczy.

acatai commented 6 years ago

Przemyślenie. Goal node musi (jeśli istnieje) być jedno na cały graf. Skoro tak, to proponuję traktować go w fazie mergowania LML'a specjalnie i zamiast kombinować z dawaniem odpowiedniej liczby outerów czy coś - po prostu generując multigraf pomijać wszelkie krawędzie wychodzące z GOAL, tzn. nie przypisywać im par. Natomiast w fazie merge po prostu zostawić jeden.

Albo może jeszcze prościej - nie dawać goal outerów? Z drugiej strony jeśli powiemy że daną zone mergujemy zawsze na siłę to outery nic nie szkodzą - po prostu po mergu wyjść z takiej zony może być więcej niż początkowo zakładano...

Podobnie kwestia ma się z teleportami. Uważam że jeśli istnieje teleport zone o id 6, to wszystkei takie teleporty z multi powinny się mergować do jednego (a teleporty z id np. 8 do jednego osobnego). I tu mamy podobną kwestię z dodatkowymi outerami - bo ponieważ mergujemy na siłę outery zawsze będę implicite istniały - bo każda single zona ma krawędź do swojej instancji teleportu/goala. Ale dodatkowe outery chyba nie przeszkadzają?

mention: #57

radekmie commented 6 years ago

[...] po prostu generując multigraf pomijać wszelkie krawędzie wychodzące z GOAL, tzn. nie przypisywać im par. Natomiast w fazie merge po prostu zostawić jeden.

Brzmi dobrze.

Albo może jeszcze prościej - nie dawać goal outerów? [...]

Raczej nie - w ten sposób GOAL zawsze (?) będzie liściem.

[...] Uważam że jeśli istnieje teleport zone o id 6, to wszystkei takie teleporty z multi powinny się mergować do jednego (a teleporty z id np. 8 do jednego osobnego). [...]

Nie, dlaczego? Mamy wiele jego instancji, które są odległe od siebie o 0 (lub jakąś stałą).

acatai commented 6 years ago

Raczej nie - w ten sposób GOAL zawsze (?) będzie liściem.

W single niekoniecznie bo może mieć inne krawędzie wewnętrzne do wierzchołków grafu LML. W multi to już w ogóle nie - bo wręcz będzie otoczony ze wszystkich stron przez strefy single każdego z graczy.

Nie, dlaczego? Mamy wiele jego instancji, które są odległe od siebie o 0 (lub jakąś stałą).

Po pierwsze nie rozumiem co to znaczy wiele instancji odległych od siebie ;]. Po drugie mamy tylko 4 teleporty - i wstawiając je jako features do grafu z założeniem full merge mam nad tym panowanie. Jeśli część by się zmergowała a część nie, na 8 graczy dwa teleporty mogą się nagle rozplenić do np. 6. Poza tym to daje jasną semantykę teleportów ;].

radekmie commented 6 years ago

Po pierwsze nie rozumiem co to znaczy wiele instancji odległych od siebie ;].

Chodzi o to, że będziemy mieli N (N - ilość graczy) zon z teleportem i są one odległe od siebie o jakąś stałą. Nie możemy ich mergeować, bo wtedy będzie tylko jedna, gdzie mamy postawić N teleportów. Chyba, że się nie rozumiemy.

acatai commented 6 years ago

Już łapię gdzie mamy nieporozumienie ^^. One nie są odległe. One są wirtualne. Nie ma czegoś takiego jak 'zona z teleportem' jest 'zona będąca teleportem' (taka multikrawędź). Jeśli jej wszystkie instancje zmergujemy, to każda inna zona która będzie miała krawędź do teleportu będzie miała postawiony teleport.

Wydawało mi się to najlepsze rozwiązanie, chyba że masz jakieś argumenty przeciwko?

radekmie commented 6 years ago

Więc będzie musiał być specjalny przypadek na to, że jeżeli zona ma krawędź do teleportu (nie taki feature), to ma go sobie postawić. Nie lepiej żeby zona "miała" a nie "była" teleportem? Wtedy wiemy od razu, co stoi w każdej zonie.

acatai commented 6 years ago

To jest tylko kwestia reprezentacji na pewnym etapie. To co mówisz ma sens i chwilkę o tym jeszcze porozmawiajmy.

Kwestia jest taka, że skoro teleport jest zoną a nie features, to umożliwiamy nie tylko łączenie pomiędzy graczami/instancjami, ale także w ramach jednej instancji - i dzieje się to na poziomie ewolucji gramatycznej. Tzn. może powstać teleport który łączy np. zony LOCAL, 5 o baseid 7 wszystkich graczy oraz zony BUFFER, 8 o baseid 16 które jakoś się tam zmergowały i ostatecznie są tylko dwie.

Takie coś jest (chyba) trochę cięższe do osiągnięcia jeśli teleport jest ficzerem, tzn. wtedy mamy tak: a) mówimy, że teleport łączy tylko 'w poprzek' tzn wszystkie zony o tym samym baseid. Wtedy jest banał - traktujemy jako feature na etapie inicjalizacji grafu, losujemy do jakiej klasy noda idzie każdy z teleportów i wsio. b) Jeśli miałby też łączyć zony o różnym baseid, to feature miałby value który jest po prostu id teleportu. Wtedy już na etapie inicjalizacji musielibyśmy powiedzieć teleport o danym id do jakich (klasa) i ilu zon idzie; gramatyka by je tylko przesuwała jeśli kilka zon miałoby tę samą klasę.

Wersja jako zona wydaje się ciekawsza z punktu widzenia działania programu bo trochę mniej przewidywalna, a równocześnie zakładamy że grafy będą się robiły z jakimś 'sensem'

Z drugiej strony trzeba wtedy obsługiwać zony w gramatyce, a jeśli to jest feature to przerzucamy go bezmyślnie (albo z jakimiś prostymi heurezami) jak każdy inny feature. Z kolei w tym przypadku inicjalizacja decyduje o większej liczbie rzeczy i to tak brzydko losowo na zasadzie: jak wypadnie więcej oczek niż 2 to teleport jest też w innej zonie - wylosuj liniowo w jakiej.

OK, bardziej szczegółowo rozwinąłem kwestię, ciekawi mnie Twoje zdanie (oraz każdego innego kto by się chciał wypowiedzieć), zwłaszcza, że właściwie jestem w trakcie pisania tych fragmentów ;].

radekmie commented 6 years ago

Tzn. może powstać teleport który łączy np. zony LOCAL, 5 o baseid 7 wszystkich graczy oraz zony BUFFER, 8 o baseid 16 które jakoś się tam zmergowały i ostatecznie są tylko dwie.

Tym bardziej optowałbym za teleportem jako zoną.

Jeśli miałby też łączyć zony o różnym baseid, to feature miałby value który jest po prostu id teleportu. Wtedy już na etapie inicjalizacji musielibyśmy powiedzieć teleport o danym id do jakich (klasa) i ilu zon idzie; gramatyka by je tylko przesuwała jeśli kilka zon miałoby tę samą klasę.

Można nawet pójść dalej i zrobić specjalne reguły w gramatyce dla teleportów.

Z kolei w tym przypadku inicjalizacja decyduje o większej liczbie rzeczy i to tak brzydko losowo na zasadzie: jak wypadnie więcej oczek niż 2 to teleport jest też w innej zonie - wylosuj liniowo w jakiej.

Nie jest to jedyne miejsce, gdzie te "2 oczka" będę decydować o jakości mapy.

acatai commented 6 years ago

Tym bardziej optowałbym za teleportem jako zoną.

No to się zdecyduj bo wcześniej optowałeś za ficzerem ;]

Można nawet pójść dalej i zrobić specjalne reguły w gramatyce dla teleportów.

No tak by było - dlatego piszę, że jako feature jest prościej.

Nie jest to jedyne miejsce, gdzie te "2 oczka" będę decydować o jakości mapy.

No wiem, dlatego zacząłem się właśnie skłaniać ku trzymaniu teleportu jako feature a nie zona.

radekmie commented 6 years ago

Eh, sam widzisz, jak rozdarty jestem. Feature wygląda przyjaźniej.

acatai commented 6 years ago

Wiem - skłaniam się teraz własnie ku feature ;]. Przyjaźniej to bardzo celne określenie. (Choć mniej interesująceo...)

PiotrPytlik commented 6 years ago

Hej, zgodnie z prośbą, wtrące swoje dwa grosze ;)

Z punktu widzenia zastosowania - wydaje mi sie ze jesli chcemy aby teleport wnosil ciekawe elementy do gry na poziomie LML/MLML, to powinien byc jako zona, bo jako zone, jasno jest okreslone (na poziomie LML) gdzie sie łączy z czym, bo jest global teleport jako feature - bardziej lokal teleport żeby tworzyc jakby polaczenie w ramach jednego gracza (ale jest to ciut zbedne i moim zdaniem zniknie w praniu, jesli bedziemy stosowali teleporty do naprawiania zlych polaczeń)

Z perspektywy rozwiazania - gigantycznym uproszczeniem i ulatwieniem bedzie jesli teleport taki potraktujemy jako zone, bo

  1. Nie trzeba obslugiwac polaczen typu teleport (mamy juz lokal / buffer i to troche zajmie zeby ładnie pracowalo)
  2. Wystarczy na koniec MLML (albo nawet pozniej) po prostu wpisac teleport do konkretnych stref i jest pieknie
acatai commented 6 years ago

Mam wrażenie że wszyscy którzy mówią o traktowaniu teleportu jako zone mają na myśli coś co ja opisałem jako traktowanie jako feature. Kurde to trzeba chyba narysować na tablicy ;], bo lepiej niż wcześniej chyba już nie wytłumaczę co miałem na myśli. (OK, spróbuję)

1) Teleport jako zona. -- istnieje zona typu teleport -- przez LML jest traktowana jak zwykła zona: ma krawędzie do innych, może nawet mieć outery, jest to w pełni obsługiwane przez gramatykę -- przy MultiLML wszystkie instancje zony z teleportem łączymy na siłę w jedną (jak goal) -- wtedy zona ta działa jak multikrawędź łącząc odpowiadające sobie strefy różnych graczy z być może różnymi strefami tych samych graczy -- każda zona która miała krawędź do teleportu ma wstawiany teleport

2) Teleport jako feature. -- istnieje feature teleport, jak każdy feature ma przypisaną klasą zony w której ma wylądować -- w procesie initLML losujemy dla teleportu w jakich i ilu zonach ma być -- z punktu widzenie LML jest to zwykły feature który sobie przerzuca zachowując tylko klasę -- z punktu widzenia MultiLML zony w ogóle nie istnieją, zony w których on jest łączą się i mergują jak chcą -- każda zona która ma w sobie feature teleport ma wstawiany teleport

Głosujemy 1/2. Ja zrobiłem już w initNodzie levele zon (i zakomentowałem dotychczasowe prace nad teleportem), zostały mi miasta, outery i wtedy już tylko teleporty ;].

PiotrPytlik commented 6 years ago

Dobra, czy w podejsciu drugim taki teleport i tak sie zachowuje na zasadzie "wszystkie zony które maja feature teleport o poziomie X dostają teleport globalny" - czyli taki o ktorym mowilismy kiedys, że łączy wszystkie te zony?

Jesli tak to jestem w takim razie za 2. Przemyslalem teraz chwile i widze potencjalne problemy wynikające z 1, a nie lubie myslec o potencjalnych błędach :P

radekmie commented 6 years ago

Jestem za 2.

acatai commented 6 years ago

Dobra, czy w podejsciu drugim taki teleport i tak sie zachowuje na zasadzie "wszystkie zony które maja feature teleport o poziomie X dostają teleport globalny" - czyli taki o ktorym mowilismy kiedys, że łączy wszystkie te zony?

Tak. Tzn. moglibyśmy kombinować, ale jak wspominałem mamy wtedy problem z limitacją teleportów itd. Chciałem wcześniej żeby teleporty były 'bardziej ogólne' - ale wtedy pałowalibyśmy się z nimi tyle co z połową pozostałych features.

OK, dziękuję za Wasz głos - tak jak wspomniałem wcześniej ze względu na prostotę też jestem za 2, choć 1 ciągle kusiło ze względu na 'fajność'.

2 Accepted - teleporty będą implementowane jako feature - czas zmieniać doki ;-).

acatai commented 6 years ago

OK, to jeszcze trochę o tym jak ma wyglądać faza Multi żebyśmy jak do niej dojdziemy gładko ten etap przeszli.

Działanie - update (szkic by w docu, strona 7):

  1. Bierzemy MetagrafLML, czyli pojedynczy wierzchołek z krawędziami
  2. Generujemy Metagraf Multi (patrz #57), więcej o tym potem bo są problemy
  3. Multiplikujemy LML, łączymy krawędzie zgodnie z grafem meta
  4. Mergujemy bufory (przy jakich warunkach?) oraz na twardo GOAL (jeśli występuje)
  5. Ustalamy odpowiednie levele krawędzi (jako max z proponowanych leveli i sąsiadujących zon)
  6. Sprawdzamy kto ma dostęp do jakich zon jako 'pierwszy' (z remisami).
  7. Zapisujemy do h3pgm w odpowiednim formacie (to co jest w docu na stronie 11 chyba wciąż się nadaje, można całkiem wywalić type - bo i tak jest dostępny przez base - albo dla wygody zamienić go na class).
    • (no i w międzyczasie oczywiście tworzymy rysuneczki poglądowe)

Teraz istotne kwestie: Pierwsza decyzja jak mergujemy bufory:

To będzie miało wpływ na wygląda grafów bo zmergowaniu, tzn. druga strategia merguje sporo więcej (i chyba jest lepsza? Trzeba chwilę omówić.) Oczywiście merge działa do skutku, tzn. do momentu aż mamy graf w którym nie da się nic zmergować. Chyba że wyjdzie zbyt agresywnie, ale chyba nie powinno jesli nie będzie dużo sytuacji gdzie zona ma >1 outer.

Teraz same matchingi: Jak wynika z #60, w większości przypadków mamy problem ze znalezieniem jakiegokolwiek matchingu który jest fair. A chcielibyśmy znaleźć kilka/wszystkie i z nich losować! Jeden feature który powinien usprawnić obliczenia zaproponowałem. (Być może dodatkowy bucketing po buforach o tym samym poziomie by pomógł, ale jeśli nie rozróżnialibyśmy różnych takich połączeń to mogłoby powodować dodatkowe problemy...) Albo to zadziała albo trzeba będzie przysiąść i wykombinować jakiś naprawdę sensowny algorytm.

Uważam, że to jest kwestia do rozwiązania ASAP. Jak nie da się mergować w skończonym czasie grafów które wychodzą przy obecnych, no może ciut umniejszonych ustawieniach map, to jest kiepsko.

Oczywiście kolejna kwestia będzie kto się tym zajmuje. Ja we fragmentach mogę, ale jak dojdzie do spisywania pracy to pewnie to będzie moje główne zajęcie...

radekmie commented 6 years ago

Jeżeli chodzi o merge, to chyba poszedłbym z b) - wydaje mi się to lepsze, bo bardziej łamie symetrie. Co do tego drugiego: proponuję to chociaż pobieżnie omówić na najbliższym spotkaniu.

acatai commented 6 years ago

Można działać dalej, kod przygotowujący Metagraf LML jest generowany przez #63