Poradnik

Jak hostować grę HTML5 na swojej stronie: wgranie i naprawa

Praktyczny przewodnik dla statycznego folderu gry: gdzie go umieścić, jak otworzyć, jak osadzić w stronie i co sprawdzić, gdy gra się nie uruchamia.

Panda Polarzinho wpycha pudełko z grą przez świecącą rurę z serwera w stronę okna przeglądarki, w którym widać grę z latającymi wyspami.

Jak hostować grę HTML5, w jednym zdaniu: proszę wgrać zawartość jej folderu game/ na dowolny hosting serwujący pliki statyczne, zachować podfoldery dokładnie takie, jakie są, i otworzyć adres folderu w przeglądarce. Gotowy do hostowania folder game/ każdej edycji w naszym sklepie działa bez zmian: bez PHP, bez bazy danych, bez etapu budowania i bez konta, więc hosting musi tylko przekazywać pliki do przeglądarki gracza.

To całe zadanie, gdy wszystko idzie dobrze. Ten poradnik dotyczy pozostałych dni: pustego ekranu, błędów 404, komunikatu o typie MIME, iframe, który niczego nie wyświetla. Sprzedajemy te szablony, więc proszę traktować go jako podręcznik terenowy do naszych własnych paczek. Serwowaliśmy kopie Gridspark i Velvet Pool z tymczasowego serwera lokalnego, kilkoma sposobami celowo psuliśmy Gridspark i czytaliśmy publiczne podręczniki innych edycji. Gdy twierdzenie pochodzi z podręcznika, a nie z naszego testu, mówimy o tym.

Na czym naprawdę polega hostowanie gry HTML5

Hosting statyczny przechowuje pliki i wydaje je przeglądarkom na żądanie. Nigdy nie uruchamia Państwa gry; robi to przeglądarka gracza. Dlatego wymagania naszych edycji brzmią tak prosto: aktualna przeglądarka, hosting serwujący pliki statyczne przez HTTP lub HTTPS oraz brak PHP, bazy danych i konta do grania. Folder game/ jest już zbudowany, więc jego publikacja nie wymaga npm ani etapu budowania.

Dwa ograniczenia, które warto znać na początku. Niektóre edycje mają opcjonalne elementy niestatyczne: Zabum i Ricopop wymieniają opcjonalną tablicę wyników, która wymaga PHP 7.4 lub nowszego i katalogu z prawem zapisu, a edycje w TypeScript (Beep Out, Pinloop, Trimora, Twirldrop, Riffvolt, Sunset Rally, Tenguin, Mochi Monsters, Deepforge, Barricade Z i Zabum) wymagają Node.js tylko wtedy, gdy chcą Państwo edytować źródła i budować je ponownie; każdy podręcznik podaje wersję. Velvet Pool, Puttide, Ricopop i Gridspark są dostarczane jako zwykły JavaScript, bez kompilacji między edycją a plikami, które Państwo wgrywają. Nic z tego nie jest potrzebne, by opublikować grę w stanie dostarczonym. Sam hosting nie jest też częścią zakupu. Warunki sklepu wymieniają hosting i instalację na Państwa serwerze wśród osobnych usług, które wyceniamy przed rozpoczęciem pracy; wsparcie obejmuje pytania dotyczące instalacji i używania dostarczonych plików.

Co trafia na serwer, a co zostaje na komputerze:

  • Proszę wgrać wszystko, co jest w game/: index.html, skrypty, style, obrazy, dźwięki i czcionki.
  • Proszę pominąć source/ (edytowalna kopia dla programisty), documentation/ (podręcznik) i sam plik ZIP. Podręcznik Zabum wymienia omyłkowe wgranie source/ jako przyczynę błędów 404, takich jak main.tsx.
  • Informacje licencyjne podmiotów trzecich dołączone do paczki proszę zachować razem z produktem, jak wymagają warunki.

Zobacz Gridspark, edycję, której używamy jako przykładu

Jak hostować grę HTML5: krótka droga od pliku ZIP do grywalnej strony

