Jump to content
×
×
  • Create New...

[FIX] Black screen / Client freeze


Recommended Posts

Introduction
I think everyone know about this famous bug. I profiled the game and checked granny documentation why it happens because we also faced this on MAP1s since we have a lot of offline shops. Actually the game not even freezes, it runs well and the updates happen. What eventually happens there is just that update time takes too long so it will skip rendering.

What makes update times longer?
The answer is granny controls. When you minimize your game, the completed controls never get freed. It's because the game frees them in CGrannyModelInstance::UpdateWorldPose which is called from CPythonApplication::RenderGame in a long way. There are just more and more of them that are never freed and that makes GrannySetModelClock take more and more time so when you open up your client from the minimized state it will never finish the update fast enough to call RenderGame in which they would be freed again.

Hidden Content

    Give reaction to this post to see the hidden content.

Thats all, you won't face the "black screen bug" again!

Good luck guys! 😄

Edited by Distraught
  • Metin2 Dev 69
  • Love 44
  • Love 6
  • Good 40
  • Lmao 1
  • Scream 1
  • Think 3
  • Confused 1
  • Vomit 1
  • Not Good 1
  • Troll 2
  • LoL 5

8P1MpHp.jpg

"My mom hiccups in the kitchen because Geppetto Lakatos is doing the Owl Dungeon." - Fleux

Link to comment
  • Replies 38
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

@ Distraught Thanks for the release! 👍 I tested the change and black screen seems to be finally fixed! I'm gonna to do more tests, but I think it'll be also fine. And what about moving effects? (loop problem when you minimize client for some time)

Link to comment
7 hours ago, ReFresh said:

@ Distraught Thanks for the release! 👍 I tested the change and black screen seems to be finally fixed! I'm gonna to do more tests, but I think it'll be also fine. And what about moving effects? (loop problem when you minimize client for some time)

Move the update of EffectManager to UpdateGame from RenderGame where it should be.

8P1MpHp.jpg

"My mom hiccups in the kitchen because Geppetto Lakatos is doing the Owl Dungeon." - Fleux

Link to comment
  • Honorable Member

The black screen was mostly caused by two major bugs:

  1. The granny controller freezing the process for n seconds until you get dc'd from the game
    1. You can test it by:
    2. Spawning tons of monsters
    3. Minimize the client for 30 - 40 minutes
    4. Maximizing the window again (it will freeze exactly at this point)
  2. The EffectManager not destroying the expired effects while the window was minimized, which caused all the executed effects to stack up and be run all at once after maximizing the window again
    1. You can test this bug very easily:
    2. Spawn tons Flame Ghosts and minimize the window
      1. /ma "Flame Ghost" 100
      2. /cannot_dead

I wasn't sure how to solve the 1st one, but for the 2nd one you can fix it in one of these ways:

Hidden Content

    Give reaction to this post to see the hidden content.

 

151605UCH22zd.png

1st Way) refresh only once every 256 frames = 4-6 seconds depending on the lag

1516050B26Z93.png

2nd Way) effect manager refresh for every frame

151605kBI2BOi.png

3rd Way) move the update from RenderGame to UpdateGame (it may not be called if skipFrame=true on ::Process)

  • Metin2 Dev 60
  • Love 25
  • Love 9
  • Good 27
  • Scream 1
  • Think 3
  • Confused 1
  • Angry 1
  • Troll 1
Link to comment
2 hours ago, martysama0134 said:

The black screen was mostly caused by two major bugs:

  1. The granny controller freezing the process for n seconds until you get dc'd from the game
    1. You can test it by:
    2. Spawning tons of monsters
    3. Minimize the client for 30 - 40 minutes
    4. Maximizing the window again (it will freeze exactly at this point)
  2. The EffectManager not destroying the expired effects while the window was minimized, which caused all the executed effects to stack up and be run all at once after maximizing the window again
    1. You can test this bug very easily:
    2. Spawn tons Flame Ghosts and minimize the window
      1. /ma "Flame Ghost" 100
      2. /cannot_dead

I wasn't sure how to solve the 1st one, but for the 2nd one you can fix it in one of these ways:

Hidden Content

    Give reaction to this post to see the hidden content.

 

 

Thanks Marty!

  • Metin2 Dev 1
Link to comment
4 hours ago, V0lvox said:

Hidden Content

    Give reaction to this post to see the hidden content.

 

