Jump to content

[M2Dev] Advanced Files To Build Your Server: Src & Server Files & Client [x64 / DX9Ex / CMake / Python3.14 / FreeType / XChaCha20-Poly1305]


Recommended Posts

I’m new at this! I was trying to understand why some features I was installing weren't working... Then I figured out I was running a client with Python 2.7. I kind of lost hope, but then I found this post! You are a lifesaver, man. Big thanks! ❤️

  • Love 1
  • 3 weeks later...

Everything is perfect but i have a problem. In locale only the EN version has item_proto.txt the others have it already compiled. And i need to add a new item but without having item_proto.txt for all languages i can't add it. Any solution ? Thanks

  • kekw 1
  • 3 weeks later...

I am having serious issues with these files; I should mention that I worked in a native Windows environment rather than using a virtual machine. I cloned the four resources (m2dev-server, m2dev-server-src, m2dev-client-src, m2dev-client). On my first attempt, I did everything on my own, only glancing at the guides kindly provided by distraught; however, once the environment was ready and I tried to start the server, only the db and auth ports remained active, while the ports for the channels I launched did not (consequently, when I started the client, it showed the channels as offline). On my second attempt, I followed every step of distraught's guides to the letter, yet I still encountered the same problem: the channels (1, 2, 3, 4) crashed, leaving only the db and auth ports active. A major issue I encountered concerns the server compilation (which generates the game.exe, db.exe, and qc.exe files); while there seem to be no problems with the first two, there is an issue with qc.exe. When moving qc.exe to the ...\share\locale\english\quest folder and running `python make.py`, the compilation stops with this error:

Compiling snow_dungeon.quest...

QUEST : snow_dungeon

STATE : start

FUNCTION setting()

FUNCTION make_dungeon()

FUNCTION start_at_level(stage)

FUNCTION clear_timer(inx)

FUNCTION is_snowd(idx)

FUNCTION level_clear()

WHEN : login

Traceback (most recent call last):

File "C:\project\m2dev-server\share\locale\english\quest\make.py", line 90, in <module>

main()

~~~~^^

File "C:\project\m2dev-server\share\locale\english\quest\make.py", line 86, in main

subprocess.run([str(qc_exe), str(filename)], check=True)

~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Python314\Lib\subprocess.py", line 577, in run

raise CalledProcessError(retcode, process.args,

output=stdout, stderr=stderr)

subprocess.CalledProcessError: Command '['C:\\project\\m2dev-server\\share\\locale\\english\\quest\\qc.exe', 'C:\\project\\m2dev-server\\share\\locale\\english\\quest\\pre_qc\\snow_dungeon.quest']' returned non-zero exit status 3221225477.

However, if I run the `python make.py` command using the old qc.exe (the original one provided with Distraught's files), the compilation succeeds. This might be because qc needs to be compiled for x86 rather than x64—I'm not sure. There is also a difference in file size between the two qc.exe files (the original is 1,518 KB, while the x64-compiled version is 416 KB; this might be due to optimizations applied in the x86 environment). However, I don't understand why the client and server are unable to communicate with each other. I updated the IPs (server and server_test) in serverinfo.py to my static IP and repacked the root and all other archives, getting my pack folder. 

I don't understand what's wrong with my procedure or why the channels keep crashing right after the server starts up. P.S. There is nothing in the channel syserr logs because the crash occurs before the server startup is complete. The only syserr produced is that of the db, which tells me this:

[2026-08-16 21:30:36.380] [error] [int __cdecl Start(void)()] TABLE_POSTFIX not configured use default
[2026-08-16 21:30:41.321] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:41.321] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:41.321] [error] [int __cdecl CClientManager::Process(void)()] Recv failed
[2026-08-16 21:30:42.506] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:42.506] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:42.506] [error] [int __cdecl CClientManager::Process(void)()] Recv failed
[2026-08-16 21:30:43.632] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:43.632] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:43.632] [error] [int __cdecl CClientManager::Process(void)()] Recv failed
[2026-08-16 21:30:44.565] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:44.565] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:44.565] [error] [int __cdecl CClientManager::Process(void)()] Recv failed

 

When starting the Visual Studio debugger, it tells me that the problem lies in the code block below (from qc.cpp):

 

if (hasError)

{

      cout << "Calls undeclared function! : " << endl;

      for (auto it = error_func.begin(); it != error_func.end(); ++it)

      {

         cout << *it << endl;

      }

      abort();

   }

 

Thank you for your help

Edited by spaccanabbi
wrong directory

Not sure how do you have issues. i have same severfile with 0 issues.

 

The qc.exe issue and the channel crashes appear to be two separate problems.

Exit code 3221225477 is 0xC0000005, which indicates an access violation. However, the debugger shows that qc.exe reaches the check for undeclared quest functions and then terminates. Please check the output immediately before the crash—it should list the exact undeclared functions after:

