aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Metin2

Build a Metin2 Database Site (Item & Mob Proto)

A Metin2 database site turns the game's item and monster data into a web wiki that visitors can search and filter. Players can answer questions like "where does this item drop?", "what level is this mob?" or "what bonuses does this costume give?" without logging in. In this guide I walk through taking item_proto and mob_proto data, importing it into a clean web database, and building a fast, searchable database site step by step.

Understanding the data sources: proto files

In Metin2, every item and monster the game knows about is defined in two main structures: item_proto and mob_proto. On most servers these exist as both binary item_proto/mob_proto files and plain-text sources:

  • item_proto / item_names.txt — each item's vnum, type (weapon, armor, costume, potion…), subtype, value0–5 fields, bonuses (applies), price and names.
  • mob_proto / mob_names.txt — each monster's vnum, level, rank (pawn/boss/king…), HP/attack values, experience and names.
  • item_names.txt and mob_names.txt — vnum → localized name mapping. For a multilingual wiki these files are critical.

The cleanest path for a website is to import this data into a separate wiki database without touching the live player tables. That way you can build whatever schema you want without ever loading the game server.

Importing the data into a web database

Many servers also keep proto data in MySQL (for example a player.item_proto table). If you only have plain-text files, the healthiest approach is a small import script that parses them once and writes to your own wiki tables. Let's start with a simple schema:

CREATE TABLE wiki_items (
  vnum      INT UNSIGNED PRIMARY KEY,
  name      VARCHAR(64) NOT NULL,
  type      VARCHAR(32) NOT NULL,
  subtype   VARCHAR(32) NULL,
  level     SMALLINT UNSIGNED DEFAULT 0,
  price     INT UNSIGNED DEFAULT 0,
  KEY idx_name (name),
  KEY idx_type (type)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE wiki_mobs (
  vnum  INT UNSIGNED PRIMARY KEY,
  name  VARCHAR(64) NOT NULL,
  level SMALLINT UNSIGNED DEFAULT 0,
  rank  VARCHAR(16) NULL,
  exp   INT UNSIGNED DEFAULT 0,
  KEY idx_name (name),
  KEY idx_level (level)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Storing bonus fields (apply types and values) in a separate wiki_item_attrs table as rows linked by vnum makes future searches like "all items with attack power +X" possible.

Parsing the tab-separated proto

Files like item_names.txt are usually tab-separated columns with a header row. A safe import in PHP looks like this:

<?php
$fh = fopen('item_names.txt', 'r');
fgets($fh); // skip the header line

$stmt = $pdo->prepare(
  "INSERT INTO wiki_items (vnum, name, type)
   VALUES (:vnum, :name, :type)
   ON DUPLICATE KEY UPDATE name = VALUES(name)"
);

while (($line = fgets($fh)) !== false) {
    $cols = explode("\t", trim($line));
    if (count($cols) < 2) continue;
    $stmt->execute([
        ':vnum' => (int) $cols[0],
        ':name' => $cols[1],
        ':type' => 'unknown',
    ]);
}
fclose($fh);

You can read type and bonus information from item_proto and update the same row. Using ON DUPLICATE KEY UPDATE lets you re-run the import after a game update to refresh the data without wiping it each time.

The search and filter API

The heart of a Metin2 database site is search. Let's build an endpoint that returns matching items and mobs when the user types part of a name. Never embed user input directly into the query; bind it as a parameter with a prepared statement:

<?php
$q = trim($_GET['q'] ?? '');
$type = $_GET['type'] ?? null;

$sql = "SELECT vnum, name, type, level FROM wiki_items WHERE name LIKE :q";
$params = [':q' => '%' . $q . '%'];

if ($type) {
    $sql .= " AND type = :type";
    $params[':type'] = $type;
}
$sql .= " ORDER BY level DESC, name ASC LIMIT 50";

$stmt = $pdo->prepare($sql);
$stmt->execute($params);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($stmt->fetchAll());

For very large item sets, name LIKE '%...%' can get slow. As the site grows, consider a MySQL FULLTEXT index or a search engine (like Meilisearch); but for a few thousand rows an indexed LIKE is more than enough.

Building the drop relationship: "where does it drop?"

The information players search for most is which monster drops an item. Drop data lives on the server in sources like mob_drop_item.txt, common_drop_item.txt and drop_item_group. If you import this relationship into a table linking mob vnum to item vnum, you unlock two-way queries:

CREATE TABLE wiki_drops (
  mob_vnum  INT UNSIGNED NOT NULL,
  item_vnum INT UNSIGNED NOT NULL,
  chance    DECIMAL(8,4) NULL,
  PRIMARY KEY (mob_vnum, item_vnum),
  KEY idx_item (item_vnum)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Now an item page can list "monsters that drop this item" and a mob page can list "this monster's drop table" with a JOIN. When you show drop chance, remember that the raw probability format in the files can vary by server type; if you're not sure, don't present the rate as exact — label it as "approximate".

The interface: tooltips and icons

No matter how accurate the data is, nobody uses it if the presentation is poor. A good item page mimics the in-game tooltip: name, type, level requirement, bonus list and price. For icons, you can export the item icons from the game client as PNGs and match them by vnum. A few practical tips:

  • Escape every string from the database with htmlspecialchars() before printing — names with special characters can cause XSS.
  • Convert bonuses into readable labels (e.g. apply type 1 → "Max HP"). Keep this mapping in a small dictionary file.
  • On mobile, wrap tables in a horizontally scrollable container to prevent overflow.

Performance, caching and SEO

Database sites are read-heavy: the data rarely changes but is read a lot. This structure is ideal for caching. Each item and mob page should have a permanent URL (e.g. /item/27003) and you should cache results for a few minutes. For SEO, giving each page a descriptive <title>, a meta description and ideally JSON-LD data boosts visibility for "Metin2 [item name]" searches. Generating a sitemap.xml containing all item and mob URLs also speeds up getting into search results.

Frequently Asked Questions

Does the wiki site affect the game server?

Not when it's set up correctly. If you import the proto data into a separate wiki database and only let the site read from those tables, you never touch the live game database.

I don't have plain-text proto files, only binary. What should I do?

Most servers also keep an item_proto/mob_proto table in MySQL you can read from. Otherwise you'll need community tools (proto unpackers) that convert the proto files into a plain-text version.

The names show up with broken characters, why?

It's usually a charset mismatch. Create the tables with utf8mb4, convert the file's real encoding (many protos use a Latin/Windows encoding) to UTF-8 during import, and add <meta charset="utf-8"> to the page.

Want a professional database/wiki site for your server? I can safely import your proto data and build a fast, searchable, multilingual wiki. To discuss your project, get in touch with me.

Bu kategorideki tüm yazılar →

Devamı için