Iam getting this error, when i have it to long minimized:

 

In EterLib/GrpScreen.cpp find CScreen::RestoreDevice and in the

if (FAILED(hrReset))

condition add (and don't forget to include comdef.h)

_com_error ce(hrReset);
const TCHAR* errMsg = ce.ErrorMessage();

So it should look like:

R2jZPb8.png

Now put a breakpoint there or print out the error message somewhere so we can get more info why your device couldn't reset.

By the way it's really another topic and not what this thread is about.

  • Metin2 Dev 5
  • Love 3
  • Good 4
  • Dislove 1

8P1MpHp.jpg

"My mom hiccups in the kitchen because Geppetto Lakatos is doing the Owl Dungeon." - Fleux

Link to comment
11 hours ago, martysama0134 said:

The black screen was mostly caused by two major bugs:

  1. The granny controller freezing the process for n seconds until you get dc'd from the game
    1. You can test it by:
    2. Spawning tons of monsters
    3. Minimize the client for 30 - 40 minutes
    4. Maximizing the window again (it will freeze exactly at this point)
  2. The EffectManager not destroying the expired effects while the window was minimized, which caused all the executed effects to stack up and be run all at once after maximizing the window again
    1. You can test this bug very easily:
    2. Spawn tons Flame Ghosts and minimize the window
      1. /ma "Flame Ghost" 100
      2. /cannot_dead

I wasn't sure how to solve the 1st one, but for the 2nd one you can fix it in one of these ways:

Hidden Content

    Give reaction to this post to see the hidden content.

 

Hidden Content

    Give reaction to this post to see the hidden content.

1st Way) refresh only once every 256 frames = 4-6 seconds depending on the lag

Hidden Content

    Give reaction to this post to see the hidden content.

2nd Way) effect manager refresh for every frame

Hidden Content

    Give reaction to this post to see the hidden content.

3rd Way) move the update from RenderGame to UpdateGame (it may not be called if skipFrame=true on ::Process)

What is the best way? I'm testing 2nd.. So you can tell more about this fixes I think can be usefull for all.. Thanks anyway 🙂

  • Metin2 Dev 1
  • Good 1
Link to comment
14 hours ago, martysama0134 said:

The black screen was mostly caused by two major bugs:

  1. The granny controller freezing the process for n seconds until you get dc'd from the game
    1. You can test it by:
    2. Spawning tons of monsters
    3. Minimize the client for 30 - 40 minutes
    4. Maximizing the window again (it will freeze exactly at this point)
  2. The EffectManager not destroying the expired effects while the window was minimized, which caused all the executed effects to stack up and be run all at once after maximizing the window again
    1. You can test this bug very easily:
    2. Spawn tons Flame Ghosts and minimize the window
      1. /ma "Flame Ghost" 100
      2. /cannot_dead

I wasn't sure how to solve the 1st one, but for the 2nd one you can fix it in one of these ways:

Hidden Content

    Give reaction to this post to see the hidden content.

 

Hidden Content

    Give reaction to this post to see the hidden content.

1st Way) refresh only once every 256 frames = 4-6 seconds depending on the lag

Hidden Content

    Give reaction to this post to see the hidden content.

2nd Way) effect manager refresh for every frame

Hidden Content

    Give reaction to this post to see the hidden content.

3rd Way) move the update from RenderGame to UpdateGame (it may not be called if skipFrame=true on ::Process)

Where exactly cand I find fix 1? What binary file? Thx.

  • Good 1
  • LoL 1
Link to comment

So tested 12 hours...

1. After 12 hours I got kick.. Doesnt work.. @ Distraught

2. Works fine, thanks @ martysama0134

Edit: So tested with network bridge without net.. Source clean kraizy mainline without any modification (build only for test) I don't got black screen but something is bad because game no freeze but kicking..

Edited by Cunoo
  • Lmao 1
Link to comment
7 minutes ago, Cunoo said:

UserInterface/PythonApplication.cpp here is martysama fix for expired skills..

I literally don t have any of the code from his picture there. How is it possible?

The only m_isMinimizedWnd reference I got there is this:

if (m_isMinimizedWnd)
		{
			canRender = false;
		}

 

Edited by narcisxb
Link to comment
16 minutes ago, narcisxb said:

I literally don t have any of the code from his picture there. How is it possible?

The only m_isMinimizedWnd reference I got there is this:

if (m_isMinimizedWnd)
		{
			canRender = false;
		}

 

Search: 

if (dwCurrentTime > s_uiNextFrameTime)

This: 

	if (dwCurrentTime > s_uiNextFrameTime)
	{
		int dt = dwCurrentTime - s_uiNextFrameTime;
		int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime; 

		if ( dt >= 500 )
		{
			s_uiNextFrameTime += nAdjustTime; 
			printf("FrameSkip 보정 %d\n",nAdjustTime);
			CTimer::Instance().Adjust(nAdjustTime);
		}

		s_bFrameSkip = true;
		bCurrentLateUpdate = TRUE;
	}

	//s_bFrameSkip = false;

	//if (dwCurrentTime > s_uiNextFrameTime)
	//{
	//	int dt = dwCurrentTime - s_uiNextFrameTime;

	//	//너무 늦었을 경우 따라잡는다.
	//	//그리고 m_dwCurUpdateTime는 delta인데 delta랑 absolute time이랑 비교하면 어쩌자는겨?
	//	//if (dt >= 500 || m_dwCurUpdateTime > s_uiNextFrameTime)

	//	//기존코드대로 하면 0.5초 이하 차이난 상태로 update가 지속되면 계속 rendering frame skip발생
	//	if (dt >= 500 || m_dwCurUpdateTime > s_uiNextFrameTime)
	//	{
	//		s_uiNextFrameTime += dt / uiFrameTime * uiFrameTime; 
	//		printf("FrameSkip 보정 %d\n", dt / uiFrameTime * uiFrameTime);
	//		CTimer::Instance().Adjust((dt / uiFrameTime) * uiFrameTime);
	//		s_bFrameSkip = true;
	//	}
	//}

	if (m_isFrameSkipDisable)
		s_bFrameSkip = false;

#ifdef __VTUNE__
	s_bFrameSkip = false;
#endif
	/*
	static bool s_isPrevFrameSkip=false;
	static DWORD s_dwFrameSkipCount=0;
	static DWORD s_dwFrameSkipEndTime=0;

	static DWORD ERROR_FRAME_SKIP_COUNT = 60*5;
	static DWORD ERROR_FRAME_SKIP_TIME = ERROR_FRAME_SKIP_COUNT*18;

	//static DWORD MAX_FRAME_SKIP=0;

	if (IsActive())
	{
	DWORD dwFrameSkipCurTime=ELTimer_GetMSec();

	if (s_bFrameSkip)
	{
	// 이전 프레임도 스킵이라면..
	if (s_isPrevFrameSkip)
	{
	if (s_dwFrameSkipEndTime==0)
	{
	s_dwFrameSkipCount=0; // 프레임 체크는 로딩 대비
	s_dwFrameSkipEndTime=dwFrameSkipCurTime+ERROR_FRAME_SKIP_TIME; // 시간 체크는 로딩후 프레임 스킵 체크

	//printf("FrameSkipCheck Start\n");
	}
	++s_dwFrameSkipCount;

	//if (MAX_FRAME_SKIP<s_dwFrameSkipCount)
	//	MAX_FRAME_SKIP=s_dwFrameSkipCount;

	//printf("u %d c %d/%d t %d\n", 
	//	dwUpdateTime9-dwUpdateTime1,
	//	s_dwFrameSkipCount, 
	//	MAX_FRAME_SKIP,
	//	s_dwFrameSkipEndTime);

	//#ifndef _DEBUG
	// 일정 시간동안 계속 프레임 스킵만 한다면...
	if (s_dwFrameSkipCount>ERROR_FRAME_SKIP_COUNT && s_dwFrameSkipEndTime<dwFrameSkipCurTime)
	{
	s_isPrevFrameSkip=false;
	s_dwFrameSkipEndTime=0;
	s_dwFrameSkipCount=0;

	//m_pyNetworkStream.AbsoluteExitGame();

	/*
	TraceError("무한 프레임 스킵으로 접속을 종료합니다");

	{
	FILE* fp=fopen("errorlog.txt", "w");
	if (fp)
	{
	fprintf(fp, "FRAMESKIP\n");
	fprintf(fp, "Total %d\n",		dwUpdateTime9-dwUpdateTime1);
	fprintf(fp, "Timer %d\n",		dwUpdateTime2-dwUpdateTime1);
	fprintf(fp, "Network %d\n",		dwUpdateTime3-dwUpdateTime2);
	fprintf(fp, "Keyboard %d\n",	dwUpdateTime4-dwUpdateTime3);
	fprintf(fp, "Controll %d\n",	dwUpdateTime5-dwUpdateTime4);
	fprintf(fp, "Resource %d\n",	dwUpdateTime6-dwUpdateTime5);
	fprintf(fp, "Camera %d\n",		dwUpdateTime7-dwUpdateTime6);
	fprintf(fp, "Mouse %d\n",		dwUpdateTime8-dwUpdateTime7);
	fprintf(fp, "UI %d\n",			dwUpdateTime9-dwUpdateTime8);
	fclose(fp);

	WinExec("errorlog.exe", SW_SHOW);
	}
	}
	}
	}

	s_isPrevFrameSkip=true;
	}
	else
	{
	s_isPrevFrameSkip=false;
	s_dwFrameSkipCount=0;
	s_dwFrameSkipEndTime=0;
	}
	}
	else
	{
	s_isPrevFrameSkip=false;
	s_dwFrameSkipCount=0;
	s_dwFrameSkipEndTime=0;
	}
	*/