Poniższe kroki wynikają z rozdziałów instalacyjnych podręczników Velvet Pool, Puttide, Gridspark i Sunset Rally oraz ze sprawdzeń, które dodaliśmy po testach. Gridspark jest przykładem, bo to edycja, którą serwowaliśmy i psuliśmy najczęściej.

  1. Proszę rozpakować paczkę na komputerze. Znajdą Państwo game/ (folder do publikacji), source/ (edytowalną kopię) i documentation/ (podręcznik).
  2. Opcjonalnie, ale tanio: proszę przetestować lokalnie. W terminalu w folderze game/ proszę uruchomić python -m http.server 8765 i odwiedzić http://localhost:8765/. Jeśli gra tam działa, pliki są w porządku, a każdy późniejszy problem leży po stronie hostingu.
  3. Proszę od razu wybrać docelowy adres, na przykład https://your-site.example/games/gridspark/. Podfolder działa, ponieważ ścieżki wewnątrz gry są względne; podręcznik Gridspark proponuje public_html/games/gridspark/.
  4. Proszę wgrać zawartość game/ do tego folderu menedżerem plików hostingu lub klientem FTP, zachowując każdy podfolder. Plik index.html musi znaleźć się bezpośrednio w folderze, a nie piętro głębiej.
  5. Proszę otworzyć adres folderu przez https, z ukośnikiem na końcu. W Gridspark dotykają Państwo ekranu startowego (przeglądarki czekają na dotyk lub kliknięcie, zanim pozwolą na dźwięk) i naciskają Play.
  6. Proszę wykonać jeden ruch, przeładować stronę i sprawdzić, czy menu oferuje teraz Continue. To dowodzi, że przeglądarka zapisuje postęp dla Państwa adresu.
  7. Proszę dodać link do folderu na swojej stronie albo osadzić go na stronie (patrz sekcja o iframe poniżej).

Gotowy folder Gridspark zawiera obok siebie index.html, style.css, gridspark.config.js, src/ i assets/, a podręcznik prosi, by trzymać je razem. Inne edycje mają inny układ (Velvet Pool ma css/ i assets/ zamiast jednego arkusza stylów), ale zasada jest ta sama: wgrywa się folder tak, jak przychodzi.

Dlaczego dwuklik na index.html daje pustą stronę

Edycje, które otwieraliśmy, ładują kod jako moduły ES, a przeglądarki odmawiają ładowania modułów z adresów file://. Otworzyliśmy Gridspark prosto z dysku w Chromium i dostaliśmy ciemny, pusty ekran. Konsola mówiła, że skrypt został zablokowany przez politykę CORS, z uzasadnieniem "Cross origin requests are only supported for protocol schemes", takimi jak http i https. Ten sam folder serwowany przez lokalny serwer WWW od razu pokazał ekran startowy. Podręczniki Velvet Pool, Puttide, Sunset Rally i Gridspark mówią to samo: nie otwierać gry z file://.

  • Nie zadziała: file:///C:/Users/you/games/gridspark/index.html
  • Zadziała: http://localhost:8765/ z lokalnego serwera testowego albo https://your-site.example/games/gridspark/ na Państwa hostingu.

Testowaliśmy tylko Chromium. Podręczniki opisują blokadę jako coś, co robią popularne przeglądarki, więc proszę zakładać, że dotyczy wszystkich.

Osadzenie gry na stronie przez iframe

Aby pokazać grę na istniejącej stronie, wystarczy skierować iframe na wgrany folder. To znacznik, który testowaliśmy:

<iframe src="https://your-site.example/games/gridspark/" title="Gridspark" allow="fullscreen; autoplay" width="960" height="540" style="border:0"></iframe>

  • src: pełny adres folderu, z https i ukośnikiem na końcu.
  • title: krótka nazwa. Czytniki ekranu używają jej do opisania ramki.
  • allow="fullscreen; autoplay": podręczniki mówią, by w razie potrzeby zezwolić w iframe na pełny ekran i autoodtwarzanie. W naszym teście ramka z innego adresu bez tego miała wyłączony pełny ekran, a Gridspark po prostu ukrywał swój przycisk pełnego ekranu. Starszy atrybut allowfullscreen dawał ten sam wynik co allow. Ramka pod tym samym adresem co strona dostaje pełny ekran w obu przypadkach.
  • Bez atrybutu sandbox. Przy samym sandbox="allow-scripts" Gridspark nigdy się nie uruchomił: ramka dostaje pochodzenie null, przeglądarka zablokowała własny skrypt gry, a local storage zgłosiło błąd bezpieczeństwa. Dodanie allow-same-origin sprawia, że działa, ale MDN ostrzega, że ta para na ramce z tego samego pochodzenia znosi ochronę, więc dla gry hostowanej samodzielnie sandbox proszę pominąć.

