Jump to content

Devnote Tuesday: Smashing Buttons


SQUAD

Recommended Posts

3 hours ago, StahnAileron said:

...

So I ask you: what kind of home would you prefer?

I like my house build solid and I want to know it will last a while, with the basic services installed. Once that is achieved I want some furniture and some luxuries. 

We have waited patiently for a very long time for KSP to be on a stable version of Unity and for the product to be stable. We are there now. So it's time to add some fun stuff rather than forever tinkering with the existing code. 

Link to comment
Share on other sites

31 minutes ago, Foxster said:

I like my house build solid and I want to know it will last a while, with the basic services installed. Once that is achieved I want some furniture and some luxuries. 

We have waited patiently for a very long time for KSP to be on a stable version of Unity and for the product to be stable. We are there now. So it's time to add some fun stuff rather than forever tinkering with the existing code. 

Except were not there just yet. Orbits are wonky, wheels and landing gear are wonky, landing legs are wonky, docking is wonky, asteroids are wonky, the editor is wonky, the surface of the planets are wonky, and apparently there is some wonky code under the hood that the codeheads are trying to square up. 

 

Theres a lot of wonkiness to sort out still, is what I'm saying. There's progress, but we're not there quite yet. 

Link to comment
Share on other sites

48 minutes ago, Foxster said:

I like my house build solid and I want to know it will last a while, with the basic services installed. Once that is achieved I want some furniture and some luxuries. 

We have waited patiently for a very long time for KSP to be on a stable version of Unity and for the product to be stable. We are there now. So it's time to add some fun stuff rather than forever tinkering with the existing code. 

It will be far easier for the devs to add new content and maintain the stability you desire if they do so on top of clean code. The end product may be pretty stable for many users, but as is mentioned in these and other devnotes the code is full of inefficiencies, work-arounds, and left-over junk that can be as harmless as extra lines to have to work around to as bad as creating new and interesting crash-inducing bugs whenever new content is introduced.

 

New content will probably be much simpler and quicker to implement when the code is cleaned and made more manageable. Optimizing the code now will help the end result run better when more content is piled on. I think everyone, devs included, would love to see new things being added to KSP, but I think most people can agree that it would be best to add the new, shiny, clean code to code that has been carefully cleaned and polished with continuing development in mind.

Edited by Mako
Link to comment
Share on other sites

9 hours ago, NathanKell said:

Yep! Order of preference is:

for(int i = foo.Count/Length - 1; i >= 0; --i) // this saves a STO

followed by

int fC = foo.Count/Length;

for(int i = 0; i < fC; ++i)

and only then by other for styles let alone foreach.

Having not seen a for loop in quite some while your statement actually startled me for a moment. While you are, of course, correct it is astounding how different circumstances influence the use of the same language even if it's one where you don't have full control of the machine code.

This for vs. foreach discussions is a great example: I am on a strict foreach-only policy where even classic counting loops have to use something like foreach (var pos in Enumerable.Range(0,10)) which would not be a good idea at all in your case.
While this approach may seem strange the reason behind it is quite sound: the moment you have database access, service calls (maybe even over the network), general IO, everything regarding allocations and gc (except for maybe the LOH in special cases) becomes practically free. So the only concern is to be as expressive as possible also if you consider that hardware is cheap, but dev hours are painfully expensive so maintainability has to be as high as possible.

Anyway, since LINQ is the closest C# has to a piping workflow I feel for you not being able to use it. I'm sure you did tests and if you feel the performance impact is worth bloating the code I believe you since nobody would attempt that without very good reasons :wink:

Link to comment
Share on other sites

9 hours ago, nightingale said:

Sigh.... I've been putting off de-linq-ing and foreach killing in Contract Configurator for ages.  I suppose I've put it off long enough.

It does get very bad if you have a lot of contract packs installed.  This user is having peaks of garbage creation of over 256 MB/s...

Even my stutter reduction feature in MemGraph has a hard time improving things much when there's that sort of garbage rate...

33 minutes ago, marce said:

Anyway, since LINQ is the closest C# has to a piping workflow I feel for you not being able to use it. I'm sure you did tests and if you feel the performance impact is worth bloating the code I believe you since nobody would attempt that without very good reasons :wink:

Yes, they (and countless other developers of Unity games and the Unity devs themselves) have run tests and in-depth diagnosis of the resulting generated code and there is absolutely no doubt that use of foreach (in many cases) and LINQ generates lots of garbage and is also generally less CPU efficient than writing the code the "bloated" way.

Link to comment
Share on other sites

Ah, the life of a game publishing studio...

When SQUAD pushes out new features, it gets vocal people saying, "New features are nice, but I wish you'd fix things so they'd be stable!"

When SQUAD fixes things for stability, it gets vocal people saying: "Stability is nice, but I wish you'd push out new features!"

