Jump to content

Recommended Posts

21 minutes ago, razzor69 said:

Also how about this mod https://www.nexusmods.com/skyrim/mods/93025?tab=files ?
i'm still using it right now, and yeah its no more CTD during wondering around in wilderness 

It has no relation to the patch. Seems to fix something that already fixed by CrashFixPlugin with side effects of not spawning rabbits.

If you're looking for a game setup with no CTD take a look at this topic https://www.loverslab.com/topic/128438-2019-skyrim-le-stability-guide/ I ran through whole skyrim with 1000 movespeed with no crashes using this setup. Only detail need to be fixed there is the SSME block size and ExpandSystemMemoryX64 usage for hard modded games.

 

Link to comment
1 hour ago, razzor69 said:

Also how about this mod https://www.nexusmods.com/skyrim/mods/93025?tab=files ?
i'm still using it right now, and yeah its no more CTD during wondering around in wilderness 

.....that's not how templates work (many of the leveled actor lists are multi race), so i think they are wrong about the cause, i think the respawn flag added by USLEP could be the problem there. edit: nope i'm unable to reproduce that crash either way.

Link to comment

What is the actually recommended thing to do when someone is currently using Animation Loading Fix? Disable and use only this? I've seen mrsrt saying to downgrade to 1.0 to maintain compatibility, but is it necessary? Are there any benefits to having both instead of just replacing it with this one?

 

And of course, thank you so much for your work towards solving this issue!

Link to comment
16 hours ago, mrsrt said:

Normally, the game shouldn't freeze and/or CTD. If it happens, try to use the topic https://www.loverslab.com/topic/128438-2019-skyrim-le-stability-guide/ (info about SSME and os allocators a bit outdated, I'll update it next month).

 

My game is armed to the teeth with fixes and tipps from that guide. But thanks. Still using this mod and so far still up and running well. Subjectively I have faster loading times when starting the game. Nice.

 

Link to comment
9 hours ago, thiciathy said:

Are there any benefits to having both instead of just replacing it with this one?

that one loads the player's animations first before the npc animations, loading the player animations first seems to reduce some of the crashing caused by loading large save files or game with lots of animations installed (or at least that's what people are reporting).

this one skips some startup code to allow a fuck load more animations, it also seems to have fixed some other things in the process as a side effect.

 

so in theory having both "should" be a good thing (but v1.1 edits the same stuff that this one is trying to bypass, so you need to stay away from 1.1 if you want to use this one at the same time)

 

Link to comment

I have encountered a problem, but it is not directly caused by this mod, it is an indirect consequence.

I guess the same problem can happen when we use Animation Loading Fix.

 

The Creation Kit do CTD when we open any cell if we have a CTD% over 100% in FNIS.

The problem is not caused by this mod. Is caused by excesive animations inside the CK.

 

It doesn't matter the type of cell, interior or exterior, it doesn't matter how many ESP we load in the CK, it doesn't matter if the cell is in Skyrim, in the DLC's or in any other ESP/ESM file.

The CTD not shown when we see the animations in the Animation tab of the actor editor.

The CTD not shown when we see the animation graph in the menu Game -> Animations.

The CTD only happens when make double-click in the cell view to see the cell in the Render Window.

I not necesary open any ESP/ESM for get the CTD. Simply open the CK, select World Space = Default World in the Cell View. Make double click over Wilderness and you get the CTD in CK caused by Excesive Animations.


If other users confirm the problem I think it should be indicated in the description of the mod.

I have this mod installed for more than a week but I did not use the CK until yesterday and I expent half of the day to locate the problem.

Link to comment
11 hours ago, mrsrt said:

Of course, CPU and RAM. This processing happens between actual frame renders by GPU, if your GPU is overloaded by graphic mods then in most cases you will not see any difference. In that case, if you're looking for fps boost you have to free GPU resources by using less complex graphic setup or to buy a more powerful GPU. 

I think it's important for you to clarify that in the description and people should post their hardware specifications when claiming they've got a performance improvement over this.

 