Dopasowanie do telefonów

Stały obszar 16:9 wygląda dobrze na komputerze i źle na telefonie. Przy szerokości 390 px iframe z aspect-ratio 16/9 ma tylko 219 px wysokości, a menu Gridspark było ucięte pod przyciskiem Daily challenge. Ustawienie wysokości ramki na 75svh, trzy czwarte wysokości ekranu, pokazało całe menu. Państwa własna strona potrzebuje też znacznika meta viewport; sześć otwieranych przez nas paczek ma go we własnym index.html, dlatego gra skaluje się po otwarciu bezpośrednim.

Dwa ekrany telefonów obok siebie, każdy pokazuje stronę z menu startowym Gridspark w iframe: po lewej niski kadr 16:9, który ucina menu, po prawej wysoki kadr pokazujący całe menu.
Ta sama gra, ta sama szerokość telefonu. Po lewej: iframe 16:9. Po prawej: ramka o wysokości 75svh.

Gra działa pod własnym adresem, bez żadnej strony wokół, więc zwykły link otwierający ten adres jest zawsze poprawnym rozwiązaniem awaryjnym.

Zobacz Velvet Pool, edycję 3D osadzaną w ten sam sposób

WordPress i inne kreatory stron

Hostowanie folderu i pokazanie go na stronie to dwa osobne zadania, a w WordPressie wykorzystują dwa różne narzędzia. Wszystko poniżej pochodzi z dokumentacji WordPressa i referencji dla programistów, a nie z uruchamiania WordPressa przez nas.

  1. Proszę wgrać folder menedżerem plików hostingu lub FTP, do drzewa folderów strony (na przykład folder games/ obok folderów WordPressa). Nie przez Bibliotekę mediów: kod WordPressa usuwa .html i .js z dozwolonych typów wgrywania, jeśli użytkownik nie ma uprawnienia unfiltered_html.
  2. Proszę otworzyć adres folderu osobno, zanim dotkną Państwo jakiejkolwiek strony. Domyślne reguły Apache opisane w dokumentacji WordPressa kierują żądanie do index.php tylko wtedy, gdy nie istnieje pasujący plik ani folder (to sprawdzają warunki !-f i !-d), więc wgrany folder jest serwowany w stanie, w jakim jest.
  3. Proszę dodać iframe w bloku Własny HTML. WordPress dokumentuje, że użytkownikom bez uprawnienia unfiltered_html, na przykład Współtwórcy, znaczniki iframe są usuwane przy zapisie wpisu. Jeśli ramka znika po zapisie, proszę sprawdzić, kto edytował stronę.

Inne kreatory stron i systemy CMS: nie testowaliśmy ich i niczego o żadnym z nich nie twierdzimy. Gra potrzebuje wszędzie tych samych dwóch rzeczy: miejsca na wgrany folder i elementu osadzania, który akceptuje iframe. Jeśli kreator nie oferuje żadnego z nich, proszę hostować folder gdziekolwiek, gdzie serwowane są pliki statyczne, i linkować do jego adresu.

Gdy gra się nie uruchamia: lista rozwiązywania problemów

Proszę otworzyć narzędzia deweloperskie przeglądarki (F12 w większości przeglądarek na komputerze) i obejrzeć karty Console i Network, zanim cokolwiek Państwo zmienią. Każda z poniższych awarii zostawia tam czerwoną linię, a nazwa pliku w niej zwykle wskazuje przyczynę.

Pusty ekran

Proszę sprawdzać po kolei: adres zaczyna się od http:// lub https://; konsola nie ma czerwonych linii; nazwy plików zachowują dokładną wielkość liter; a w przypadku edycji 3D dostępny jest WebGL2 (podręcznik Velvet Pool mówi, by włączyć akcelerację sprzętową). Hosty z Linuksem traktują Game.js i game.js jako dwa pliki, a Windows nie, więc folder działający na Państwa komputerze może przestać działać po wgraniu. Podręczniki Velvet Pool i Zabum ostrzegają przed tym.