Shine on, all you crazy, lovely people.

Link to comment
Share on other sites

1 hour ago, Jovus said:

Ah, the life of a game publishing studio...

When SQUAD pushes out new features, it gets vocal people saying, "New features are nice, but I wish you'd fix things so they'd be stable!"

When SQUAD fixes things for stability, it gets vocal people saying: "Stability is nice, but I wish you'd push out new features!"

Shine on, all you crazy, lovely people.

To be fair, there has only been 1 vocal person saying "Stability is nice, but I wish you'd push out new features!", and I think that voice was fairly well answered by a grand majority of the thread saying the exact opposite.  In this case, the grand majority of the thread is correct in stating that SQUAD should take it's time and fix their stuff before moving on and adding more and sometimes the community at large isn't thinking overly clearly in their request for more new shiny stuff.  In the last 2 updates we've got quite a but more stuff, even though it is somewhat overlooked as some of it is under the hood; the biggest one being a whole new up-to-date version of the Unity engine which pretty much required a re-write/re-integration of the game with the engine.

This particular situation leads me to think of a John Lydgate (later adopted by Lincoln) quote:
“You can please some of the people all of the time, you can please all of the people some of the time, but you can’t please all of the people all of the time.”

I'm very excited to see the progress that is being made myself.  Good job SQUAD and keep on keepin' on!

Link to comment
Share on other sites

12 hours ago, nightingale said:

Sigh.... I've been putting off de-linq-ing and foreach killing in Contract Configurator for ages.  I suppose I've put it off long enough.

Boy do I feel for you!

In my new mod (PersistentDynamicPodNames), which I haven't even released yet, and is much less complex than CC, I have over 100 "foreach" loops.  A few of them can be left, since they are only used one time at initialization, but the rest.....

Yuck!  And I haven't even released this yet!

I wasn't aware of the issues with "foreach".  I like it because it makes the code simpler, but if it contributes to the lagging, I'll be working on removing them from all my mods.  gonna take some time though

Link to comment
Share on other sites

11 hours ago, Arsonide said:

We will be looking at wheel stability in 1.2,

Hi Arsonide.

 Do you know if wheels will ignore collision to their parent craft in 1.2? This has caused a lot of broken wheels in many situations but I have not heard anyone mention the collision issue, only that blocking will be gone. Cheers!

Link to comment
Share on other sites

9 hours ago, NathanKell said:

just myList[ i ]

 

Also per what @Shadowmage said it's better not to recheck the Count each time, that's why my two examples you quoted in each case referenced Count only once. I said Count/Length in the hope that it would be clear that the examples I provided worked equally for Lists and Arrays respectively.

Ok, another question:

I have the case where I have a list of parts. The original foreach looks like this:

foreach (Part part in Utils.getPartList(pm2)) 
{
    if (part.Modules.Contains<ModuleEngines> ()) {

Replacing this with:

List<Part> pl = Utils.getPartList(pm2);
for (int i = pl.Count - 1; i >= 0; --i)
{
    if (pl[i].Modules.Contains<ModuleEngines> ()) {

the code references the part in multiple locations, as you can see by the if statement.  So, is it more efficient to use the index pl or to do the following:

for (int i = pl.Count - 1; i >= 0; --i)
{
    Part part = pl[i];

    if (part.Modules.Contains<ModuleEngines> ()) {

 

Link to comment
Share on other sites

I literally just spent around 2 hours last night working out how foreach statements work so i could implement them into the GUI for a plugin i've just started making (literally no C# experience before now).

O well i suppose it's better to find a new way now than once the project is finshed! i really feel for you guys who have to go back and change this!

Link to comment
Share on other sites

On the topic of Scrum, just remember that "sprint" means to move so fast that the pace cannot be sustained. You need to rest in between sprints, or team members will crash and burn.

Also, the single most productivity-enhancing technique is the one that's the hardest to sell to managers, because it's counter-intuitive: have only one keyboard and mouse for the whole team (up to 5 people), and all work together.

(Interesting that Squad is starting to use Scrum when all the cool kids are starting to abandon it.)

Link to comment
Share on other sites

Scrum is still up and coming. 

and the term "sprint" is not quite as what you said:

A scrum sprint is a regular, repeatable work cycle in scrum methodology during which work is completed and made ready for review. Scrum sprints are basic units of development in the scrum methodology. Generally, scrum sprints are less than 30 days long.

Link to comment
Share on other sites

5 minutes ago, linuxgurugamer said:

@dboi88

Keep in mind that this is being done for efficiency.  It is actually bad coding, and makes the code a bit harder to understand.  The "foreach" statement was made for a reason, it's just a shame it's been so badly implemented

Just to make sure i understand. Is this statement correct?

'ForEach is the correct method, but due to bad implementation in Unity the increased efficency of using For outweighs the increased coding complexity'

Link to comment
Share on other sites

I just want to add that while foreach certainly does make coding a lot simpler for things like lists (and oh, how I wanted it in C when doing a lot of work with sets in a compiler), that simplicity comes at a cost that has nothing to do with implementation: flexibility. Really, it's a trade-off between the two (ie, flexibility vs simplicity/readability).

Link to comment
Share on other sites

58 minutes ago, dboi88 said:

Just to make sure i understand. Is this statement correct?

'ForEach is the correct method, but due to bad implementation in Unity the increased efficency of using For outweighs the increased coding complexity'

Basically, yes, except that it's the bad implementation in the version of Mono that Unity uses rather than in Unity itself.  The same garbage issues do not occur when using a more modern implementation as long as the enumerator object is declared as a struct (a bit simplified but that's the general rule, e.g. the List<T>.GetEnumerator function returns a struct) because it is then allocated on the stack rather than on the heap.  The old version of Mono ignores the fact it's a struct and allocates it on the heap anyway.

The plain "for" method will always be slightly more efficient than any enumerator object based mechanism as two function calls are required to the enumerator object each time around the loop (one to get the current item and one to move to the next).  The difference is not very large but it can be significant in some cases, e.g. for large nested loops with a very small body the extra function calls can be a significant chunk of each iteration.  There is also an argument for avoiding List<T> in some situations and using a plain array instead as doing:

list[i]

...results in a function call that internally just does:

array[i]

This can also be measured in some situations.

Edited by Padishar
Arrgh, be consistent, either allow BBCode or don't, not this half-way house that just causes problems...
Link to comment
Share on other sites

@linuxgurugamer: I know what Scrum sprints are in theory. In practice, senior executives hear the word "sprint" and translate it to "working really fast and hard", and that's what they try to get people to do. It's a poorly-chosen word.

If you work in a place where the tech managers are able to resist business pressures of this sort, you are lucky.

Link to comment
Share on other sites

54 minutes ago, dboi88 said:

Just to make sure i understand. Is this statement correct?

'ForEach is the correct method, but due to bad implementation in Unity the increased efficency of using For outweighs the increased coding complexity'

Bad implementaiton in the c# compiler, not unity.

and instead of "correct", I would say "preferred" in terms of maintainability and readability.

16 minutes ago, Padishar said:

Basically, yes, except that it's the bad implementation in the version of Mono that Unity uses rather than in Unity itself.  The same garbage issues do not occur when using a more modern implementation as long as the enumerator object is declared as a struct (a bit simplified but that's the general rule, e.g. the List<T>.GetEnumerator function returns a struct) because it is then allocated on the stack rather than on the heap.  The old version of Mono ignores the fact it's a struct and allocates it on the heap anyway.

The plain "for" method will always be slightly more efficient than any enumerator object based mechanism as two function calls are required to the enumerator object each time around the loop (one to get the current item and one to move to the next).  The difference is not very large but it can be significant in some cases, e.g. for large nested loops with a very small body the extra function calls can be a significant chunk of each iteration.  There is also an argument for avoiding List<T> in some situations and using a plain array instead as doing list results in a function call that internally just does an array.  This can also be measured in some situations.

That is an excellent explanation, thank you for putting it so clearly

18 minutes ago, joebopie said:

well 1.1.3 crashes (CTD) after an hour or two for me. but there are no logs being written by ksp.

certainly doesn't seem stable to me sadly.

Are you looking at the KSP.log or the output_log.txt file?

KSP.log doesn't show everything.  Check the KSP_Data/output_log.txt (for 32 bit) or KSP_x64_Data/output_log.txt (for 64 bit)

Link to comment
Share on other sites

7 minutes ago, linuxgurugamer said:

Bad implementaiton in the c# compiler, not unity.

[...]

Not the compiler, the runtime. And Unity is to blame (at least for a big part) because they keep using this stone-age version of Mono instead of paying Miguel (now that would be MS I suppose) for a new one.
Anyway, I think I read something about Unity working on a .NET Native like project to improve performance.

Link to comment
Share on other sites

10 hours ago, marce said:

Anyway, I think I read something about Unity working on a .NET Native like project to improve performance.

There are two things that Unity are doing.  The one you are probably referring to is IL2CPP but, if my understanding is correct, this is unlikely to be used by KSP because it is mostly a build time process that converts the compiled c# code into C++ source code which is then compiled.  This will make modding very much more difficult, if not impossible.

The other thing they are doing is investigating updating the version of Mono that is used.  There has been a reasonable amount of activity in this direction on Unity's fork of Mono.  I doubt we'll see it very soon but it should improve this specific issue (the later versions of Mono do allocate struct iterators on the stack), shouldn't stop mods from working and should improve performance and support for some of the newer stuff in .NET4 and later...

Edited by Padishar
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...