Calls undeclared function!

This most likely means that the newly compiled qc.exe does not contain or recognise one or more functions used by snow_dungeon.quest. The original qc.exe works because it matches the provided server files and quest functions. It should not need to be compiled as x86; the difference in file size can be caused by build configuration, static libraries, debug information and compiler optimisations.

Make sure that:

qc.exe, the quest files and the server source are all from the same revision.

You run python make.py from the correct quest directory.

All custom Lua quest functions used by snow_dungeon.quest are registered in the server source.

You share the undeclared function names printed by qc.exe, as those are more useful than the Python traceback.

Regarding the channels, the DB messages are not the original cause. They indicate that the channel processes connected to DB and then unexpectedly disconnected:

socket_read failed
Recv failed

TABLE_POSTFIX not configured use default is only a warning and should not cause the channels to crash.

The client cannot connect because the channel processes are already dead, so changing or repacking serverinfo.py will not fix this stage of the problem. First, run one channel directly from its own directory, preferably through Visual Studio, and capture:

The first exception, not only the final termination.

The complete call stack.

The console output.

Any generated crash dump or Windows Event Viewer entry.

The channel configuration, with passwords removed.

Also verify that the server processes are being launched with the correct working directory. If game.exe starts from the wrong directory, it may fail to find its configuration, locale or data files before the logger is fully initialised, which would explain why no channel syserr is created.

For the network configuration, internal connections such as game-to-DB should normally use the local address configured for the server environment. Only the client-facing address in serverinfo.py should use the LAN or public IP. Also check that each channel has unique ports and that Windows Firewall allows the channel executables.

In short, the DB is remaining online and reporting that the channel processes are crashing. The next useful information is the first exception and complete call stack from game.exe; without that, changing the client IP or rebuilding the packs will not solve the channel crash.

  • Active+ Member
5 hours ago, spaccanabbi said:

I am having serious issues with these files; I should mention that I worked in a native Windows environment rather than using a virtual machine. I cloned the four resources (m2dev-server, m2dev-server-src, m2dev-client-src, m2dev-client). On my first attempt, I did everything on my own, only glancing at the guides kindly provided by distraught; however, once the environment was ready and I tried to start the server, only the db and auth ports remained active, while the ports for the channels I launched did not (consequently, when I started the client, it showed the channels as offline). On my second attempt, I followed every step of distraught's guides to the letter, yet I still encountered the same problem: the channels (1, 2, 3, 4) crashed, leaving only the db and auth ports active. A major issue I encountered concerns the server compilation (which generates the game.exe, db.exe, and qc.exe files); while there seem to be no problems with the first two, there is an issue with qc.exe. When moving qc.exe to the ...\share\locale\english\quest folder and running `python make.py`, the compilation stops with this error:

Compiling snow_dungeon.quest...

QUEST : snow_dungeon

STATE : start

FUNCTION setting()

FUNCTION make_dungeon()

FUNCTION start_at_level(stage)

FUNCTION clear_timer(inx)

FUNCTION is_snowd(idx)

FUNCTION level_clear()

WHEN : login

Traceback (most recent call last):

File "C:\project\m2dev-server\share\locale\english\quest\make.py", line 90, in <module>

main()

~~~~^^

File "C:\project\m2dev-server\share\locale\english\quest\make.py", line 86, in main

subprocess.run([str(qc_exe), str(filename)], check=True)

~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "C:\Python314\Lib\subprocess.py", line 577, in run

raise CalledProcessError(retcode, process.args,

output=stdout, stderr=stderr)

subprocess.CalledProcessError: Command '['C:\\project\\m2dev-server\\share\\locale\\english\\quest\\qc.exe', 'C:\\project\\m2dev-server\\share\\locale\\english\\quest\\pre_qc\\snow_dungeon.quest']' returned non-zero exit status 3221225477.

However, if I run the `python make.py` command using the old qc.exe (the original one provided with Distraught's files), the compilation succeeds. This might be because qc needs to be compiled for x86 rather than x64—I'm not sure. There is also a difference in file size between the two qc.exe files (the original is 1,518 KB, while the x64-compiled version is 416 KB; this might be due to optimizations applied in the x86 environment). However, I don't understand why the client and server are unable to communicate with each other. I updated the IPs (server and server_test) in serverinfo.py to my static IP and repacked the root and all other archives, getting my pack folder. 

I don't understand what's wrong with my procedure or why the channels keep crashing right after the server starts up. P.S. There is nothing in the channel syserr logs because the crash occurs before the server startup is complete. The only syserr produced is that of the db, which tells me this:

[2026-08-16 21:30:36.380] [error] [int __cdecl Start(void)()] TABLE_POSTFIX not configured use default
[2026-08-16 21:30:41.321] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:41.321] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:41.321] [error] [int __cdecl CClientManager::Process(void)()] Recv failed
[2026-08-16 21:30:42.506] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:42.506] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:42.506] [error] [int __cdecl CClientManager::Process(void)()] Recv failed
[2026-08-16 21:30:43.632] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:43.632] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:43.632] [error] [int __cdecl CClientManager::Process(void)()] Recv failed
[2026-08-16 21:30:44.565] [error] [int __cdecl socket_read(unsigned __int64,char *,unsigned __int64)()] about to lose connection
[2026-08-16 21:30:44.565] [error] [int __cdecl CPeerBase::Recv(void)()] socket_read failed No such file or directory
[2026-08-16 21:30:44.565] [error] [int __cdecl CClientManager::Process(void)()] Recv failed

 