404 dla src/main.js, czcionek lub obrazów

Część folderu nie dotarła albo dotarła piętro za głęboko. Odtworzyliśmy to, wgrywając tylko index.html, style.css i plik konfiguracyjny: ekran pozostał pusty, a karta Network pokazała 404 dla src/main.js i każdej czcionki. Proszę wgrać brakujące foldery albo przenieść zawartość wyżej, by index.html leżał pod adresem, który Państwo otwierają. Jeśli brakuje obrazów lub dźwięków albo są uszkodzone, podręcznik Zabum sugeruje FTP w trybie binarnym lub automatycznym albo wgranie archiwum ZIP i rozpakowanie go w menedżerze plików hostingu. 404 oznacza brakujący plik. To nie jest problem MIME.

Strona ładuje się bez stylów, z gigantycznymi ikonami

Jeśli reguła przepisywania lub ustawienie czystych adresów serwuje folder bez ukośnika na końcu, ścieżki względne są rozwiązywane piętro wyżej. Odtworzyliśmy to na serwerze testowym, który zwraca stronę folderu bez przekierowania. Przeglądarka zażądała /games/style.css i /games/src/main.js zamiast plików wewnątrz /games/gridspark/, dostała 404 i narysowała menu jako surowe przyciski i nadmiernie duże ikony. Do folderu proszę linkować z ukośnikiem na końcu albo wskazywać bezpośrednio index.html.

Okno przeglądarki z białą stroną, niestylowanymi szarymi przyciskami i nadmiernie dużymi czarnymi ikonami: menu Gridspark bez arkusza stylów.
Gridspark otwarty pod adresem bez ukośnika na końcu, na serwerze bez przekierowania: brak arkusza stylów, brak skryptu.

Błąd typu MIME w skrypcie modułu

W naszym teście konsola pokazała: Failed to load module script: Expected a JavaScript-or-Wasm module script but the server responded with a MIME type of "text/plain". Przeglądarki są rygorystyczne wobec skryptów modułów. Podręczniki mówią, że serwer musi wysyłać pliki .js z typem MIME JavaScript, a .wasm jako application/wasm; podręcznik Sunset Rally dodaje .mjs. Karta Network pokazuje Content-Type każdego pliku. W otwieranych przez nas wersjach moduły to pliki .js. Jeśli dodają Państwo własne pliki .mjs, a starsza konfiguracja Apache ich nie mapuje, rozwiązuje to jedna linia w .htaccess, ta sama, której używa nasza własna strona:

AddType text/javascript .mjs

Tabela typów Apache 2.4.62 na naszej maszynie testowej mapuje już js i mjs na text/javascript, a wasm na application/wasm, więc standardowa instalacja nie potrzebuje tej linii. Inne serwery mają własne tabele; proszę zapytać osobę, która prowadzi Państwa serwer.

Zablokowane przez politykę CORS

Skrypty modułów i czcionki ładowane z innego adresu wymagają nagłówka Access-Control-Allow-Origin z tego adresu. W naszym teście strona na jednym porcie nie mogła załadować skryptu modułu z innego portu, dopóki drugi serwer nie wysłał nagłówka. W praktyce rozwiązanie jest nudne: pliki gry proszę trzymać razem w jednym folderze pod jednym adresem, tak jak zbudowane są paczki. CORS nie jest potrzebny do osadzenia gry w iframe na innej stronie, ponieważ iframe po prostu ładuje adres gry. Błąd CORS w osadzeniu zwykle pochodzi od atrybutu sandbox, opisanego wyżej.

Treść mieszana na stronie https

Strona serwowana przez https nie może ładować skryptów ani iframe przez http: przeglądarki blokują oba, a MDN wymienia wśród blokowanych typów także czcionki i żądania fetch. W src iframe i w każdym wpisanym pełnym adresie proszę używać https://. Pliki gry używają ścieżek względnych, więc podążają za schematem otwartego adresu. Jeśli adres https w ogóle się nie otwiera, proszę najpierw włączyć certyfikat w panelu hostingu.

Iframe pokazuje „refused to connect”