(Comments and  __VTUNE__ can be deleted)
replace with this:

	if (dwCurrentTime > s_uiNextFrameTime)
	{
		int dt = dwCurrentTime - s_uiNextFrameTime;
		int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime;

		if (dt >= 500)
		{
			s_uiNextFrameTime += nAdjustTime;
			CTimer::Instance().Adjust(nAdjustTime);
		}

		if (!m_isFrameSkipDisable)
			s_bFrameSkip = true;
		bCurrentLateUpdate = TRUE;
	}

	if (m_isMinimizedWnd)
		CEffectManager::Instance().Update();

	if (m_isFrameSkipDisable && !m_isMinimizedWnd)
		s_bFrameSkip = false;

Edit for understanding.. You just add this:

if (m_isMinimizedWnd)
		CEffectManager::Instance().Update();

under this:

if (dwCurrentTime > s_uiNextFrameTime)
	{
		int dt = dwCurrentTime - s_uiNextFrameTime;
		int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime; 

		if ( dt >= 500 )
		{
			s_uiNextFrameTime += nAdjustTime; 
			printf("FrameSkip 보정 %d\n",nAdjustTime);
			CTimer::Instance().Adjust(nAdjustTime);
		}

		s_bFrameSkip = true;
		bCurrentLateUpdate = TRUE;
	}

+ this:

if (m_isFrameSkipDisable)
		s_bFrameSkip = false;

change to this:

if (m_isFrameSkipDisable && !m_isMinimizedWnd)
		s_bFrameSkip = false;

Thats all.. 2nd way refresh for every frame..

Edited by Cunoo
  • Love 1
Link to comment
10 minutes ago, Cunoo said:

Search: 

if (dwCurrentTime > s_uiNextFrameTime)

This: 

	if (dwCurrentTime > s_uiNextFrameTime)
	{
		int dt = dwCurrentTime - s_uiNextFrameTime;
		int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime; 

		if ( dt >= 500 )
		{
			s_uiNextFrameTime += nAdjustTime; 
			printf("FrameSkip 보정 %d\n",nAdjustTime);
			CTimer::Instance().Adjust(nAdjustTime);
		}

		s_bFrameSkip = true;
		bCurrentLateUpdate = TRUE;
	}

	//s_bFrameSkip = false;

	//if (dwCurrentTime > s_uiNextFrameTime)
	//{
	//	int dt = dwCurrentTime - s_uiNextFrameTime;

	//	//너무 늦었을 경우 따라잡는다.
	//	//그리고 m_dwCurUpdateTime는 delta인데 delta랑 absolute time이랑 비교하면 어쩌자는겨?
	//	//if (dt >= 500 || m_dwCurUpdateTime > s_uiNextFrameTime)

	//	//기존코드대로 하면 0.5초 이하 차이난 상태로 update가 지속되면 계속 rendering frame skip발생
	//	if (dt >= 500 || m_dwCurUpdateTime > s_uiNextFrameTime)
	//	{
	//		s_uiNextFrameTime += dt / uiFrameTime * uiFrameTime; 
	//		printf("FrameSkip 보정 %d\n", dt / uiFrameTime * uiFrameTime);
	//		CTimer::Instance().Adjust((dt / uiFrameTime) * uiFrameTime);
	//		s_bFrameSkip = true;
	//	}
	//}

	if (m_isFrameSkipDisable)
		s_bFrameSkip = false;

