De interface van de Metin2-client is volledig in Python geschreven, en als je die vensters rond je eigen server wilt vormgeven, begint het werk bij de metin2 root python-bestanden. Je hoeft de engine niet aan te raken om de inventaris te verplaatsen, het chatvenster te vergroten of een nieuwe knop toe te voegen — je hoeft alleen het juiste .py-bestand te vinden en een verstandige aanpassing te maken. In dit artikel loop ik met je door hoe het root-pakket werkt, hoe je de bestanden opent en bewerkt, en hoe je je wijzigingen in de client test.
Het root-pakket en de UI-architectuur
De client stelt zijn interface samen uit drie afzonderlijke delen, en zonder die opdeling te begrijpen raak je verdwaald in de berg bestanden:
- root — De eigenlijke Python-logica staat hier.
ui.pydefinieert het UI-raamwerk (klassen zoals Window, Board, Button, TextLine), terwijl bestanden alsuiInventory.py,uiCharacter.py,uiChat.pyeninterfaceModule.pyhet gedrag van elk venster regelen. - uiscript — Hier wordt de indeling van de vensters bewaard. Bestanden als
inventorywindow.pyzijn geen HTML; ze beschrijven de geometrie als een Python-dictionary: coördinaten, breedte, hoogte en onderliggende elementen. - locale — Teksten en taalafhankelijke instellingen (
locale_string.txten sommige labels inuiscript) staan hier.
Dus hoe een venster eruitziet wordt grotendeels in uiscript bepaald, terwijl hoe het zich gedraagt in root staat. Voor de meeste visuele aanpassingen is alleen uiscript bewerken voldoende.
De bestanden uitpakken en een bewerkomgeving opzetten
De client bewaart deze bestanden in versleutelde pakketten: root.epk / root.eix en uiscript.epk / uiscript.eix. Om ze te bewerken moet je ze eerst uitpakken:
- Gebruik een tool als EterNexus om uit te pakken en weer in te pakken. Als je het
.eix-bestand opent, kun je de mappenstructuur eruit halen. - De bestanden komen meestal als gecompileerde
.pyc. Heb je de bron-.pyniet, dan heb je een Python 2-decompiler nodig (bijvoorbeelduncompyle2) om ze terug te zetten. Omdat de client op Python 2.2 draait, werken moderne Python 3-tools vaak niet. - Veel privéservers stellen de client zo in dat hij uit losse mappen leest in plaats van pakketten, voor eenvoudiger ontwikkelen. Is dat beschikbaar, dan kun je de root- en uiscript-mappen rechtstreeks bewerken en de inpakstap overslaan.
Elke editor met syntaxiskleuring (VS Code, Notepad++) voldoet. Sla de bestanden op in de codering die de client verwacht en vermijd het mengen van tabs en spaties in de inspringing — Python is gevoelig voor inspringing.
De indeling van een venster wijzigen met uiscript
De meest voorkomende taak is een venster verplaatsen of van grootte veranderen. Het bestand uiscript/inventorywindow.py heeft ongeveer deze structuur:
window = {
"name" : "InventoryWindow",
"x" : SCREEN_WIDTH - 176,
"y" : SCREEN_HEIGHT - 37 - 565,
"style" : ("movable", "float",),
"width" : 176,
"height" : 565,
"children" : (
{
"name" : "board",
"type" : "board",
"x" : 0,
"y" : 0,
"width" : 176,
"height" : 565,
"children" : (
# titel, tabbladen, vakjes...
),
},
),
}
Om het venster naar links te schuiven, wijzig je de "x"-waarde; om het breder te maken, wijzig je "width". Onthoud: als je de breedte van het buitenste venster vergroot, moet je ook de breedte van het binnenste board-element aanpassen, anders loopt de achtergrondafbeelding over. Met de constanten SCREEN_WIDTH en SCREEN_HEIGHT kun je het venster aan een schermhoek verankeren; ze gebruiken in plaats van vaste getallen houdt alles correct bij verschillende resoluties.
De logica binnen root bewerken
Als de indeling niet genoeg is, wijzig je het gedrag aan de root-kant. Zo laadt uiInventory.py het indelingsbestand als volgt:
import ui
import uiScriptLocale
class InventoryWindow(ui.ScriptWindow):
def __LoadWindow(self):
pyScrLoader = ui.PythonScriptLoader()
pyScrLoader.LoadScriptFile(self, "uiscript/inventorywindow.py")
self.wndItem = self.GetChild("ItemSlot")
# ... verwijzingen naar elementen
De naam in de GetChild-aanroep moet exact overeenkomen met het "name"-veld in het uiscript-bestand. Heb je een nieuwe knop toegevoegd, dan definieer je die eerst in uiscript, pak je hem aan de root-kant met GetChild("NieuweKnop") en koppel je hem aan een functie via SetEvent. Komen de namen niet overeen, dan geeft de client None terug en crasht hij meestal met een 'NoneType' object has no attribute ...-fout.
ui.py aanraken is geavanceerd werk: omdat alle vensters dit raamwerk delen, raakt één fout hier de hele interface. Tenzij je echt een nieuw componenttype nodig hebt, laat je ui.py zoals het is.
Inpakken, caching en debuggen
Als je klaar bent met bewerken, pak je de bestanden weer in (of, in de losse-mapmodus, sla je gewoon op) en start je de client opnieuw. Een paar praktische punten:
- De client kan oude pakketten cachen; om zeker te zijn, werk je zowel het
.epk- als het.eix-bestand samen bij. - Werkt iets niet, dan is de eerste plek om te kijken het bestand
syserr.txtin de clientmap. Python-uitzonderingen, met het foutieve regelnummer, worden daar weggeschreven. - Veelvoorkomende fouten: inspringingsmismatch (
IndentationError), een niet-gesloten haakje, of een ontbrekende komma in een uiscript-dict. Vergeet in Python-dictionaries de afsluitende komma na elk element niet.
Veelgemaakte fouten en tips
- Maak een back-up van het origineel. Kopieer voor je begint de root- en uiscript-pakketten, zodat terugdraaien seconden kost, geen minuten.
- Eén wijziging tegelijk. Bewerk niet tien bestanden en test dan pas; de bug zoeken wordt een marteling.
- Naamconsistentie is alles. De
"name"in uiscript en deGetChildin root moeten identiek geschreven zijn; zelfs hoofdletters tellen. - Denk aan de resolutie. Gebruik
SCREEN_WIDTH/SCREEN_HEIGHTin plaats van vaste coördinaten, zodat het venster ook op brede schermen op zijn plaats blijft.
Veelgestelde vragen
De root-bestanden komen als .pyc — hoe kom ik aan de bron?
Veel bestanden worden als gecompileerde .pyc verspreid. Een Python 2-decompiler (zoals uncompyle2) kan ze omzetten naar leesbare .py. Sommige community-releases delen al schone bron; werk indien mogelijk rechtstreeks met de bron in plaats van te decompileren.
Ik wil alleen een venster verplaatsen — moet ik root aanraken?
Nee. Positie, grootte en de indeling van onderliggende elementen zitten volledig aan de uiscript-kant. Zolang je geen knopgedrag wijzigt, events koppelt of nieuwe logica toevoegt, hoef je de root-bestanden nooit te openen.
Mijn wijziging verschijnt niet in de client — waarom?
Meestal is óf het pakket niet bijgewerkt (vernieuw het .eix/.epk-paar samen), óf er is een Python-fout. Kijk eerst in syserr.txt; daar vind je het probleem vaak met het exacte regelnummer.
Wil je de interface helemaal opnieuw rond je eigen server ontwerpen? Heb je hulp nodig bij Metin2-clientaanpassing, root-bewerking of een UI-ontwerp op maat, neem dan contact met me op — laten we je project samen tot leven brengen.