W naszym teście Chromium zapisało tę linię, z adresem zablokowanej ramki w pierwszych cudzysłowach: Refused to display 'https://game-host.example/' in a frame because it set 'X-Frame-Options' to 'sameorigin'. Serwer hostujący grę wysyłał ten nagłówek. SAMEORIGIN zezwala na osadzanie tylko z tego samego adresu, a DENY nie zezwala nigdy; podobną rolę pełni reguła frame-ancestors w nagłówku Content-Security-Policy. Proszę zmienić nagłówek dla folderu gry albo serwować stronę i grę z jednego adresu.

Brak dźwięku na początku

Przeglądarki blokują dźwięk do pierwszego dotyku lub kliknięcia, dlatego Gridspark otwiera się na ekranie „dotknij, by zacząć”. Proszę dotknąć raz, a potem sprawdzić głośność i uprawnienia przeglądarki.

Zobacz Puttide, edycję golfową z gotową do hostowania wersją

Aktualizacja gry bez serwowania wpół starej wersji

Przeglądarki buforują skrypty, więc po wgraniu Państwo lub gracz możecie nadal widzieć starą grę. Podręcznik Gridspark podaje regułę: zrobić kopię zapasową swoich zmian, wymienić grywalne pliki jako jeden zestaw, przetestować i wykonać twarde odświeżenie, jeśli hosting buforuje stare moduły. Nie wolno mieszać starych i nowych modułów. Gra złożona z wielu małych plików importujących się nawzajem to coś, czego nie aktualizuje się w połowie.

Edycje z service workerem mają własny cache. Zabum jest PWA: po aktualizacji proszę wykonać twarde odświeżenie (Ctrl lub Cmd plus Shift plus R). Jeśli wymieniali Państwo pliki audio, proszę zmienić nazwę cache w sw.js (przykład z podręcznika przechodzi z zabum-v5 na zabum-v6) i wgrać ten plik. Jeśli strona stoi za CDN, proszę też wyczyścić jego cache. Z przeczytanych przez nas podręczników Zabum jest jedyną PWA; podręczniki Velvet Pool i Puttide mówią wprost, że ich gry nie są instalowalnymi aplikacjami offline.

Przed wymianą plików proszę przeczytać dziennik zmian i zachować kopię wszystkiego, co Państwo edytowali. Zapisy mieszkają w przeglądarce każdego gracza, a nie w wgrywanym folderze, więc wymiana plików ich nie usuwa.

Zobacz Zabum, edycję PWA z opcjonalną tablicą wyników w PHP

Gdzie zapisywany jest postęp i co robi wyczyszczenie przeglądarki

Te edycje nie mają kont ani serwerowej bazy danych. Ustawienia, język, bieżąca rozgrywka i rekordy osobiste są w pamięci lokalnej przeglądarki (local storage) i nic nie jest wysyłane do Polar Games. Podręcznik Gridspark wymienia klucze gridspark.standalone.v1.*; po jednym ruchu widzieliśmy gridspark.standalone.v1.best i gridspark.standalone.v1.save.

Menu główne Gridspark z przyciskiem Continue, odnośnikiem New game, przyciskiem Daily challenge i zapisanym najlepszym wynikiem 3 257.
Przy kolejnej wizycie menu oferuje Continue i zapisany najlepszy wynik. Oba są odczytywane z przeglądarki.

Pamięć należy do adresu (protokół, host i port), a nie do folderu. Sprawdziliśmy to na trzy sposoby. Kopia Gridspark w innym folderze tego samego adresu odczytała te same zapisane wartości. Ta sama gra otwarta jako localhost zamiast 127.0.0.1 zaczęła od zera, tak samo ten sam adres na innym porcie. Podręcznik Zabum dodaje, że http i https, www i bez www oraz subdomeny mają każda własną pamięć.

  • Wyczyszczenie danych witryny lub ciasteczek kasuje zapisaną grę i rekordy. W oknie prywatnym postęp może trwać tylko przez sesję; gra działa dalej, gdy pamięć jest zablokowana.
  • Inna przeglądarka lub inne urządzenie zaczyna od zera. Nie ma synchronizacji ani konta do zalogowania.
  • Zmiana adresu resetuje wszystkich: http na https, www na bez www, nowa domena.
  • Przeniesienie gry do innego folderu pod tym samym adresem zachowuje zapisy, jak pokazał nasz test Gridspark.