#ifdef __VTUNE__
	s_bFrameSkip = false;
#endif
	/*
	static bool s_isPrevFrameSkip=false;
	static DWORD s_dwFrameSkipCount=0;
	static DWORD s_dwFrameSkipEndTime=0;

	static DWORD ERROR_FRAME_SKIP_COUNT = 60*5;
	static DWORD ERROR_FRAME_SKIP_TIME = ERROR_FRAME_SKIP_COUNT*18;

	//static DWORD MAX_FRAME_SKIP=0;

	if (IsActive())
	{
	DWORD dwFrameSkipCurTime=ELTimer_GetMSec();

	if (s_bFrameSkip)
	{
	// 이전 프레임도 스킵이라면..
	if (s_isPrevFrameSkip)
	{
	if (s_dwFrameSkipEndTime==0)
	{
	s_dwFrameSkipCount=0; // 프레임 체크는 로딩 대비
	s_dwFrameSkipEndTime=dwFrameSkipCurTime+ERROR_FRAME_SKIP_TIME; // 시간 체크는 로딩후 프레임 스킵 체크

	//printf("FrameSkipCheck Start\n");
	}
	++s_dwFrameSkipCount;

	//if (MAX_FRAME_SKIP<s_dwFrameSkipCount)
	//	MAX_FRAME_SKIP=s_dwFrameSkipCount;

	//printf("u %d c %d/%d t %d\n", 
	//	dwUpdateTime9-dwUpdateTime1,
	//	s_dwFrameSkipCount, 
	//	MAX_FRAME_SKIP,
	//	s_dwFrameSkipEndTime);

	//#ifndef _DEBUG
	// 일정 시간동안 계속 프레임 스킵만 한다면...
	if (s_dwFrameSkipCount>ERROR_FRAME_SKIP_COUNT && s_dwFrameSkipEndTime<dwFrameSkipCurTime)
	{
	s_isPrevFrameSkip=false;
	s_dwFrameSkipEndTime=0;
	s_dwFrameSkipCount=0;

	//m_pyNetworkStream.AbsoluteExitGame();

	/*
	TraceError("무한 프레임 스킵으로 접속을 종료합니다");

	{
	FILE* fp=fopen("errorlog.txt", "w");
	if (fp)
	{
	fprintf(fp, "FRAMESKIP\n");
	fprintf(fp, "Total %d\n",		dwUpdateTime9-dwUpdateTime1);
	fprintf(fp, "Timer %d\n",		dwUpdateTime2-dwUpdateTime1);
	fprintf(fp, "Network %d\n",		dwUpdateTime3-dwUpdateTime2);
	fprintf(fp, "Keyboard %d\n",	dwUpdateTime4-dwUpdateTime3);
	fprintf(fp, "Controll %d\n",	dwUpdateTime5-dwUpdateTime4);
	fprintf(fp, "Resource %d\n",	dwUpdateTime6-dwUpdateTime5);
	fprintf(fp, "Camera %d\n",		dwUpdateTime7-dwUpdateTime6);
	fprintf(fp, "Mouse %d\n",		dwUpdateTime8-dwUpdateTime7);
	fprintf(fp, "UI %d\n",			dwUpdateTime9-dwUpdateTime8);
	fclose(fp);

	WinExec("errorlog.exe", SW_SHOW);
	}
	}
	}
	}

	s_isPrevFrameSkip=true;
	}
	else
	{
	s_isPrevFrameSkip=false;
	s_dwFrameSkipCount=0;
	s_dwFrameSkipEndTime=0;
	}
	}
	else
	{
	s_isPrevFrameSkip=false;
	s_dwFrameSkipCount=0;
	s_dwFrameSkipEndTime=0;
	}
	*/

(Comments and  __VTUNE__ can be deleted)
replace with this:

	if (dwCurrentTime > s_uiNextFrameTime)
	{
		int dt = dwCurrentTime - s_uiNextFrameTime;
		int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime;

		if (dt >= 500)
		{
			s_uiNextFrameTime += nAdjustTime;
			CTimer::Instance().Adjust(nAdjustTime);
		}

		if (!m_isFrameSkipDisable)
			s_bFrameSkip = true;
		bCurrentLateUpdate = TRUE;
	}

	if (m_isMinimizedWnd)
		CEffectManager::Instance().Update();

	if (m_isFrameSkipDisable && !m_isMinimizedWnd)
		s_bFrameSkip = false;

