kolejka wydarzen w grze dla kazdego usera? Gra cz.2 (kolejka wydarzen)

0

To drugi temat odnosnie ogolnikow do mini silnika gry przegladarkowej. Sytuacja nastepująca. Dwoje userow kazdy zalogowany. Jeden z nich zaczyna budowac (DOM) i (SZOPE) zatem w tabeli query trzeba dodac jakie zadanie ma byc wykonane: 1. buduj dom na poziom , 2 buduj szope na poziom 1 Wydaje sie proste ale teraz tak. Zakladamy ze wybudowanie kolejnych poziomow podnosi punkty w rankingu gracza. Gracz ma 0 punktow i buduje te dwie rzeczy po zakonczeniu bedzie mial 23 punkty lacznie. Teraz tak, zlecam kolejke budowy i wychodze. Nie loguje sie wiecej do gry ale w rankingu po skonczeniu budowy widac ze mam 23 punkty. Ja zobacze wybudowane rzeczy dopiero po zalogowaniu ale dla innych graczy one juz sa zbudowane. Czyli kolejka czynnosci aktualizacji tabeli gracza podczas wydania polecenia musi byc ogolna i podlaczona pod crona ?

0

No ale jeśli będzie budował kopalnię, to Twój pomysł już nie zadziała.

0

To znaczy kto bedzie budowal kopalnie i czemu nie zadziala?

0

To nie będzie kopalni? To beznadziejna ta gra.

0

Nie chodzi o to czy bedzie czy nie ale czemu ma to nie zadzialac?

0

Nie trzeba crona. Wystarczy tabelka w bazie w której będziesz zapisywał eventy jakie miały/będą mieć miejsce i przeliczać punkty/surowce/cokolwiek dopiero wtedy, gdy będzie potrzebna aktualna ilość.

Łopatologiczny przykład:
jest 20:00, aktualnie masz 100 kamienia i wydobywasz 10 kamieni na godzinę w swoim kamieniołomie.
Zlecasz budowę dwóch usprawnień kamieniołomu (Usprawnienie 1 wybuduje się o 21:00 i zwiększy wydobycie do 15/h; usprawnienie 2 wybuduje się o 23:00 i zwiększy wydobycie do 20/h) i idziesz spać.
Po stronie serwera te dwa eventy maja wylądować w bazie danych (dwa INSERTy).
Dodatkowo o 01:00 najechał cie złoczyńca i zniszczył ci kamieniołom całkowicie - kolejny event ląduje w bazie danych (jeden INSERT).

O 06:00 wstajesz i logujesz się do gry. Trzeba ci wyświetlić twoja aktualną ilość kamienia, więc skrypt pobiera:

  • twoją ostatnio zapisaną ilość kamienia (100)
  • twoją ostatnio zapisaną produkcję kamienia (10/h)
  • trzy eventy dotyczące twojego wydobycia kamienia
    Myślę, że w 2 SELECTach się zamkniesz. Potem kilka mnożeń i dodawań:
    100 +
    10/h * 1 +
    15/h * 2 +
    20/h * 2 +
    0/h * 5 = 180 kamienia
    Teraz, żeby nie trzeba było później obliczać tego od nowa, zapisujesz do bazy aktualną ilość kamienia (180) i aktualną produkcję (0/h), czyli jeden UPDATE i kasujesz niepotrzebne już eventy (jeden DELETE).

Cała ta procedura przeliczania kamienia wykonywana jest dopiero wtedy, gdy potrzebujesz aktualnych wartości. Czyli gdy śpisz i nie jesteś zalogowany na stronie, to nic nie jest obliczane - jest to znacznie wydajniejsze niż wykonywanie zapytań do bazy co sekundę.
Dodatkowo "wyzwalaczem" obliczeń niekoniecznie musi być zalogowanie się na stronie. Na przykład jeśli o 05:00 inny wrogi gracz wysłał do twojego państwa szpiega, żeby dowiedzieć się ile masz surowców, to wtedy również potrzebna jest aktualna ilość kamienia, więc to również powinno uruchomić procedurę przeliczania surowców.