Lista testowa przed udostępnieniem linku

  1. Proszę otworzyć docelowy adres w przeglądarkach, z których korzystają Państwa gracze: opartej na Chromium (Chrome lub Edge), Firefoksie i Safari. Nasze testy działały tylko w Chromium, więc to lista do wykonania przez Państwa.
  2. Proszę otworzyć na prawdziwym telefonie, najpierw pod własnym adresem gry, a potem wewnątrz Państwa strony, w obu orientacjach.
  3. Proszę ograniczyć łącze w narzędziach deweloperskich i obserwować pierwsze ładowanie. Gridspark, serwowany bez kompresji z naszego lokalnego serwera, potrzebował około 0,5 MB i 26 żądań, by dojść do ekranu startowego. Przy Chromium ograniczonym do 1,6 Mbit/s i opóźnieniu 150 ms ekran pojawił się po około 3 sekundach. Cały folder game/ ma w naszej kopii około 3,4 MB; Velvet Pool około 7,3 MB, a Puttide około 15 MB. Jeśli starsze telefony sobie nie radzą, podręcznik Zabum sugeruje sprawdzić, czy hosting kompresuje pliki przez gzip lub brotli.
  4. Proszę wykonać ruch, przeładować i potwierdzić, że widać Continue i najlepszy wynik.
  5. Proszę dotknąć raz i sprawdzić, czy dźwięk startuje. Cisza przed pierwszym dotykiem jest normalna.
  6. Proszę otworzyć okno prywatne. Gra powinna nadal działać, nawet jeśli po zamknięciu zapomni postęp.
  7. Proszę przeczytać karty Console i Network przy pierwszym ładowaniu: bez czerwonych linii, bez 404.
  8. W osadzeniu proszę sprawdzić, czy przycisk pełnego ekranu się pojawia i czy ramka jest wystarczająco wysoka na telefonie.

FAQ

Czy do hostowania gry HTML5 potrzebuję PHP, bazy danych lub specjalnego serwera?

Nie w przypadku naszych edycji w stanie dostarczonym. Są statyczne: wgrywa się folder game/ na hosting serwujący pliki przez HTTP lub HTTPS i otwiera go. Zabum i Ricopop mają opcjonalną tablicę wyników, która wymaga PHP 7.4 lub nowszego i katalogu z prawem zapisu.

Czy mogę po prostu kliknąć dwukrotnie index.html?

Nie. Przeglądarki blokują moduły gry w file://, a strona pozostaje pusta. Grę proszę otwierać przez adres http lub https, na hostingu albo na lokalnym serwerze testowym, takim jak python -m http.server 8765.

Czy potrzebuję HTTPS?

Podręczniki mówią, by przy publicznym hostingu używać HTTPS. Podręcznik Zabum mówi, że Dodaj do ekranu głównego tego wymaga, a strona https nie może osadzić iframe przez http, ponieważ przeglądarki blokują to jako treść mieszaną.

Jak dodać grę na stronie WordPressa?

Proszę wgrać folder menedżerem plików hostingu lub FTP, otworzyć jego adres, by potwierdzić, że gra działa, a potem dodać iframe w bloku Własny HTML. Użytkownikom bez uprawnienia unfiltered_html iframe są usuwane, więc proszę sprawdzić rolę osoby edytującej stronę.

Gdzie zapisywany jest postęp i co, jeśli gracze wyczyszczą dane przeglądarki?

W pamięci lokalnej przeglądarki, dla danego adresu. Wyczyszczenie danych witryny go kasuje, inna przeglądarka lub urządzenie zaczyna od zera, a zmiana domeny lub przełączenie między http i https go resetuje. Nie ma kont i nic nie jest wysyłane do nas.

Czy Polar Games hostuje dla mnie grę?

Nie. Sklep sprzedaje pliki. Wsparcie obejmuje pytania dotyczące instalacji i używania; hosting i instalacja na Państwa serwerze są osobnymi usługami, które wyceniamy przed rozpoczęciem pracy.

Następny krok

Jeśli nadal wybierają Państwo gry HTML5 na swoją stronę, strona każdego produktu podaje wymagania, linkuje podręcznik i pozwala zagrać w demo przed zapłatą. Proszę najpierw przeczytać rozdział instalacyjny podręcznika: to strona, z której skorzystają Państwo przy zadaniu opisanym w tym poradniku.

Przeglądaj szablony gier HTML5