piątek, 30 grudnia 2011

Ukryta gra na Steamie - Rusty Hearts

Tak oto kolejny wpis traktować będzie o świątecznej promocji na Steamie, jednak tym razem jego bohaterem będzie ukryta (na pewno przed polakami) gra. Gra, której z wewnątrz klienta nie odnajdziemy, ale już z przeglądarki jak najbardziej. Sęk w tym, że nie wiadomo jakiej gry szukać...

A nie wiadomo, gdyż w wielkim stosie prezentów (The Great Gift Pile) gra ta figuruje jako "Hidden" - a z darmowych Hiddenów to wyszukiwarka pokazuje jedynie mod do HL2, który to już wcale taki darmowy nie jest.

Wyszukiwarka w kliencie Steam nie pokazuje gry
Na szczęście w innych krajach gra ta jest dostępna, tak więc dość łatwo można wyszukać jej tytuł :)
A jeśli chodzi o samą instalację - wystarczy w przeglądarce wejść na stronę sklepową Rusty Hearts i kliknąć "ZAINSTALUJ", lub po prostu kliknąć w ten link (install).
A aby zdobyć to upragnione osiągnięcie (All I Want for Christmas is Sewers) trzeba jak mi się zdaje wykonać pierwszy quest dla człowieka od milicji (join militia), gdyż dopiero wtedy Ryan będzie chciał dać nam tego "A Simple Task" questa.

niedziela, 25 grudnia 2011

Steam a zajmowane miejsce na dysku

Tak jakoś ostatnio przy okazji tej wielkiej świątecznej promocji na Steamie zauważyłem, że miejsce na dysku, które gra ma rzekomo zajmować ma się nijak do miejsca faktycznie używanego.
Odkrycia tego nie dokonałbym po prawdzie gdybym nie postanowił zdobyć świątecznego osiągnięcia (achievement) w grze CrimeCraft GangWars. Dlaczego bym nie odkrył? Ano dlatego, że przy większości gier różnica między deklarowanym a faktycznym użyciem dysku jest niewielka - w dzisiejszych czasach 100 czy nawet 500 MiB nie robi wielkiej różnicy.
Z CrimeCraft jest jednak inaczej - tutaj różnica sięga 4GiB, co jakby nie patrzeć jest prawie 2x większą ilością niż deklarowane 5500MiB...

Według Steam'a gra zajmuje 5500MB
Na dysku zaś system pokazuje, że jest to praktycznie 10GB
Na początku sądziłem, że to po prostu jakiś bug związany z tą grą, ale przypadek ten nie jest odosobniony - dotyczy on praktycznie każdego tytułu, a widoczny jest zwłaszcza przy tych, które "rozwinęły się" od momentu dodania je na Steam'a.

Dodatkowo  dane ze "Spiral Knights" - kolejnej darmowej gry



W mojej opinii jest to problem wynikający z faktu, że Steam po otrzymaniu wersji "do dystrybucji" wbija w systemie rozmiar gry i później już jej nie aktualizuje, podczas gdy producent może ją cały czas aktualizować i powiększać jej rozmiar. 





Rozwiązanie jest proste - ot wystarczyłoby by po każdej aktualizacji producent zmuszony był wbić nowy rozmiar... bo nie czarujmy się mieć 4GB a nie mieć to jest już różnica - zwłaszcza, gdy te 4GB musimy ściągnąć przez Internet.

wtorek, 1 listopada 2011

Stronghold 3: engine fail

Po długim wyczekiwaniu pojawiła się trzecia odsłona twierdzy (link). O samej grze rozpisywać się nie będę - bo nie miejsce na to - wspomnę jednak o problemie, który zapewne dotyka większość użytkowników posiadających 2 karty graficzne na komputerze (czyli głównie posiadacze laptopów z zarówno zintegrowanymi kartami "energooszczędnymi" jak i zwykłymi).

Problem ów dotyczy inicjalizacji silnika gry a objawia się takim oto komunikatem zaraz po uruchomieniu gry:
Failed to initialize the engine
Problem leży właśnie w tym, że gra wykrywa, iż mamy dwie karty i z nieznanych przyczyn sprawdza czy ta słabsza poradzi sobie z tym wielkim tworem studia firefly. Oczywiście w większości przypadków wynikiem tego testu jest uroczy komunikat o błędzie.