Dobre zaprojektowanie takiego systemu może przysporzyć trochę problemów, więc jeśli z góry zakładasz, że twoja gra nie będzie cieszyła się zainteresowaniem, albo masz kupę kasy do inwestowania w nowe serwery, to zrób to przy użyciu crona :)

0

Wyobraz sobie taka sytuacje:
jestem JA , TY i jakis koles. Ja mam kopalnie kamieni wedlug tego schematu wyzej a ty o 1 w nocy mnie atakujesz i niszczysz na maxa.
Ale teraz o 00:30 ktos mnie atakuje by zdobyc kamienie ale tez poszedl spac o 21 wiec jesli Ja sie nie loguje Ty sie nie logujesz i koles sie nie loguje.
To kiedy obliczy się ile ten koles ukradl mi kamienia jesli jego ktos zatakuje ? czy jest zatem jedna baza z kolejka i ma np 1000 czy 2000 tysiace zdarzen czy ma byc kilka tabel dla kazdej osoby tabela jego zdarzen i one maja byc jakos pozniej polaczone w zaznosci od potrzeby obliczen ?

0

To w końcu będą te kopalnie czy nie, bo już nic nie wiem? :(

0

Jeśli:

  • gracz A ma kopalnie kamieni
  • gracz B atakuje gracza A o 00:30
  • gracz C atakuje gracza A o 01:00
  • gracz D atakuje gracza C o 02:00
  • wszystkie te zadania zostały 'zaplanowane', a sami gracze smacznie śpią od godziny 21:00 do 06:00

O 06:00 gracz D loguje się do gry. Przeliczamy jego ilość kamienia:

  • D_stan_poczatkowy + D_przyrost * 9h + ilosc_kamienia_gracza( C, 02:00 )

ilosc_kamienia_gracza( C, 02:00 ) to:

  • C_stan_poczatkowy + C_przyrost * 5h + ilosc_kamienia_gracza( A, 01:00 )

ilosc_kamienia_gracza( A, 01:00 ) to mniej więcej:

  • ilosc_kamienia = A_stan_poczatkowy;
  • ilosc_kamienia += A_przyrost * 3,5h;
  • zwieksz_ilosc_kamienia_graczowi( B, ilosc_kamienia);
  • ilosc_kamienia = 0; // gracz B ukradl wszystko
  • ilosc_kamienia += A_przyrost * 0,5h;
  • return ilosc_kamienia;

Czyli utworzyły nam się łańcuchy powiązań. Zalogowanie jednego gracza powoduje przeliczanie surowców u kilku innych graczy. Podczas przeliczania surowców gracza X powinno się:

  • kasować stare eventy dotyczące jednego gracza (gracz_X_ulepsza_kopalnie_o_23:00)
  • zamieniać stare eventy dotyczące wielu graczy (gracz_Y_atakuje_gracza_X_o_01:00 ===> gracz_Y_wraca_z_lupem_wysokosci_238_kamienia) // 238 to ilość kamienia gracza X o godzinie 01:00

I teraz tak:
Czy da się to tak zaprojektować, żeby zadziałało w każdym, nawet najbardziej skomplikowanym przypadku? TAK
Czy jestem w stanie/chce mi się zaprojektować to podczas pisania z palca odpowiedzi tu na forum? NIE
Więc w powyższym przykładzie pewnie też będzie się dało znaleźć jakieś luki :)

0

To brzmi rozsadnie bardzo czyli wybieramy zaleznosc relacyjną. Wiadomo, że przeliczenie akcji gracza X to zaledwie kilka rekordów w tabeli zdarzen. Tylko pytanie co zrobic jesli gracz C zaloguje sie i juz obliczy sobie ile ma kamienia a gracz D zaloguje sie dopiero rano. Wtedy rozkaz oblicz stan kamienia gracza (C,2:00) powinien uwzgledniac juz przeliczona wartosc wczeniejsza.

