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

Metin2 Event System: Setting Up Automatic Events

A metin2 event system lets your server open an OX quiz at set hours each day, start a double-drop or double-EXP period, or announce a fishing event — all without a GM lifting a finger. A well-built event loop pulls players back in on a regular schedule; a badly built one inflates the economy, causes lag, or thinks an event is still "on" after a restart. In this article I cover the event flag logic that underpins every event, the manual GM commands, and how to automate them with a quest timer or the operating system's cron.

Event flags: the shared language of every event

In the Metin2 source, almost every event runs on an event flag. A flag is an integer mapped to a name (for example double_drop = 1) that can be read by both the game core (C++) and the quest system (Lua). The logic is simple: somewhere you set the flag to 1, the drop/exp/event code checks that value and changes its behaviour, and when the event ends you set it back to 0.

On the quest side you use two core functions:

-- set the flag (1 = on, 0 = off)
game.set_event_flag("double_drop", 1)

-- read the flag
local active = game.get_event_flag("double_drop")
if active == 1 then
    -- event is running
end

The strength of this approach is that a single central switch drives every system. From the drop calculation to the on-screen announcement, every part looks at the same flag, so turning an event on or off comes down to a single line.

Manual control: GM commands

Before automating anything, you need to be able to toggle each event by hand — essential for both testing and emergencies. In most sources a GM can change an event flag directly with a command in-game:

/event_flag double_drop 1   // turn double drop on
/event_flag double_drop 0   // turn it off

The exact command name can differ between sources (check which command calls SetEventFlag in cmd.cpp). Events with their own map and special logic, such as OX, have their own commands — typically three separate GM commands to start the event, ask a question, and close it. Once you've verified these commands with a GM account, setting up automation is far safer, because the timer simply triggers "what a GM would have typed by hand".

Automating with a quest timer

The cleanest in-game automation is to use the server's own quest system as a scheduler. You start a server timer that fires at regular intervals, check the clock on each tick, and flip the flag at the right moment. The example below reads the clock every minute and turns the double-drop event on and off twice a day:

quest auto_event begin
    state start begin
        when login begin
            -- start the timer only once
            if not q.getf("running") then
                q.setf("running", 1)
                server_timer("event_tick", 60)
            end
        end

        when event_tick.server_timer begin
            local t = os.date("*t", get_global_time())
            if t.hour == 20 and t.min == 0 then
                game.set_event_flag("double_drop", 1)
                notice_all("The double-drop event has started! It lasts 2 hours.")
            elseif t.hour == 22 and t.min == 0 then
                game.set_event_flag("double_drop", 0)
                notice_all("The double-drop event has ended.")
            end
            -- re-arm the timer
            server_timer("event_tick", 60)
        end
    end
end

Note three things here: start the timer only once (otherwise every login opens a new one), re-arm it on every tick (server timers are one-shot), and announce to the whole server with notice_all. Timer and function names can vary slightly between sources; use the existing examples in your own questlib.lua as a reference.

Wiring the drop and EXP multiplier to the flag

The quest sets the flag, but the actual multiplier happens in the game core. To make the drop rate respond to the flag, add a check to the drop calculation in char_item.cpp:

int iEventFlag = quest::CQuestManager::instance().GetEventFlag("double_drop");
if (iEventFlag > 0)
    iDropPct *= 2;   // double the drop chance

The same logic applies to EXP in the experience-gain function in char.cpp, and to yang/money drops in the relevant function. The most common mistake here is making the multiplier too aggressive (say x5 EXP) and then forgetting to reset the flag when the event ends, inflating the economy permanently. Keep the multipliers moderate and make sure every flag you turn on has a matching off condition.

OX, fishing and other map-based events

An OX quiz needs more than a simple flag: a dedicated map (usually a separate map index), teleporting players there, a question-and-answer loop, and logic to eliminate anyone who answers wrong. That's why OX ships in most sources as a ready-made quest and map; your job is to wire it to the scheduler. In an automated setup your timer calls the command/function that starts OX at the right hour, announces it to players, and closes the event when time runs out.

  • OX quiz: gather players, ask questions and hand out rewards; requires teleporting to a map.
  • Fishing event: bind a flag to the fishing system to temporarily raise the chance of rare fish/items.
  • Double drop / EXP / yang: just an event flag plus a multiplier check in the core — the easiest to set up.

If you prefer OS-level automation, you can run a small script via Linux cron that flips the flag at specific hours; but since the script has to talk to the game core safely, a quest timer is simpler and less fragile for most servers.

Persistence and common mistakes

Event flags live in memory and, in many sources, reset when the server restarts. That's why it's more robust to write your timer with "keep it on if we're inside the event window" logic rather than just "turn it on at this hour"; that way an event returns to the correct state on its own after a crash. Other things to watch:

  • Give every set_event_flag(..., 1) a clear off condition; an event left "on" by accident breaks the economy.
  • Don't overdo announcements; a notice_all hitting the screen every minute annoys players.
  • Test teleport-based events like OX at peak hours; map capacity and teleport logic can behave differently under load.
  • Document your flag names somewhere; consistent names like double_drop and double_exp prevent confusion later.

Frequently Asked Questions

Event flags disappear when the server restarts — what should I do?

In most sources flags live in memory and reset on restart. The most practical fix is to write the timer with "window logic": on each tick, check whether the current time falls inside the event window and set the flag accordingly. That way the state corrects itself within a minute or two after a restart.

I turned on the double-drop event but the drops didn't change — why?

Most likely the quest is setting the flag but the game core isn't reading it. You need to add the drop multiplier to the calculation in char_item.cpp and recompile the source. Make sure the flag name is spelled exactly the same in the quest and in the core.

Do I have to write the OX event from scratch?

No. OX ships with its map and special logic in most sources; your job is to verify it and wire it to the scheduler. Writing it from scratch only makes sense if you want a completely original mechanic.

Want a stable automatic event system on your server? We can work together on Metin2 event flag architecture, OX and double-drop automation. To talk about your project, get in touch with me.

Bu kategorideki tüm yazılar →

Devamı için