Edit for understanding.. You just add this:

if (m_isMinimizedWnd)
		CEffectManager::Instance().Update();

under this:

if (dwCurrentTime > s_uiNextFrameTime)
	{
		int dt = dwCurrentTime - s_uiNextFrameTime;
		int nAdjustTime = ((float)dt / (float)uiFrameTime) * uiFrameTime; 

		if ( dt >= 500 )
		{
			s_uiNextFrameTime += nAdjustTime; 
			printf("FrameSkip 보정 %d\n",nAdjustTime);
			CTimer::Instance().Adjust(nAdjustTime);
		}

		s_bFrameSkip = true;
		bCurrentLateUpdate = TRUE;
	}

+ this:

if (m_isFrameSkipDisable)
		s_bFrameSkip = false;

change to this:

if (m_isFrameSkipDisable && !m_isMinimizedWnd)
		s_bFrameSkip = false;

Thats all.. 2nd way refresh for every frame..

It works like a charm. Thank you! xD

Quick question: how bad will refreshing every frame affect perfomance? does it matter considering modern cpus?

Edited by narcisxb
Link to comment
24 minutes ago, narcisxb said:

It works like a charm. Thank you! xD

Quick question: how bad will refreshing every frame affect perfomance? does it matter considering modern cpus?

Thats my question up.. But I think not too much.. I tested it and I dont see different.. 5% cpu up with cpu mode.. But I think modern pc use gpu in settings for rendering... You can use 2nd way in realtime..

Link to comment

I'm still not sure what Marty's effect fix exactly fixing, if it should fix the effects to stacking up when window is minimized for example for butterflies, it doesn't work and the effect is still stacking up.

And I have it like this:

Spoiler
https://ctrlv.cz/o8my

 

Link to comment
14 minutes ago, ReFresh said:

I'm still not sure what Marty's effect fix exactly fixing, if it should fix the effects to stacking up when window is minimized for example for butterflies, it doesn't work and the effect is still stacking up.

And I have it like this:

  Reveal hidden contents
https://ctrlv.cz/o8my

 

I think this works for all effects... Because you refresh all effects thats works for skills, effects just member things.. I dont have problem with this fix, works real time fine.. I have problem only with first fix.. And no my problem is black screen but kick after overflow.. I think missing some code.. Because if I "can" got blackscreen I got simply kick... Tested with clean mainline and still same problem with all tests.. 

Link to comment
49 minutes ago, Cunoo said:

I think this works for all effects... Because you refresh all effects thats works for skills, effects just member things.. I dont have problem with this fix, works real time fine.. I have problem only with first fix.. And no my problem is black screen but kick after overflow.. I think missing some code.. Because if I "can" got blackscreen I got simply kick... Tested with clean mainline and still same problem with all tests.. 