Most modern games will rely far more on the GPU than the CPU. My CPU (i7-4770K) is 6 years old (can't even reach 4.5 GHz), while my new GPU (GTX 1660) will perform better than my old one (GTX 970).

I only run 2K, 1K or below textures while playing at 1080p and my ENB preset is a modified version of Rusty's (aimed towards performance with some extra annoying effects such as DOF and Vignette disabled and with the only AA running being TAA).

With that being said, I can get my GPU to 100%, but individual CPU cores will never be at 100% (most of the time they are around 50% with some occasional spikes up to 80% when loading new assets).

 

To me it seems you might get some performance improvements but only if your CPU is really, and I mean, really old (+1 decade or so) or if you've underclocked your CPU.

Took a look again at the code and I still believe that do while loop should run extremely fast on any modern CPU; It doesn't even have any FPU operations in it.

 

My recommendation for this plugin is:

Are you having animation related crashes? Use it.

Do you get a performance boost with this plugin? Use it.

Otherwise, I recommend not running it because it always skips this by XORing the eax register into 0:

if ( v4 )
{
    v5 = (_DWORD *)(v3 + 8);
    do
    {
        --v4;
        *v5 = 0;
        v5 += 3;
    }
    while ( v4 );
}

and even the author doesn't know the consequences for doing such a thing.

 

My recommendation for the author; Allow us a setting (similar to Crash Fixes) that instead of always skipping this piece of code warns us about the overflow.

Link to comment
8 hours ago, thiciathy said:

What is the actually recommended thing to do when someone is currently using Animation Loading Fix? Disable and use only this? I've seen mrsrt saying to downgrade to 1.0 to maintain compatibility, but is it necessary? Are there any benefits to having both instead of just replacing it with this one?

 

And of course, thank you so much for your work towards solving this issue!

Yes, it's necessary. Since ver 1.1 the author of Animation Loading Fix is trying to expand the anim limit x2 and editing the same instruction as me in my patch. If you use both, dependent on dll load order, highly likely, you'll get CTD at some point. In ver 1.0 author only preloads animations and it's compatible with the patch. The original purpose for mods like Animation Loading Fix is to avoid FootIK error. You can alternate it with save preloaders like https://www.nexusmods.com/skyrim/mods/78557/? https://www.nexusmods.com/skyrim/mods/85443 they work differently, but was created to solve the same problem. I don't know, maybe save preloaders may also help to cure other startup ctds than only just FootIK error. Personally I use Continue Game No Crash.

 

3 hours ago, GenioMaestro said:

I have encountered a problem, but it is not directly caused by this mod, it is an indirect consequence.

I guess the same problem can happen when we use Animation Loading Fix.

 

The Creation Kit do CTD when we open any cell if we have a CTD% over 100% in FNIS.

The problem is not caused by this mod. Is caused by excesive animations inside the CK.

Yes, it's pretty possible, as the Creation Kit emulates the game engine and highly likely has duplicated code. In that case CK needs a patch too. Or simply decrease the anim count while you're creating something. 

 

58 minutes ago, Hawk9969 said:

...

I really don't have time and don't want to explian you how the render thread works and what's the cost of linear complexity increase during it. If you really think that freeing the render thread from hunderds of thousands or even millions iterations has no relation to fps then continue thinking so, or be a bit more smarter and learn yourself about the topic you're trying to dispute.

Link to comment
10 minutes ago, mrsrt said:

I really don't have time and don't want to explian you how the render thread works and what's the cost of linear complexity increase during it. If you really think that freeing the render thread from hunderds of thousands or even millions iterations has no relation to fps then continue thinking so, or be a bit more smarter and learn yourself about the topic you're trying to dispute.

God, another one with an ego being passively aggressive, but ok I'll bite.

 

First off, I did test it under 8k animations with no influence on either loading times nor fps, which I already said so, on a 6 years old CPU.

Secondly, those operations are extremely fast on any modern CPU as I've already stated, even if they are in the millions. Write a simple single-threaded checksum calculator and see how fast you will run it (and this will include the time taken for the kernel to initialize that program and allocate the stack). Each iteration in this case is very likely in the nano or micro seconds range for a modern CPU.

Furthermore, since the GPU will be used for graphics processing far more than the CPU, the render thread will await until the GPU is ready before doing further processing, which is the reason for my 6 years old CPU not getting hogged by the render thread.

You didn't even bother to tell which CPU you are running nor the performance gain you've experienced. You're just saying it's going to be there for everyone without any proof and disregarding modern x86 analytics, when in practice many users will experience those gain in the nano or micro seconds range.

 

You've also gladly ignored my suggestion to add a warning option, something that meh321 did for some of the fixes he wasn't sure about unknown behaviors.

 

And with all this being said, this is merely a comment addressed at the do while loop from the decompiled code. If it shows a different behavior elsewhere (positive or negative), I don't know.

Link to comment

You know you are right I should have posted some specs to back up my claim of FPS increase and would have been skeptical seeing anyone else spouting 20+ FPS improvements. (In my defense I was super hyped and was back in Skyrim shortly after the posts.)

 

My friends I give you my basic specs to see where I am coming from with my claim of 20+ now closer to 30 FPS increase in my Skyrim.

note: my FPS is not stable and when I run into a large battle / city I have dropped as low as 30 FPS but that was my top before so I feel so good seeing the little 60 FPS at the corner of my screen.

 

AMD FX 4100 Quad Core 3.6Ghz

8Gb RAM -- main board cant use more than 8 :(

Radeon 480 8Gb -- newest hardware still a few years old

Link to comment
14 minutes ago, majormagers said:

You know you are right I should have posted some specs to back up my claim of FPS increase and would have been skeptical seeing anyone else spouting 20+ FPS improvements. (In my defense I was super hyped and was back in Skyrim shortly after the posts.)

 

My friends I give you my basic specs to see where I am coming from with my claim of 20+ now closer to 30 FPS increase in my Skyrim.

note: my FPS is not stable and when I run into a large battle / city I have dropped as low as 30 FPS but that was my top before so I feel so good seeing the little 60 FPS at the corner of my screen.

 

AMD FX 4100 Quad Core 3.6Ghz

8Gb RAM -- main board cant use more than 8 :(

Radeon 480 8Gb -- newest hardware still a few years old

Yeah, that's older than what I've and it's running slower aswell.

 

I was never critizing the author nor his work, I was merely pointing out that people with more modern CPUs might not fall into the same anecdotes concerning the aforementioned performance gains (speaking entirely out of my own experience).

I do apologize to the author if it came as an attack on his work, which was not my intention at all.

 

Telling me to learn about x86 when I've been doing asm (not only in x86 but in other retro architectures aswell) for years was kind of rude, but meh. Hopefully I've made it clear to him that I am not attacking him nor his work and merely adding a "note" to it.

Link to comment
4 hours ago, Hawk9969 said:

God, another one with an ego being passively aggressive, but ok I'll bite.

If I'm not the first who said you that things maybe it's time to listen them? You don't read the thread, you don't understand the topic you're trying to speak and proving your words with information that have no relation to what you're trying say. What do you expect to hear?

 

I'll answer you one time.

FPS - means Frames-Per-Second. If you have 60 fps then each frame takes about ~16.7ms to be processed. Personally, I have and play with 144 fps it means my frames get ~7ms to be processed. 

Now I execute this code to emulate the skipped one with 28k anim objects (around 7.5k actual animations) and 30 npcs around:

Spoiler

long point_to_nanos(time_point<system_clock> point)
{
	return duration_cast<nanoseconds>(point.time_since_epoch()).count();
}

long loop(int anim_obj, int npcs_around)
{
	int var = 0;
	int* ptr = &var;
	int ctr = 0;
	time_point<system_clock> start = system_clock::now();
	for (int i = 0; i < npcs_around; i++)
	{
		for (int j = 0; j < anim_obj; j++)
		{
			*ptr = 0;
			ctr += 3;
		}
	}
	time_point<system_clock> end = system_clock::now();
	return point_to_nanos(end) - point_to_nanos(start);
}

int main()
{
	int const ANIM_OBJECTS = 28000;
	int const NPCS_AROUND = 30;

	float correction_ms = (float) loop(0, 0) / 1000000;
	float execution_ms = (float) loop(ANIM_OBJECTS, NPCS_AROUND) / 1000000;
	float delta = execution_ms - correction_ms;
	cout << "empty call correction millis: " << correction_ms << endl
		<< "execution millis: " << execution_ms << endl
		<< "delta: " << delta << endl;
}

 

 

With i7 6800k and 4-channel RAM I got these results:

empty call correction millis: 0.0057
execution millis: 1.78
delta: 1.7743

It means the code during render may get additional 1.8ms for frame processing. In result my frame process time can be 8.8ms instead of 7ms what's already 113 fps, 31 less. It means under several circumstances the patch may give me up to 31 fps with 28k anim objects and 30 npcs around, but it's not guaranteed and not everywhere, because during frame processing graphical render, AI, scripts and other parts of the game also take their time in the render thread (even if they work parallel in a different thread). If you want to understand why the patch gives or give not you fps boost at first you have to learn how these things work and not to give false statements here.

 

4 hours ago, Hawk9969 said:

You've also gladly ignored my suggestion to add a warning option, something that meh321 did for some of the fixes he wasn't sure about unknown behaviors.

What warning do you expect? Do you understand how register overflow works? If you put 33k in a signed short you'll get -31k, if you put 66k you'll get positive 1k. How do you expect to understand what value is correct? And CTD on loading is not enough warning for you? If you want to turn off the patch then remove the dll, what's the damn problem? Please, just stop this.

Link to comment
1 hour ago, mrsrt said:

If I'm not the first who said you that things maybe it's time to listen them? You don't read the thread, you don't understand the topic you're trying to speak and proving your words with information that have no relation to what you're trying say. What do you expect to hear?

No, you are the first one in that regard, the rest is merely an observation from how toxic the Skyrim modding community is (way too many egos).

This account name does not reflect the names I use on other modding and programming forums for privacy reasons, as such I could care less about my reputation in here.

34 minutes ago, mrsrt said:

What warning do you expect? Do you understand how register overflow works? If you put 33k in a signed short you'll get -31k, if you put 65k you'll get positive 1k. How do you expect to understand what value is correct? And CTD on loading is not enough warning for you? If you want to turn off the patch then remove the dll, what's the damn problem? Please, just stop this.

What? Anything above 0x7FFF is a negative in a signed short.

unsigned short a = 0xFFFF; // All 16 bits set.
signed   short b = a; // Putting 65535 in a signed short.

printf("%hu\n", a); // 65535
printf("%h\n", b);  // -1

And here is how you can skip the code if you are not expecting a negative value:

movsx eax, word ptr DS:[esi+A8]
test eax,eax
js skipCode // Negative as movsx sets the higher bits with the MSB.

The whole point of the warning is to let the user know whether his game is affected by this specific overflow or not rather than just fail silently when the behavior can be unknown. There are other crashes when loading a game after all.

 

As for another anecdote, you're trying to run at 144 fps but I am trying to run at 60 fps, like most people; And I already said that, my CPU is waiting for the GPU to be ready, so that couple of mses wasted in here would be wasted anyway waiting for my GPU to have finished rendering.

Not sure whether it's arrogance or not, but you clearly don't want to admit that the performance gain is situational and dependent on hardware, which is exactly what I've been saying from the start. Obviously, removing code will end up with faster executions times, but how fast is that and where it applies is situational in this case.

 

But whatever, this seems like a huge waste of time on my part as I've already stated there is no gain in performance for me and I do not run more than those 7.5k animations.

I'll just stop here as you've asked.

Link to comment
On 12/10/2019 at 3:33 PM, fore said:

 

It's not really that easy. I cannot simply remove the limit, change a few parameters and everything is ok. FNIS wasn't designed to be extended indefinitely (actually it all started with hundred lines of Excel script). And every time I extend the limit it takes 2 or 3 releases to figure out which one of the dozens of arrays might overflow as well.

 

And it will also effect performance drastically. Especially for users with "potatoes".

 

This game is 8 years old, and user have learned to live with 11 to 13k. If they have 26k now it is twice as much. Or more, when I make it a round 30k. But isn't that REALLY enough?

You already know the answer to that is no. Vanity mods are not like other modding endeavors and they are the direct opposite of mechanical and utility mods and what you don't seem to get still is while your mod performs a utility and direct mechanical function it is itself a vanity mod that directly encompasses and provides a direct framework for other vanity mods. The end, period. Vanity mods by definition have no limit:

 

16K skins

64K bodies with hundreds of nodes

128K+ multimesh armors over those other naked armors

shit tons of bones attached to those nodes

shit tons of NPCs utilizing all of that

animation made at 240/360 fps for absurd smoothness regardless of base framerate

 

these are all things that are part and parcel legerdemain for vanity mods and your mod is a direct component in that environment.

 

If a user installed every mod with animation available here, the limit is well over 30K, for all I know funnybizness by himself has already passed that limit much less anyone else.

 

 

Link to comment

Once again...

58 minutes ago, Hawk9969 said:

No, you are the first one in that regard, the rest is merely an observation from how toxic the Skyrim modding community is (way too many egos).

If you come to every technical thread like you did here I'm not surprised in your perspective of view. Furthermore, I wasn't trying to be offensive, I just don't want to spend another couple of hours in disputes like it was in my previous thread, but you take it as confirmation of your "ego idea".

 

1 hour ago, Hawk9969 said:

This account name does not reflect the names I use on other modding and programming forums for privacy reasons, as such I could care less about my reputation in here.

As many others, included me. What's the point in this message?

 

1 hour ago, Hawk9969 said:

What? Anything above 0x7FFF is a negative in a signed short.

Spoiler

int main()
{
	short coming_anims = 0;
	int const OFFSET = 0x7FFF;
	cout << coming_anims << " + " << OFFSET << " = ";
	coming_anims += OFFSET;
	cout << coming_anims << endl;

	cout << coming_anims << " + " << 1 << " = ";
	coming_anims += 1;
	cout << coming_anims << endl;

	cout << coming_anims << " + " << OFFSET + 1000 << " = ";
	coming_anims += OFFSET + 1000;
	cout << coming_anims << endl;
}

 

 

0 + 32767 = 32767
32767 + 1 = -32768
-32768 + 33767 = 999

 

1 hour ago, Hawk9969 said:

The whole point of the warning is to let the user know whether his game is affected by this specific overflow or not rather than just fail silently when the behavior can be unknown. There are other crashes when loading a game after all.

Is it that hard to check crashfix log with exception address and compare the code with one, mentioned in the first post? Well, thanks for suggestion, but I see no logical profit in creating such stuff. 

 

1 hour ago, Hawk9969 said:

Not sure whether it's arrogance or not, but you clearly don't want to admit that the performance gain is situational and dependent on hardware, which is exactly what I've been saying from the start.

Is it some kind of joke? I said this to you with my first answer. 

On 12/18/2019 at 4:32 AM, mrsrt said:

If you didn't see the difference, then, probably, your fps is capped, or you have an extremely heavy graphic preset under which the difference cannot be noticed. Don't expect something like "+20 fps and instant loadings for everyone", the impact completely depends on your hardware and game setup. If you really want to see difference, use some very lightweight enb preset (or enboost) together with uncapped fps and not the fastest CPU.

After which you started the topic about function complexity and CPU/GPU usage.

 

If you want to continue this dialogue contact me with PM, I'll answer you when I have time. For now, I'll ignore your further messages related to the dispute in the thread. And this is not the "big ego confirmation", I just can't continue this topic with walls of text right now and don't want to trash the thread.

Link to comment

I dont think anybody here is interested in FPS gains mainly but in the increase in animation limit. 

I run this on i5 750 with GTX 660Ti and 12 GB Ram. A undead potatoe. 

 

I still had New Game CTD when I did not close my browser (background processes). I did not notice any faster game booting. 
I did not notice a FPS boost.

With background (browser) closed the new game loaded as always. 

 

But neither of that is relevant if I will be able to use more animations (have yet to push that limit, one at a time, haha). I made the first adjustments to see if I feel a significant change in my game with only adding this patch. Animation limit push will be next. 

 

Link to comment

My investigations say that the CTD caused by Excesive Animations is generated in the render process and that match with all the investigations of mrsrt because the Creation Kit have the same CTD caused by the same motive but only shown when we start the render window showing a cell.

When we open the tab animations in the Actor Editor the CK analize every behavior file and show every animation registrered in every animation pack but not make CTD.

The CTD by Excesive Animations happend only when the render is active.

 

In that way, the patch can affect the render process and some users are reporting an increase in FPS but that only can happend when the CPU is at 100% ussage. Every task removed from the CPU, like a simple loop, mean less works for the CPU but that decrease of work is not noticeable if the CPU is not in 100% ussage.

 

I notice a reduction in the time need to load the first savegame because i use Load Game CTD Fix that put the CPU in 1 single core while load the savegame. As my game is running in only 1 of my 4 cores my CPU ussage is from 25% to 30% but the core 1 is at 100% and the loop that the patch eliminate give me a boost, but only while i load the savegame.

While i play my 4 cores are actives and my CPU have an average ussage of 50% with a maximun of 80-85% and i not notice any increment in the FPS because i have a very weak graphics card, a simple GTX 660 2gb, and my CPU is waiting for my GPU end their work, but i notice less CPU ussage.

 

Normally, 99% of the players not have the CPU at 100% usage and 99% of the players can not notice a increment in FPS because, as others technicals players say, the CPU have free time and is waiting for the GPU and the FPS not change. The only noticeable thing can be lower CPU ussage, because the patch remove a loop, but that only can be noticed when we made a detailed analisys.

 

Only specific players that not use FPS limiters or have very weak machines with the CPU in constant 100% usage can notice a increment in frame rate.

Link to comment

SSE version released

Beta version of the patch for Skyrim Special Edition released. Patched the same point, behavior shouldn't differ much from the LE version. If you find something weird after installation, please, notify me and other users with a post in the thread. 

 

 

Link to comment

Let me add a couple things here.

First, the code I'm posting is the output of those two functions you posted earlier, except taken from Ghidra and from SE 1.5.80. I've modified and annotated it to make it more understandable. It also explains what the cause of the crash is.

ulonglong FUN_140b66930(longlong param_1,hkbCharacter *param_2,undefined8 param_3) //BE6C50
{
  char cVar1;
  byte bVar3;
  ulonglong uVar4;
  float fVar5;
  undefined4 local_a8;
  undefined4 local_a4;
  ushort local_a0;
  undefined2 local_9e;
  undefined8 local_98;
  undefined local_90 [8];
  undefined local_88 [48];
  undefined local_58 [80];
  
  local_98 = -0x2;
  FUN_1409eee90(local_58,param_2,0,0,0);
  hkbBehaviorGraph* graph = &param_2->behaviorGraph;
  cVar1 = (byte)(param_1 + 9);
  local_a8 = 0x3f800000; // (float) 0x3f800000 = 1.0
  local_a4 = 0x3f800000; // (float) 0x3f800000 = 1.0
  local_a0 = (bool)(cVar1 != 0);
  local_9e = 0;
  if (!lVar2) {
    return 0;
  }
  else {
    fVar5 = DAT_1415232e8; // (float) 0x3f800000 = 1.0
    if (!graph->isActive && !cVar1) {
      return 0;
    }
    else {
      if (!cVar1) {
        fVar5 = DAT_14174cd50; // (float) 0x3d23d70a = 0.04
      }
    }
    // Vanilla
    /*  (1)
        the cast from short to uint uses MOVSX (read: move sign extend)
        ie. a negative value gets padded with 1's in front.
        Therefore, after casting the negative value, it does not 
        represent the intended integer value
    */
    FUN_140b66bb0(local_88,(longlong)((float)(uint)*(short *)graph->numStaticNodes * fVar5));
    // with Engine Fixes: AnimationLoadSignedCrash = true
    /*
        This uses MOVZX (read: move zero extend)
        FUN_140b66bb0(local_88,(longlong)((float)(uint)*(ushort *)graph->numStaticNodes * fVar5));
    */
    bVar3 = FUN_140b66de0(local_58,param_1,param_3,lVar2,&local_a8,local_90);
    FUN_140b66ce0(local_88);
    uVar4 = (ulonglong)bVar3;
  }
  return uVar4;
}


longlong FUN_140b66bb0(longlong param_1, uint param_2) //BE6D80
{
  uint uVar1;
  int iVar2;
  undefined8 uVar3;
  longlong lVar4;
  undefined8 *puVar5;
  uint uVar6;
  
  lVar4 = 0;
  uVar6 = 0;
  if (param_2 != 0) {
    // min(uVar2) st. 2^uVar2 >= param_2
    // this calculates the maximum size of the array at (2)
    if(param_2 > 1) {
        for(uVar2=31, uVar6=1; uVar2>0; uVar2--) {
            uVar6 *= 2;
            if(uVar6 >= param_2) break;
        }
    }
  }

  // <some uninteresting stuff>
  param_1->4 = uVar6;
  param_1->0x10 = 0x141e009ec;
  param_1->8 = uVar6;
  param_1->0xc = uVar6;
  if (_DAT_141ebd708 != 2) {
    FUN_140c026d0(&DAT_141ebd280,&DAT_141ebd708);
  }
  uVar3 = FUN_140c01800(&DAT_141ebd280,0);
  param_1->0x18 = uVar3;
  if (param_2 != 0) {
    lVar4 = FUN_140c034a0(param_1->0x18,(ulonglong)(param_1->4) * 0x18,8);
  }
  param_1->0x20 = lVar4;
  if ((param_2 != 0) && (lVar4 != 0) && (param_1->4 != 0)) {
  // </some uninteresting stuff>
    // gets interesting here
    unk24* puVar5 = lVar4->0x10; // array with elements of size 3*8 bytes with a max capacity of uVar6 entries
    for(int i = uVar6-1; i >= 0; i--) {
      /* (2)
          crashes here, because the value passed in param_2 exceeds
          the actual size of the array when a sign extended negative
          value was passed at (1), which lead to an oversized bound 
          in uVar6
          ie. memory at lVar4->0x10[uVar6-1] is not mapped
      */
      puVar5 = lVar4->0x10[i];
      puVar5.0 = 0;
    }
  }
  return param_1;
}

The root cause of this problem is, that bhkBehaviorGraph->numStaticNodes is marked as a short in code, when it should have been a ushort instead. It's quite clear that there is no scenario where it would make sense for that value to be negative.

You can have a look at what Ryan found out about hkbBehaviorGraph over here: https://github.com/Ryan-rsm-McKenzie/CommonLibSSE/blob/master/include/RE/hkbBehaviorGraph.h

 

About that look at the bottom, I believe(guess) it is resetting some kind of reference count, but it does not seem super important. However the stuff I put in the <some uninteresting stuff> tags might still be. That's why I would not recommend skipping the entire code block without having a general idea of what it does. I would be very surprised if the loading code corrupts the save file or anything, so if it doesn't crash it's probably not critical, but it is possible that it creates random crashes or memory leaks during the game if this code is not run.

 

Further, I wonder if going over 200-250% CTD in FNIS will actually load all animations. After all, numStaticNodes has a max value of ‭65535 (2^16)‬, and it does get used in other places. If it gets used to index these animations, the number is still limited, you just won't CTD on load anymore, regardless of using your mod or Engine Fixes. You'd just be missing a lot of animations because the game couldn't keep track of them. But if the game still loads everything past, say, 250% we should be fine until at least 2^31 nodes and numStaticNodes was only there to make Havok happy and generate crashes

Link to comment
1 hour ago, CakeTheLiar said:

Let me add a couple things here.

Thank you, good work, it's clarifying many things.

 

1 hour ago, CakeTheLiar said:

That's why I would not recommend skipping the entire code block without having a general idea of what it does. I would be very surprised if the loading code corrupts the save file or anything, so if it doesn't crash it's probably not critical, but it is possible that it creates random crashes or memory leaks during the game if this code is not run.

The movsx -> movzx patch already exists in Animation Loading Fix v1.1, I found that after already created my solution. 

As for consequences, I had the same thoughts as you and did several tests to check every possible side effect of the patch including:

- Memory consumption comparison while the chracter stands in the same place for several hours.

- Memory consumption comparison while running throughout Skyrim with very high speed.

- Script stressing.

- Usual play for several dozens of hours.

No test shown any kind of memory leak, additional crashes, bugs or gamesave corruption. For now the patch was already downloaded about 5k times in total, 2 weeks passed since LL release, and no negative reports so far. This makes me belive that the code is redundant and/or can safely be skipped with no negative side effects. However, you're right, it's possible the consequences just wasn't yet discovered, the question is what's the price. For me the performance boost that gave me the patch is important. However, if the price is big the ready solution with unsigned short already completed, as I mentioned above.

 

2 hours ago, CakeTheLiar said:

You'd just be missing a lot of animations because the game couldn't keep track of them.

Well, then it is possible to be my next patch ? 

 

P.S. I didn't provide the SSE reverse data yet, the exception point and overall picture there a bit different. I'll publish it here a bit later.

Link to comment

SSE Reverse Info

In SSE case, exception happens in the different place:

Spoiler

824502137727ff37b99e7cd864a3.png

RVA: B66A72, FO: B65E72

 

00007FF618EF6A72 | 48:837CC2 10 00          | cmp qword ptr ds:[rdx+rax*8+10],0       |

Access violation while trying to read the pointer value. At first, it was looking like a completely different place and a completely different problem, I started to debug it. Simple skipping the function or some specific place inside leads to infinite loading. 

The problem was in RAX register, normal and broken call value comparison:

00000000E0B0CA76 <- okay

00000002FDBC7957 <- crash

 

I started to move upper by call stack and found the masterpiece function by Bethesda developers from where the previous one was called:

Spoiler

728f232f5c90f50e9212c975d40e.png

RVA: B66EF0, FO: B662F0

 

(The header on Nexus I captured exactly from the function, lol)

Attempts to patch the place was also led to infinite loadings. The only real solution left is to find the origin of the value. I moved further.

 

And eventually found very familiar places:

Spoiler

1308ce8b46f4e2460a57cf8cacc4.png

RVA: B669DC, FO: B65DDC

 

a726c8606a228de1c68815b6232d.png

RVA: B66BB0, FO: B65FB0

 

This is the same code as I patched for LE version, but with several changes. One of the most important: the pointer in the loop is static now. Now it looks like some counter increasing. Static pointer helped to pass the previously problematic place, but broken value caused CTD further. Another important moment: value casts to integer, not to short. I bet Bethesda devs tried to fix the CTD, but they didn't know what exactly caused the problem or where it takes its origin.

 

Btw, I found the same point, patched it the same way and got the same result, as expected: everything works.

00007FF618EF69C0 | 0FBF83 28010000          | movsx eax,word ptr ds:[rbx+128]         |

RVA: B669C0, FO: B65DC0

 

Link to comment
16 hours ago, CakeTheLiar said:

Further, I wonder if going over 200-250% CTD in FNIS will actually load all animations. After all, numStaticNodes has a max value of ‭65535 (2^16)‬, and it does get used in other places. If it gets used to index these animations, the number is still limited, you just won't CTD on load anymore, regardless of using your mod or Engine Fixes. You'd just be missing a lot of animations because the game couldn't keep track of them. But if the game still loads everything past, say, 250% we should be fine until at least 2^31 nodes and numStaticNodes was only there to make Havok happy and generate crashes

You guys are discussing wonderful things. Unfortunately I do not have the time right now trying to understand all of it. But one thing came into my mind immediately when I read about your 200-250% assumption relative to current FNIS load count..

 

If you are right, and the max number would simply be doubled., then it might be that the new limit is even higher than 200-250%. Keep in mind that we only measure the effects on custom animations, and we don't know what the base impact by vanilla animations already is.

 

Now the number of vanilla animation isn't that high (only about 1650 3rd person character), which by itself wouldn't even justify those increase from 200 to 250%. But this limit isn't an animation limit, it's a "behavior limit", and "other" behavior features have big impact as well. Some of which which we might even not know of. And the ones which we know of are much more used in vanilla, than they are in FNIS generated/modified behaviors, e.g.:

- number of behavior files

- number of animation variables

- re-use of animation files in different clip generators (each vanilla animation file is used about 2.5 times in the behaviors -> approx. 5000 vanilla clip generators)

 

Has someone checked the value of this variable in a totally vanilla environment? Would be VERY interesting to know.

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

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. For more information, see our Privacy Policy & Terms of Use