When starting the Visual Studio debugger, it tells me that the problem lies in the code block below (from qc.cpp):

 

if (hasError)

{

      cout << "Calls undeclared function! : " << endl;

      for (auto it = error_func.begin(); it != error_func.end(); ++it)

      {

         cout << *it << endl;

      }

      abort();

   }

 

Thank you for your help

Known issue with qc on Windows, someone suggested that this may work:

.png

(Kept the quote anonymous, if you are the author feel free to tag yourself below 👇)

  • 2 weeks later...

ARM64 bug in src/game/main.cpp, line 449:

char ch;

must be changed to:

int ch;

getopt() in line 457 returns an int and uses -1 to indicate completion. On ARM64, char is unsigned, converting -1 to 255 and causing an infinite loop at 100% CPU. Tested successfully on FreeBSD 15.1/aarch64 on RockPro64.

  • Love 1

I made a few changes to the source code to make it architecture independent, the only issues left are with big endian architectures like PowerPC.

On 8/17/2026 at 11:59 PM, Mind Rapist said:

Known issue with qc on Windows, someone suggested that this may work:

.png

(Kept the quote anonymous, if you are the author feel free to tag yourself below 👇)

This fixes the qc release binary. Debug binary works because it does not use optimization. That's good, thanks!

Did anyone break Character Creation? I'm only trying it now, after 3 days of touching the files so probably something i did, but now im not sure. The problem seems to be related with granny . I did not touch those soooooooooooooooo.... 

Explaining my problem, i get this in ErrorLog:
Exception Type: 0xc0000094 (Integer divided by 0)
This happens when i click to create a new character. The client instantly crashed.

In introcreate.py, it creates a preview of each race. I guess it might be catching a bad animation? I don't know..

I'll take a look at it, and if someone has the same problem, i'll be back with a fix, maybe, maybe not, i'll try. If not, well..... just hanging around..

EDIT 1: Added some tracer messages so i could understand what was failing/breaking point and now it does not crash. Amazing. I'll be back with awesome content.

Edited by friendtm
1 hour ago, friendtm said:

Did anyone break Character Creation? I'm only trying it now, after 3 days of touching the files so probably something i did, but now im not sure. The problem seems to be related with granny . I did not touch those soooooooooooooooo.... 

Explaining my problem, i get this in ErrorLog:
Exception Type: 0xc0000094 (Integer divided by 0)
This happens when i click to create a new character. The client instantly crashed.

In introcreate.py, it creates a preview of each race. I guess it might be catching a bad animation? I don't know..

I'll take a look at it, and if someone has the same problem, i'll be back with a fix, maybe, maybe not, i'll try. If not, well..... just hanging around..

EDIT 1: Added some tracer messages so i could understand what was failing/breaking point and now it does not crash. Amazing. I'll be back with awesome content.

I can't edit the post i did so i'm creating this one. I found the fix for my problem and actually, this might be common for everyone right now.
Explaining the thing: The Client does a performance check. It basically divides what he renders by the time it takes. Under specific circumstances (wich i could not identify) the render is so fast that the measured time ends up being 0ms. With that, the client ends up trying a division by 0. Boom, crash. So, where is the fix to this?

UserInterface\PythonApplication.cpp

// Inside CPythonApplication::Process()
// Look for:
m_dwFaceAccCount += dwCurFaceCount;
m_dwFaceAccTime += m_dwCurRenderTime;

m_fFaceSpd=(m_dwFaceAccCount/m_dwFaceAccTime);

// The fixed code:
m_dwFaceAccCount += dwCurFaceCount;
m_dwFaceAccTime += std::max<DWORD>(1, m_dwCurRenderTime);

m_fFaceSpd = float(m_dwFaceAccCount) / float(m_dwFaceAccTime);


So, basically, we make sure that the render time is at least 1ms and changed integer division to float divison.
I've been testing and no more crashes. I don't know if this change will have impact on anything else, so, if you know something i don't, please don't be shy.

Don't use any images from : imgur, turkmmop, freakgamers, inforge, hizliresim... Or your content will be deleted without notice...
Use : https://metin2.download/media/add/

Please use https://metin2.download/ when uploading files smaller than 100MB, otherwise the approval will take longer due to manual upload.

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.