Wanneer je voor het eerst een Metin2-server opzet, is het meest verwarrende onderwerp de Metin2 channelstructuur: de lijst "Channel 1, Channel 2, Channel 3" die de speler ziet, wordt op de achtergrond eigenlijk door hoeveel processen bediend, welke map draait op welke core, en hoe worden de poorten verdeeld? In dit artikel leg ik het verschil tussen een channel en een core uit, de rol van de auth- en db-server, en de poortindeling van een klassieke multi-channelserver met praktische voorbeelden.
Het verschil tussen een channel en een core
Veel mensen denken dat een "channel" en een "core" hetzelfde zijn, maar het zijn verschillende lagen. Een channel is een logische verdeling die de speler op het selectiescherm ziet: zie het als meerdere kopieën van dezelfde wereld om de belasting te spreiden. Elk channel bevat alle maps (dorpen, jachtgebieden, dungeons).
Een core binnen een channel is daarentegen een apart proces dat een deelverzameling van de maps draait. Eén enkel game-proces draagt niet alle maps; de maps worden over de cores verdeeld. Heeft een channel bijvoorbeeld vier cores, dan kunnen de startdorpen op core1 draaien, de jachtgebieden van middenniveau op core2, en de high-level maps en dungeons op core3 en core4. Wanneer een speler tussen maps beweegt, vindt er een overdracht tussen cores plaats, maar de speler merkt dit nooit.
De rol van de auth- en db-server
Een multi-channelopstelling heeft twee centrale onderdelen:
- auth: de server die accountlogins valideert. De client verbindt hier eerst mee, de gebruikersnaam/wachtwoord wordt gecontroleerd en er wordt een sessietoken aangemaakt. De auth is meestal een toegewijd game-proces dat op zijn eigen poort draait met een eigen
CONFIG-bestand. - db: de databasecacheserver waarmee alle cores gezamenlijk verbinden. Gegevens zoals personages, inventaris en gildes leven in MySQL, maar de cores praten er niet rechtstreeks mee — ze gaan via het db-proces. Zo blijven de gegevens gesynchroniseerd, zodat het personage van een speler consistent blijft bij het overgaan van de ene core naar de andere.
De verbindingsketen ziet er dus zo uit: client → auth (login) → de core van het gekozen channel → en alle cores op de achtergrond → db → MySQL. Er is altijd maar één auth- en één db-server; de cores zijn het gerepliceerde deel.
Poortlogica en CONFIG
Elke core wordt gestart met een CONFIG-bestand in zijn eigen map, dat definieert op welke poort hij luistert, tot welk channel hij behoort en welke P2P-poort hij gebruikt voor communicatie tussen cores. Een consistent poortschema maakt het leven veel makkelijker. Een gangbare conventie is:
- Cores van channel 1: 13001, 13002, 13003, 13004
- Cores van channel 2: 13011, 13012, 13013, 13014
- Cores van channel 3: 13021, 13022, 13023, 13024
- auth: een aparte poort zoals 11002 — db: een aparte poort zoals 15000
Wat telt, is dat het schema niet botst en logisch blijft; de getallen zelf zijn willekeurig. Een typisch core-CONFIG-bestand ziet er grofweg zo uit:
HOSTNAME: channel1
CHANNEL: 1
BIND_IP: 0.0.0.0
PORT: 13001
P2P_PORT: 13991
PLAYER_SQL: localhost player root wachtwoord
COMMON_SQL: localhost common root wachtwoord
LOG_SQL: localhost log root wachtwoord
TABLEPOSTFIX: _
DB_ADDR: 127.0.0.1
DB_PORT: 15000
Hier is PORT de gamepoort waarmee spelers verbinden, terwijl P2P_PORT wordt gebruikt om met de andere cores in hetzelfde channel te praten. DB_ADDR en DB_PORT vertellen de core hoe hij het db-proces bereikt. De CONFIG van het auth-proces draagt daarnaast een instelling die het als authenticatieserver markeert en wordt meestal met een speciaal channelnummer (bijvoorbeeld 99) uitgevoerd.
Maps over cores verdelen
Welke maps een core laadt, wordt bepaald door de mappenlijst aan de serverkant. Elke core laadt alleen de mapmappen die eraan zijn toegewezen; niet-toegewezen maps gelden als "extern" voor die core. Wanneer een speler een map betreedt die niet op een bepaalde core staat, wordt hij via de P2P-verbinding overgedragen naar de core die die map host. Let bij het plannen van de verdeling op twee dingen:
- Belastingsbalans: stapel de drukste jachtgebieden niet op één core; verdeel de spelerdichtheid over de cores.
- Consistentie: wijs dezelfde map nooit aan twee verschillende cores toe. Elke map moet op precies één core draaien, anders breekt de overdracht.
In de praktijk krijgen de startdorpen en de constant drukke hoofdpleinen meestal hun eigen core, zodat een menigte in één jachtgebied de prestaties van de stad niet beïnvloedt.
Opstartvolgorde en procesbeheer
De opstartvolgorde van de serverprocessen is belangrijk, omdat cores bij het opstarten proberen met db te verbinden. De juiste volgorde is:
- De MySQL-service (database) moet draaien.
- Het db-proces wordt gestart.
- Het auth-proces wordt gestart.
- De cores van de channels worden één voor één gestart.
Omdat de processen handmatig volgen vermoeiend is, gebruiken de meeste beheerders een eenvoudig opstartscript. Een voorbeeld van een controlescript-aanpak:
#!/bin/sh
# elke core wordt vanuit zijn eigen map gestart
for dir in db auth ch1_core1 ch1_core2 ch1_core3 ch1_core4; do
cd "/usr/metin2/$dir" && ./game &
done
Wanneer een core crasht, laat hij meestal een core dump (een core-bestand) achter; je kunt dit met gdb inspecteren om te zien in welke functie hij ontplofte. Daarom is het draaien van de cores onder screen of een servicemanager en het apart houden van de logs een redding wanneer er iets misgaat.
Hoeveel cores heb je nodig?
Daar is geen vast antwoord op; het hangt af van het aantal spelers en de hardware. Omdat elk game-proces grotendeels single-threaded draait, kun je door het aantal cores op een multi-core server te verhogen de CPU beter benutten. Een algemeen startpunt: voor een kleine server zijn 2 cores per channel genoeg, terwijl een drukke server baat heeft bij 4 cores per channel en meer dan één channel. Begin met 1 channel + 2 cores en voeg channels en cores toe naarmate de spelersbasis groeit.
Veelgestelde vragen
Kan ik het aantal channels later verhogen?
Ja. Een nieuw channel toevoegen komt neer op het maken van CONFIG-bestanden voor de cores van dat channel, het toewijzen van niet-botsende poorten en het bijwerken van de serverlijst die de client ziet. Omdat de database gedeeld blijft, zijn de personages identiek op alle channels.
Kunnen spelers kiezen op welk channel ze zitten?
Ja, na het inloggen kiest de speler uit de channellijst. Omdat channels dezelfde wereld delen, veranderen personages en items niet; alleen op welke kopie van de server je op dat moment speelt, verandert. Dit is de belangrijkste manier om de belasting tijdens piekuren te spreiden.
Kan ik auth en db samenvoegen tot één proces?
Architecturaal is het juist, en aanbevolen, om ze gescheiden te houden. db is de gedeelde datalaag voor alle cores, terwijl auth alleen de login afhandelt; door de twee apart te houden krijg je een veel beter beheersbare structuur, zowel voor beveiliging als voor debuggen.
Wil je de architectuur van een multi-channel Metin2-server goed opzetten? Voor coreverdeling, een poortschema en een stabiele opstartindeling, neem contact met me op — laten we je opzet samen plannen.