How can you be just so so so so so stupid? If your server kicks you out it's because you don't even know what you are doing. Not my fix is the problem, it's more like your knowledge... Actually marty just repeated half of what I wrote down before and you're saying what I wrote is not working while licking his ass clean at the same time. (don't get me wrong, it's not against marty, it's against you and other incompetent stupid-ass motherfuckers like you)

Sorry for the language... But for nothing else...

 

Quote

I'm still not sure what Marty's effect fix exactly fixing, if it should fix the effects to stacking up when window is minimized for example for butterflies, it doesn't work and the effect is still stacking up.

The effects you use on your maps are not managed by EffectManager. They are managed by the Area itself.

Edited by Distraught
  • Love 1
  • Good 1
  • Lmao 5
  • Confused 1
  • LoL 3

8P1MpHp.jpg

"My mom hiccups in the kitchen because Geppetto Lakatos is doing the Owl Dungeon." - Fleux

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Read our Rules
  • Similar Content

    • By Gurgarath
      Hello! Many people complained about a "7 pixel bug" on some clients. For example the client will open a few pixels too far from the left-side of the screen. Usually between 7 and 9 pixel on the right.
      I still do not know why it happens for some people and not for other. I thought about a visual studio toolset, a screen configuration or whatever but it turns out to be harder to know why it actually happens, I also had only two people talking about this so I cannot get accurate data. Anyway, let's get started it's really easy.
      The bug looks
      Hidden Content
      Give reaction to this post to see the hidden content. , take from the official client it looks like 1 or 2 pixels only. But it looks almost exactly like it at some moments. First, make sure your metin2.cfg is correct and does not display a weird resolution (like 1913 * 1080).

      Then just add this small line in PythonApplication.cpp:
      SetPosition(-8, 0); Right after this one:
      AdjustSize(m_pySystem.GetWidth(), m_pySystem.GetHeight()); EDIT:
      If you happen to have it on the second window as well, move the line under the bAnotherWindow check. Just like this:
      And voilà, it's fixed. Don't hesistate to add or remove one pixel if needed.
      It's really small and looks like a workaround but I did it really quickly. I didn't test this fix on clients / computers not having the actual bug. If it is a client issue it shouldn't cause any problems, if it's a computer issue, I might need more data to fine-tune the fix. Don't forget to share some data if you have.
    • By Helia01
      Hey m2dev

      You summon a lot of monsters, they attack your character and then you kill or purge monsters, but the damage still continues to be shown visually. Is this a familiar situation?
      In addition, the damage is shown visually even after the death of the character... I love this game. 🥰


       
      I haven't seen a fix for this problem, let's try to fix this sh..


      Hidden Content
      Give reaction to this post to see the hidden content.
      I'm not saying that this is an ideal solution. If you have any ideas, please write comments.


      Best regards, Masha
    • By Abel(Tiger)
      An annoying bug which need a fix.
      Gif with the problem (from ѕeмa™) :  Hidden Content
      Give reaction to this post to see the hidden content.
      // PythonApplicationProcedure.cpp // After: if (m_isWindowFullScreenEnable) { __MinimizeFullScreenWindow(hWnd, m_dwWidth, m_dwHeight); } // Just add: OnMouseMiddleButtonUp(0, 0);  
    • By Shang
      M2 Download Center
      Hidden Content
      Give reaction to this post to see the hidden content. ( Internal )
      Hi devs, today I will release the fix I made for the skill cooldown, already fixed on official servers, this is the bug it self:

      And this is the fix:

      Regards!

      Hidden Content
      Give reaction to this post to see the hidden content. ### root/ui.py ### Search: def SetSlotCoolTimeColor(self, slotIndex, r, g, b, a): wndMgr.SetSlotCoolTimeColor(self.hWnd, slotIndex, r, g, b, a) ### Add after: def StoreSlotCoolTime(self, key, slotIndex, coolTime, elapsedTime = 0.0): wndMgr.StoreSlotCoolTime(self.hWnd, key, slotIndex, coolTime, elapsedTime) def RestoreSlotCoolTime(self, key): wndMgr.RestoreSlotCoolTime(self.hWnd, key)  
      Thanks to @Horinna for report that bug.
      Here's the fix:
      """ Find this: elif (not self.__CanUseSkillNow()) or (skillGrade != j): skillPage.SetSlotCount(realSlotIndex, 0) skillPage.DisableCoverButton(realSlotIndex) Add this under:""" skillPage.DeactivateSlot(realSlotIndex) # After the else, paste this: if player.IsSkillActive(slotIndex) and (skillGrade == j): # fix001 skillPage.ActivateSlot(realSlotIndex) # The if should look like this: if (skillGrade == skill.SKILL_GRADE_COUNT) and j == (skill.SKILL_GRADE_COUNT-1): skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) elif (not self.__CanUseSkillNow()) or (skillGrade != j): skillPage.SetSlotCount(realSlotIndex, 0) skillPage.DisableCoverButton(realSlotIndex) skillPage.DeactivateSlot(realSlotIndex) # fix else: skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) if player.IsSkillActive(slotIndex) and (skillGrade == j): # fix skillPage.ActivateSlot(realSlotIndex)  
  • Activity

    1. 170

      Render Target Remastered

    2. 170

      Render Target Remastered

    3. 170

      Render Target Remastered

    4. 6

      Official Item Combination + Transform & Enchant Costume

    5. 170

      Render Target Remastered

    6. 2

      Hosting packages - feedback requested

    7. 170

      Render Target Remastered

    8. 2

      Hosting packages - feedback requested

  • Recently Browsing

    No registered users viewing this page.

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.