Hostowanie resource packa dla serwera Minecraft: kompletny przewodnik (2026)
Jesli twoj serwer ma customowe modele przez ItemsAdder albo Oraxen, wlasny font, tlumaczenia na cztery jezyki albo po prostu vanilla pack z lore-teksturami, predzej czy pozniej trafisz na to samo pytanie: gdzie ten zip ma lezec, zeby klient sciagal go szybko, bez zerwan i bez Failed to download resource pack. W tym przewodniku przechodzimy po tym, jak poprawnie hostowac packa, jak wygenerowac sha1, jakie klucze w server.properties dziala na 1.21+ i czemu Discord CDN wypadl z gry pod koniec 2024 roku.
Czemu hostowac packa samemu, a nie przez plugin
Minecraft 1.20.3+ potrafi wyslac klientowi nawet piecdziesiat resource packow przez API serwera, ale samo bundle z teksturami nigdy nie idzie przez polaczenie Minecrafta. Vanillowy klient otwiera zwykly HTTPS GET na URL z resource-pack= (albo URL od plugina) i ciagnie zip bezposrednio. Serwer Minecrafta nie bierze udzialu w tej wymianie: nie obchodzi go, czy pack lezy obok jara czy na innym kontynencie, wazne zeby URL odpowiedzial i hash sie zgadzal.
Z tego wynika prosta zasada: predkosc i stabilnosc downloadu packa nie maja nic wspolnego z twoim hostingiem Minecrafta, tylko z tym gdzie lezy zip. Jezeli pack jest serwowany z taniej amerykanskiej VPS na 100 Mbps, gracz z Polski na zwyklej domowej linii czeka 30 sekund tylko na ciagnieciu liny, a kazdy malenki problem TCP konczy sie timeoutem. Polozenie packa za normalnym CDN (Cloudflare, Bunny, R2) sprawia, ze ten sam download konczy sie w 2-3 sekundy niezaleznie od regionu.
Drugi punkt: force-resource-pack=true plus poprawny resource-pack-sha1 to klucz do tego, zeby klient albo automatycznie zaakceptowal packa, albo czysto wywalil sie na Failed to apply resource pack. Bez sha1 klient sciaga packa za kazdym razem na join, czyli marnujemy ruch lub sekundy po stronie gracza. Z dobrym sha1 klient cachuje archiwum po pierwszym pobraniu i przy nastepnym wejsciu po prostu wyciaga je z dysku.
Przygotowanie packa: pack.mcmeta, format, zip
Zanim cokolwiek hostuje, sprawdz strukture packa. Bazowy uklad dla Minecraft 1.21+:
my-pack/
pack.mcmeta
pack.png
assets/
minecraft/
textures/
models/
lang/
sounds/
pack.mcmeta dla 1.21.4 (Java Edition) niesie pack_format. Kazda wersja klienta ma swoj numer, aktualna tabela jest na minecraft.wiki w artykule Pack format. Stan na srodek 2025: 1.21.4 to pack_format 46, a 1.21 to 34. Zly numer nie wywala bledu, klient po prostu po cichu nie laduje czesci tekstur.
{
"pack": {
"pack_format": 46,
"supported_formats": [34, 46],
"description": "MyServer textures 1.21+"
},
"language": {
"pl_pl": {"name": "Polski", "region": "Poland", "bidirectional": false}
}
}
supported_formats pozwala klientom roznych wersji akceptowac to samo archiwum, a language jest istotne tylko jak wrzucasz wlasne lang/pl_pl.json na vanilla. Nie zapomnij pack.png (64x64 albo 128x128, zwykly PNG); klient pokazuje go w liscie.
Budowa archiwum. Trick: zipuje sie zawartosc, nie folder:
cd my-pack
zip -r -9 ../my-pack.zip . -x "*.DS_Store" -x ".*"
Walidacja: unzip -l my-pack.zip | head powinno pokazac pack.mcmeta i assets/ na samej gorze, bez wrappera my-pack/. Jesli wewnatrz jest dodatkowy folder, klient krzyczy Couldn't load resource pack: invalid pack format.
Generowanie sha1: sha1sum i narzedzia online
Minecraft sprawdza dokladnie SHA-1 z bajtow zip, bez soli, bez sztuczek. Linux/macOS:
sha1sum my-pack.zip
8f3a9c1d4e2b6f7a8d9e0f1a2b3c4d5e6f708192 my-pack.zip
Windows w PowerShell:
Get-FileHash -Algorithm SHA1 .\my-pack.zip
Hash w server.properties musi byc lowercase, inaczej vanillowy klient wywala pack hash mismatch. Jesli edytujesz plik recznie, kopiuj wynik sha1sum jeden do jednego. Jezeli automatyzujesz update packa, dodaj krok do CI:
HASH=$(sha1sum my-pack.zip | awk '{print $1}')
echo "resource-pack-sha1=${HASH}" > .env.pack
.env.pack jest potem podlozone w twojem szablonie server.properties przy deployu.
Opcja 1: GitHub raw
Najtanszy i najprostszy sposob, zwlaszcza jak pack juz jest w gicie. Tworzysz publiczne repo, wrzucasz my-pack.zip, bierzesz raw URL:
https://raw.githubusercontent.com/<user>/<repo>/main/my-pack.zip
Plusy: za darmo, wersjonowanie przez tagi i commity, prosty rollback. Minusy i pulapki:
- GitHub oficjalnie nie poleca raw jako CDN dla binariow. Jak twoj pack pobiera sie tysiace razy na godzine, mozesz dostac rate limit, a w skrajnych przypadkach konto trafi do flagi.
- Jeden plik w zwyklym repo to limit okolo 100 MB; wieksze packi potrzebuja Git LFS, a LFS ma swoj URL i swoje limity transferu.
- Latencja srednia. raw.githubusercontent.com idzie przez GitHuba i Fastly, dla wiekszosci regionow ok, ale rzadko najszybciej.
Kiedy pasuje: maly serwer, pack do 20 MB, mniej niz 100-200 graczy online.
Opcja 2: Mc-Packs.net
Serwis dedykowany pod resource packi do serwerow. Wrzucasz zip przez formularz na mc-packs.net, dostajesz bezposredni URL plus policzony sha1. Maja API zeby rotowac ten sam URL przy update.
Plusy: za darmo, brak wlasnej infry, sha1 gotowy do skopiowania. Minusy: zalezysz od cudzego serwisu; jak ich box rzezni, pack przestaje sie ladowac, a ty dowiadujesz sie z czatu. Free tier bez SLA, bez gwarancji ze link bedzie zyl za rok.
Kiedy pasuje: serwer testowy, mala produkcja albo backup mirror dla glownego hosta.
Opcja 3: Cloudflare R2
R2 to S3-kompatybilny obiektowy storage od Cloudflare bez oplat za egress (kluczowa roznica wzgledem AWS S3). Storage kosztuje grosze, downloady graczy nic. Dokumentacja na developers.cloudflare.com/r2.
Bazowy flow:
- Tworzysz bucket w R2.
- Wrzucasz zip przez
rclonealboaws s3 cpz endpointem R2. - Bindujesz publiczna domene (
packs.example.net) do bucketu w R2 settings. - Ustawiasz Cache-Control:
public, max-age=31536000, immutablena zipie, zeby klienci i edge Cloudflare nie szli ponownie po origin.
Wrzucanie przez rclone:
rclone copy ./my-pack.zip r2:my-bucket/ --header-upload "Cache-Control: public,max-age=31536000,immutable"
URL do server.properties:
https://packs.example.net/my-pack-v12.zip
Zwroc uwage na -v12 w nazwie. To celowe: zamiast walczyc z inwalidacja cache, kazda nowa wersja packa dostaje nowa nazwe pliku, sha1 sie zmienia, gracze ciagna nowy plik, cache dziala czysto. Na R2 za darmo, na innych CDN tez best practice.
Plusy R2: anycast Cloudflare, brak egress billingu, natywna integracja z cache CF, prosta publiczna domena. Minusy: jednorazowa konfiguracja z API Cloudflare i rclone, ale robisz to raz.
Opcja 4: Self-hosted nginx albo Caddy
Jezeli juz prowadzisz VPS albo dedyk pod strone serwera, hostuj statyki tam. Minimalny nginx:
server {
listen 443 ssl http2;
server_name packs.example.net;
ssl_certificate /etc/letsencrypt/live/packs.example.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/packs.example.net/privkey.pem;
root /var/www/packs;
location ~* \.zip$ {
add_header Cache-Control "public, max-age=31536000, immutable";
add_header Access-Control-Allow-Origin "*";
sendfile on;
tcp_nopush on;
}
}
Caddy jeszcze krocej:
packs.example.net {
root * /var/www/packs
file_server
header /*.zip Cache-Control "public, max-age=31536000, immutable"
}
Plusy: pelna kontrola, prawie zerowa latencja jak host packa i host serwera siedza w tym samym DC. Minusy: ty odpowiadasz za uptime, backupy i lacze. Z 100 Mbps i 200 graczami od razu po restarcie lacze sie nasyca na 30 sekund i ktos zlapie timeout.
Sensowny default: postaw Cloudflare w trybie proxy (pomaranczowa chmura) przed wlasnym nginxem. Dostajesz darmowe edge caching, a spike rozprasza sie na edge.
Discord CDN: czemu NIE
Przez lata adminzy wrzucali zip w prywatny kanal Discorda i kopiowali URL do server.properties. Dzialalo wieki, i do konca 2023 te URLe byly stale.
Pod koniec 2023 Discord wyrolowal podpisane tymczasowe URLe (?ex=...&is=...&hm=...), a wiosna 2024 stalo sie to standardem dla wszystkich attachmentow. Podpis wygasa po okolo 24 godzinach. Czyli jak dzisiaj wrzucisz taki URL, jutro twoi gracze widza Failed to download resource pack. Sztuczki z botem rotujacym podpis tez nie ratuja; ToS Discorda wprost zakazuje uzywania ich CDN jako hostingu pod inne projekty.
Wniosek: Discord CDN umarl dla resource packow. Jesli twoja server.properties dzisiaj wskazuje na cdn.discordapp.com/..., przeskocz na ktorakolwiek opcje powyzej zanim chat zacznie krzyczec.
Konfig server.properties
Na Paper/Spigot/Folia 1.21+ kluczowe sa te opcje:
resource-pack=https://packs.example.net/my-pack-v12.zip
resource-pack-sha1=8f3a9c1d4e2b6f7a8d9e0f1a2b3c4d5e6f708192
require-resource-pack=true
resource-pack-prompt=Required textures for the server
Co warto wiedziec:
resource-pack-sha1to wlasciwa nazwa klucza, nieresource-pack-hash, niesha-1. Udokumentowane na minecraft.wiki w sekcji Server.properties.require-resource-pack=trueto nowoczesny odpowiednik staregoforce-resource-pack. Jak gracz odmowi, serwer kickuje go z wiadomoscia zresource-pack-prompt(albo defaultowa, jak prompt pusty).- 1.20.3 i starsze mialy limit 224 znakow na URL. 1.20.3+ limit usunal, ale trzymaj sie pod 1024 znakami; niektore launchery i mody jeszcze obcinaja.
resource-pack-promptprzyjmuje prosty JSON text component, mozesz kolorowac i tlumaczyc.
Po edycji server.properties musisz zrestartowac serwer; hot-reload tych kluczy nie dziala.
Per-player packi: ItemsAdder, Oraxen, force-resource-pack pluginy
Przez server.properties mozesz wyslac jeden pack. W 1.20.3+ serwerowe API moze pchnac do piecdziesieciu packow na sesje, i kazdy duzy plugin do customowych itemow z tego korzysta.
ItemsAdder i Oraxen same hostuja packa: instalujesz plugin, on generuje zip, podnosi wbudowany HTTP serwer (albo oddaje twojemu nginxowi) i wysyla graczowi przez ProtocolLib lub Paper API. Twoja jedyna robota to upewnic sie, ze port nasluchu jest dostepny z internetu, a nie tylko z LAN.
Jak chcesz wlasnego packa na gorze, sa pluginy typu ResourcePackHost lub ForceResourcePack ktore na PlayerJoinEvent wysylaja pack przez Player#setResourcePack(url, sha1). Maja zwykle takze opcje per-permission lub per-world: lobby pack na hubie, survival pack na serwerze rozgrywki.
Specjalny przypadek: BungeeCord/Velocity. Na proxy nie ma server.properties, pack idzie albo przez Velocity API, albo przez plugin na backendzie. Wiekszosc setupow idzie druga droga, bo to daje punkt kontroli per serwer.
Wielojezykowe packi
Jesli masz serwer z tlumaczeniami ru/en/de, masz dwie drogi: jeden duzy pack z folderami lang/ na wszystkie jezyki (klient sam wybiera odpowiedni na podstawie ustawien), albo kilka packow i dystrybucja per gracz przez plugin i locale.
Vanilla droga jest czystsza: assets/minecraft/lang/ru_ru.json, en_us.json, de_de.json w jednym zipie, w pack.mcmeta w sekcji language. Archiwum prawie nie rosnie (lang to JSONy 50-200 KB), a wszystko dziala bez plugina.
Jesli packi mocno rozjezdzaja sie (Halloween-tekstury tylko dla ru klientow), to routing per locale przez plugin z Player#getLocale().
Tabela opcji hostingu
| Sposob | Koszt | Predkosc | Limity | Kiedy brac |
|---|---|---|---|---|
| GitHub raw | za darmo | sredni | 100 MB plik, soft rate-limit | maly serwer, pack do 20 MB |
| Mc-Packs.net | za darmo | sredni | brak SLA, cudza infra | test, mirror, mala prod |
| Cloudflare R2 | grosze/mc | wysoki (anycast) | egress free, dowolny rozmiar bucketu | srednia/duza prod |
| Nginx/Caddy | koszt VPS | zalezy od lacza | twoj uptime, twoje backupy | juz masz VPS |
| Klasyczny S3 | $$$ za egress | wysoki | egress zabija budget | juz na AWS |
| Discord CDN | za darmo | krotko | URL umiera w 24h | nigdy |
Debugging: pack sie nie laduje
Symptomy i gdzie kopac:
-
Failed to download resource pack. Sprawdzic URL recznie przezcurl -I. Jak 200 OK i sensowne Content-Type (application/zip albo application/octet-stream), idziesz dalej. 403 znaczy ze CDN cie blokuje, sprawdz reguly. Timeout znaczy URL nie rozwiazuje sie z obcego boxa; fixuj DNS lub firewall. -
Pack hash mismatch. W 99% to mismatch sha1 miedzyserver.propertiesa samym plikiem. Przeliczyc przezsha1sum, wkleic dokladnie, restart serwera. -
Gracze mowia, ze pack sciaga sie, ale tekstury sie nie aplikuja. Sprawdz
pack_formatwpack.mcmeta, prawdopodobnie nie pasuje do wersji klienta. Dodajsupported_formatsjako tablice. -
Couldn't load resource pack: invalid pack format. W zipie jest dodatkowy folder-wrapper. Przepakuj przezcd my-pack && zip -r ../my-pack.zip ., niezip -r my-pack.zip my-pack/. -
Custom CA. Jak pack siedzi za samopodpisanym TLS, vanillowy klient odmawia. Lecisz na Let's Encrypt, ZeroSSL albo inne publiczne CA.
Wersjonowanie bez bolu
Najczestszy bug przy update packa: podmieniles zip na tym samym URL, odswiezeles sha1 w configu, zrestartowales serwer, ale czesc graczy wciaz laduje stary pack z cache. Cache jest po URL, nie po zawartosci.
Fix: kazda nowa wersja packa dostaje nowa nazwe pliku. Zamiast pack.zip, lec pack-v1.zip, pack-v2.zip. Zadnej inwalidacji cache, zadnego Cache-Control: no-cache, swiezy gracz ciagnie aktualnego builda. Stare pliki mozna wywalic za tydzien-dwa, jak wszyscy nadgonia.
Ten sam trick rozwiazuje dlugi cache CDN: edge Cloudflare lub Bunny moze trzymac plik dniami, a ty wgrales nowego builda piec minut temu. Wersjonowane nazwy omijaja konflikt zupelnie.
FAQ
Czy moge serwowac packa po HTTP bez TLS? Technicznie tak, vanilla klient akceptuje http://. W praktyce nie: niektore sieci firmowe i dostawcy filtruja nieznane HTTP hosty, a Let's Encrypt jest darmowy i instaluje sie dwoma komendami.
Co z packiem 200 MB? Klient zaakceptuje, ale rozwaz podzial na base + addon i wysylke drugiego kawalka przez API ItemsAdder/Oraxen. Duzy zip to dlugi download na mobile i wieksza szansa na zerwanie polaczenia.
Czemu immutable w Cache-Control?
Mowi przegladarce/klientowi, ze ten URL nigdy sie nie zmieni. Z wersjonowana nazwa (pack-v12.zip) to prawda, i klient przestaje wysylac requesty rewalidacyjne.
SHA-1 jest zlamany, czy moge SHA-256?
Mozesz, od Minecraft 1.20.3+ przez API serwera w Player#setResourcePack z parametrem hash, ale pole w server.properties nadal nazywa sie resource-pack-sha1. Sila kryptograficzna nie jest tu istotna, hash to tylko check integralnosci i klucz cache.
Co z packami Bedrock?
Bedrock dziala inaczej: pack idzie przez sam protokol Minecrafta, bez HTTP. Przy crossplay przez Geyser/Floodgate customowe packi Bedrock leza osobno w folderach behavior_packs i resource_packs swiata.
Czy moge serwowac packa wprost z serwera Minecraft? Technicznie tak, plugin Paper moze podniesc maly web serwer. W praktyce nie: ruch packa walczy z ruchem graczy o to samo lacze, a tickrate cierpi pod obciazeniem. Trzymaj pack na osobnym hoscie albo CDN.
Kiedy pack jest serwowany z CDN z poprawnym sha1, wersjonowanymi nazwami i sensownym Cache-Control, historia downloadu przestaje byc problemem. Gracze dostaja tekstury w pare sekund, cache dziala transparentnie, a przy update po prostu wgrywasz nowy plik z nowa nazwa i podstawiasz swiezy hash w configu.
Chroń swój serwer przed atakami DDoS
Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.
Wypróbuj za darmoPowiązane artykuły
Multiverse-Core: wiele światów na jednym serwerze Minecraft
Pełny przewodnik po Multiverse-Core: instalacja, komendy, bloki portali, rozdzielone ekwipunki, generatory i prawdziwe pułapki wydajności.
Vanilla Tweaks: najlepsze datapacki na serwer SMP w 2026
Najlepsze datapacki Vanilla Tweaks na SMP w 2026: Graves, Multiplayer Sleep, Anti Creeper Grief, instalacja i kompatybilność z pluginami.
Ile RAM potrzeba dla serwera Minecraft
Praktyczny przewodnik po doborze pamięci RAM dla serwera Minecraft: podstawowe wymagania, obliczenie RAM na gracza, porównanie Paper/Forge/Fabric, flagi Aikar, działanie garbage collectora G1GC i monitoring przez spark.