ilosc_kamienia_gracza( C, 02:00 ) to:

  • C_stan_poczatkowy + C_przyrost * 5h + ilosc_kamienia_gracza( A, 01:00 )

Chodzi o to ze jesli minela juz ta godzina a gracz A sie zalogowal, to mogl cos kupic i stan kamienia ma obecnie o 23:30 juz zakutalizowany. Ale zakladam ze jest godzina 3 w nocy i gracz A znowu sie zalogowal. To skad funkcja
ilosc_kamienia_gracza( A, 01:00 ) bedzie wiedziala ile bylo tego kamienia o 1:00 ?

1

Niezbyt rozumiem o co ci chodzi, ale i tak postaram się odpowiedzieć :)

Powiedzmy, że mamy gracza A i znamy jego ilość kamienia z przeszłości (z czasu ostatniej aktualizacji) oraz przyrost kamienia na godzinę. Mamy też eventy dotyczące ilości kamienia gracza A, np:

  • zwiększ przyrost kamienia gracza A ( 23:00 )
  • gracz B atakuje gracza A (01:00)

Oraz jakiś event nie dotyczący bezpośrednio gracza A

  • gracz C atakuje gracza B (02:00)

Wyzwalać(uruchamiać) eventy będą logujący się na stronę gracze, lub inne eventy, tworząc takie łańcuszki jak w poprzednim poście. Np:
Pierwszy event dotyczy tylko gracza A, będzie wyzwolony gdy będzie trzeba przeliczyć ilość kamienia gracza A
Drugi event dotyczy graczy A i B, będzie wyzwolony gdy będzie trzeba przeliczyć ilość kamienia gracza A lub gracza B
Trzeci event dotyczy graczy B i C, będzie wyzwolony gdy będzie trzeba przeliczyć ilość kamienia gracza B lub gracza C

Powiedzmy, że mamy godzinę 06:00 i rozpatrujemy 3 przypadki:
a) Najpierw zalogował się gracz A -> pobieramy eventy 1 oraz 2 -> obliczamy aktualną ilość kamienia gracza A
b) Najpierw zalogował się gracz B -> pobieramy eventy 2 oraz 3 -> event 2 wyzwala obliczanie ilości kamienia gracza A z godziny 01:00 -> pobieramy event 1 -> obliczamy ilość kamienia gracza A z godziny 01:00 -> obliczamy aktualną ilość kamienia gracza B
c) Najpierw zalogował się gracz C -> pobieramy event 3 -> event 3 wyzwala obliczanie ilości kamienia gracza B z godziny 02:00 -> pobieramy event 2 -> event 2 wyzwala obliczanie ilości kamienia gracza A z godziny 01:00 -> pobieramy event 1 -> obliczamy ilość kamienia gracza A z godziny 01:00 -> obliczamy ilość kamienia gracza B z godziny 02:00 -> obliczamy aktualną ilość kamienia gracza C

Natomiast z tego co rozumiem to pytasz o to, jak obliczyć ilość kamienia gracza B, jeśli minutę temu zalogował się gracz A i znamy jego ilość kamienia z godziny 05:59, a potrzebujemy z godziny 01:00. No więc tak jak mówiłem, podczas aktualizowania ilości kamienia gracza X:

  • usuwamy wszystkie stare eventy dotyczące tylko gracza X (np. zwiększ przyrost kamienia gracza X (23:00))
  • zamieniamy wszystkie stare eventy dotyczące graczy X i Y, na takie dotyczące tylko gracza Y (np. gracz Y atakuje gracza X (01:00) ===> gracz Y wraca z bitwy z łupem wysokości 283 kamienia (01:00))
0

Zastanawiałem się właśnie na obliczaniem wstecz, co jak wywnioskowałem nie istnieje, bo nie musi. rewelacja, czyli eventy obliczamy na bieżąco i aktualizujemy dane dla poszczególnego gracza którego zdarzenie dotyczy. Dzięki wielkie :D

p.s. zrobiłem dzis opis surowców i tabele zatem niebawem będą testy :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1