Rozwiązanie
Remedium na ten problem jest (tymczasowe) wyłączenie karty graficznej :)



  1. Najpierw musimy dostać się do menedżera urządzeń - tak więc znajdujemy skrót do "komputera" i klikamy go PPM, a następnie wybieramy "Właściwości"

  2. Gdy już ujrzymy właściwości naszego komputera to klikamy w "Menedżer urządzeń".

  3. W okienku, które się pojawiło wybieramy adaptery graficzne i wyłączamy ten, który odnosi się do naszej wbudowanej/zintegrowanej karty graficznej
  4. Obok ikonki powinna pojawić się taka mała strzałeczka lub inne oznaczenie (w przypadku starszych wersji Windowsa). Teraz już możemy odpalić Twierdzę 3, a po ukończeniu gry ponownie włączyć odpowiednią kartę graficzną.
Zadziwiające jest, że taka nowa gra ma takie problemy... choć ten lapsus przestaje dziwić gdy się w nią trochę dłużej pogra... 

piątek, 14 października 2011

Array vs Object

Tak jakoś nastał obiektowy szał i wszystko wszędzie musi być obiektowe. Oczywiście PHP ta mania nie ominęła i tak oto mamy coraz to większą społeczność krzyczących, że Object i Class jest super fajne, a Array to zło i anachroniczny przeżytek. Ale czy jest tak na pewno?
Oczywiście tablice nie pozwalają na implementacje funkcji odwołujących się jedynie do danych z konkretnej tablicy - takie coś musimy zrealizować poprzez metodę jakiejś klasy lub po prostu funkcję nie należącą do żadnej klasy (co oczywiście jest mało eleganckie). Jednak jeśli zależy nam jedynie na przechowaniu tudzież przekazaniu danych z jednej funkcji do drugiej to czy warto definiować nowy typ danych (zakładając, że struktura danych nigdy nie ulegnie zmianie)? W innych językach programowania w 99% przypadków odpowiedź brzmiała by "tak", jednak w przypadku PHP nie jest ona wcale taka oczywista.

Dlaczego? Ano załóżmy, że chcemy przesłać dane dotyczące elementu opisywanego za pomocą trzech atrybutów (id, name, color). Przykładowy kod realizujący takie zadanie wyglądałby następująco:
function getArray()
{
 $item = Array();
 $item['id'] = 1;
 $item['name'] = "Pure item";
 $item['color'] = "none";
 return $item;
}
 
function getObject()
{
 $item = new stdClass();
 $item->id = 1;
 $item->name = "Pure item";
 $item->color = "none";
 return $item;
}
function getItem()
{
 $item = new Item();
 $item->id = 1;
 $item->name = "Pure item";
 $item->color = "none";
 return $item;
}
Dla ostatniej funkcji konieczne jest zdefiniowanie typu "Item":

class Item
{
    public $id;
    public $name;
    public $color;
}

Wykonanie tych funkcji jak widać tworzy struktury o tych samych atrybutach - raz jest to tablica, a w dwóch przypadkach są to instancje klas.
getArray      0.1664547920
getObject      0.2381231785
getItem       0.2375209332
Jak widać stworzenie i zapełnienie tablicy trwa ok. 70% czasu potrzebnego na utworzenie odpowiadającej jej klasie. Warto zauważyć, że czasy potrzebne na utworzenie instancji obiektu za pomocą zdefiniowanej klasy (Item) jak i użycia stdClass() są porównywalne.

A jak przedstawia się proces pobierania wartości z tych trzech utworzonych struktur danych?
Acquire from Array     1.7432529926
Acquire from Object     2.1544189453
Acquire from Item     2.3280811310
Znów nie ma większych zaskoczeń- używanie tablic okazuje się o wiele szybsze niż zaprzęganie klas. Co ciekawe pobieranie danych z instancji utworzonych za pomocą stdClass() okazuje się szybsze (choć nieznacznie) od pobierania wartości atrybutów z klas zdefiniowanych przez użytkownika.

Wnioski
To co chciałem pokazać w tym wpisie to to, że nie warto bezkrytycznie podchodzić do obecnych "trendów". Jeśli potrzebujemy maksymalnie wydajnego sposobu na przekazanie zestawu danych z jednego miejsca w programie do drugiego - to definiowanie klas mija się z celem. Oczywiście jeśli chcemy by nasz kod był maksymalnie przenośny to warto (a wręcz należy) użyć klas - ale tych definiowanych przez użytkownika. Wszak po to tworzymy definicję struktury klasy aby móc dołączyć do niej metody, a w przypadku używania stdClass otrzymujemy (pod względem czystej funkcjonalności) tablicę, która w dodatku działa wolniej od tej "standardowo" tworzonej za pomocą Array().

Plik z testami do pobrania z chomika (link).