Poll of the Day > Anyone here familiar with HSHL shaders? (basic question)

Topic List
Page List: 1
Yellow
04/08/20 9:09:23 PM
#1:


I'm trying to do this overlay with a texture, textures of varying height and width.

https://i.imgur.com/mUvDhIZ.png

Using this fx file

https://github.com/jamieyello/DownUnder-UI/blob/master/DownUnder.UIEditor/Content/shader.fx

I have it set up at the moment to set the texture to grayscale, the only thing I need help with is to pass the width and the height of the texture I'm drawing to the shader. Right now I can do everything else, if I can find a way to specify the width and the height I can implement the effect I need.

Atm the best I can do is to stretch the overlay, but I want all the borders to be the same width and height.

---
... Copied to Clipboard!
Yellow
04/08/20 9:28:59 PM
#2:


Turns out SV_POSITION is in pixels, not percentage. Idk why I assumed it was percentage. That's my problem solved for now? I still need to know how to pass parameters for other reasons.

https://gamedev.stackexchange.com/questions/44403/in-hlsl-pixel-shader-why-is-sv-position-different-to-other-semantics

This stuff is annoying because there's no manual debug output, so it's hard to really tell what's going on. I kind of like the simplicity though, though it doesn't seem like very many people know how to write shaders.

I wonder if you could write a whole game on a shader?

---
... Copied to Clipboard!
Sahuagin
04/08/20 9:48:11 PM
#3:


been a while since I've done much 3d or game programming. I've had a few false starts getting into shaders but never got anywhere.

Yellow posted...
Turns out SV_POSITION is in pixels, not percentage.
not sure, but it does seem to make some sense considering a pixel shader depends on (as far as I know) the color of each individual pixel. (so like, you can refer to neighbouring pixels by adding +/-1 or +/-2 or whatever) (but I don't know enough about how it works).

---
... Copied to Clipboard!
Yellow
04/09/20 12:25:06 AM
#4:


Cool, I might make a game of life shader for fun. Or an AI. I wonder how unoptimized AI is in it's current state? I can train 50 neurons overnight, that doesn't seem right.

First I have to finish this UI and make it nice. I have another question for you now that you're here (these topics are basically directed at you anyway), if you don't know it that's fine, you don't have to do my research, but is there an easy way to draw opaque graphics? I want to have opaque windows in my UI system. There's is a way to make windows forms transparent given a single color, but not opaque.

---
... Copied to Clipboard!
Sahuagin
04/09/20 12:33:33 AM
#5:


what do you mean by "opaque"? windows are already opaque.

---
... Copied to Clipboard!
Yellow
04/09/20 12:39:30 AM
#6:


Sahuagin posted...
opaque
I didn't know what that word meant, so there's that. Translucent, that's probably why I can't find the answer.

---
... Copied to Clipboard!
Sahuagin
04/09/20 12:49:40 AM
#7:


set Opacity to a value between 0 and 1 seems to do it. I don't usually use that feature.

there's also an AllowTransparency property but I don't seem to need to set it to get it working (I might have set something up elsewhere though)

---
... Copied to Clipboard!
Yellow
04/09/20 1:25:23 AM
#8:


Yeah windows forms translucency is pretty lacking, there's only TransparencyKey, a green screen effect, and opacity, which effects all graphics on the window.

I basically need Monogame to revamp their rendering code or modify it myself. Or just hide the window altogether and redraw the backbuffer to something else I have control over. I think that's the best choice.

Monogame does have the questionable design choice of freezing all rendering when the window is being moved, erasing all graphics that are dragged off screen at any point.

---
... Copied to Clipboard!
Sahuagin
04/09/20 1:51:23 AM
#9:


you might be able to put a custom control that you manually paint into the client area of a form, and then put all of the form's controls into that custom control and have them render on top. (or just into the form with everything in front). not sure if that'd work.

you could also try making the form more or less invisible (ie: borderless), and render its client area 100% manually. not sure how easy or not it would be to still have other controls appear on top.

generally, modifying the way that windows forms controls are rendered does not work very well and you end up having to render everything yourself from scratch. just something as simple as color coding the items in a combobox ends up being exceedingly difficult and you're basically better just writing your own combobox from scratch.

---
... Copied to Clipboard!
Yellow
04/09/20 2:09:15 AM
#10:


Sahuagin posted...
you could also try making the form more or less invisible (ie: borderless), and render its client area 100% manually. not sure how easy or not it would be to still have other controls appear on top.
That's what I'm thinking of right now. I think Monogame is just a Windows Form with a single viewport, which would make that a very easy thing to do, I don't have to worry about re-drawing anything but that. I'll have to look into this later though. This is very low priority atm, I should just find out if it's possible.

I do want to keep the Monogame library as Monogame.Exended and Monogame in general is excellent.

If I get to the point where my project is really promising from anyone else but me, aka not just this guy's cute project but the a real viable commercial competitor, they might listen to me if I badger them into fixing the archaic rendering code they've been using as the base of their project since the beginning of time.

It's looking like WPF is the solution, I can use Google now that you've corrected my grammar.

---
... Copied to Clipboard!
Sahuagin
04/09/20 2:41:11 AM
#11:


Yellow posted...
It's looking like WPF is the solution
I was thinking of suggesting it, but I didn't know till just now that it's based on DirectX and not GDI/GDI+... that definitely sounds like the direction to go to get better control of rendering Windows UIs.

I wish I realized it was based on DirectX a long time ago. I've been meaning to switch to it when possible, but being based on DirectX should make it substantially better than WinForms for a customized UI. (theoretically)

---
... Copied to Clipboard!
Yellow
04/09/20 7:23:05 PM
#12:


Before

https://raw.githubusercontent.com/jamieyello/DownUnder-UI/master/Images/good_ui7.gif

After

https://i.imgur.com/qiD90Do.png

This runs at 10 fps btw, I got bored of waiting and did a software rendering of the shader, just to see for myself. Absolutely insane what a single shader can do after 3 months of changing nothing visually. Thought I'd do something "fun" after scrutinizing over things like C# serializers and trying to get rectangles to line up on a screen. Pretty happy with how this is turning out.

---
... Copied to Clipboard!
Sahuagin
04/09/20 9:49:21 PM
#13:


I don't know what I'm looking at. what parts of that are you rendering? what is it?

what did you change between them? are you saying the second one had worse FPS? is this WinForms or WPF? or are you rendering this entirely with monogame? how does what you're rendering relate to WinForms VS WPF, or is that more just about the monogame window, and your UI system from scratch and rendered in 3d?

---
... Copied to Clipboard!
Yellow
04/09/20 10:04:38 PM
#14:


This is my UI system with the "shaders" I wanted. The dark borders and gradients, they make it look so much better imo. Just those 30 lines of code made it look like a real product. It's still rendered entirely with Monogame. I won't go into WPF until I want to do window transparency, probably much later.

The caveat is that I was sick of waiting to see the effect through a shader, so I rendered it with the CPU, which is incredibly slow. I'm still getting weird compiler errors with the fx shader.

So crazy with these UI systems, 99.99% of it is actually under the hood.

---
... Copied to Clipboard!
Sahuagin
04/09/20 10:35:42 PM
#15:


so, is this your own UI model? DownUnder.UI.Widgets, where a Widget has an Area and a collection of other Widgets (children), and where a Button is a Widget, etc.etc.? and you render things yourself in monogame? that's very cool if so. (so, all of these fonts and lines and things are you rendering them manually in 3D? have you extracted out the "property grid" there? are you extracting your graphics code to make it more convenient and reusable? are those light grey rectangles on the property grid scroll bars? do they work? (if the scroll bars work with mouse control, are you handling input, detecting clicks, applying mouse movement to the scroll %, etc.etc.?))

I might recommend trying to focus on the structure and keeping things clean and be careful not to bog things down too much with special effects. but it doesn't matter that much as long as you're learning and practicing.

I haven't done that kind of stuff in a long time, and you're really making me miss it. "one of these days" I'm going to try to get back into it. (I guess I have tried once or twice recently, but I guess I don't have the creative drive I used to have...)

---
... Copied to Clipboard!
Yellow
04/09/20 11:25:09 PM
#16:


Sahuagin posted...
so, is this your own UI model? DownUnder.UI.Widgets, where a Widget has an Area and a collection of other Widgets (children), and where a Button is a Widget, etc.etc.? and you render things yourself in monogame?
Yes yes yes

Sahuagin posted...
all of these fonts and lines and things are you rendering them manually in 3D?
They're not 3D, I don't know why I'd get into 3D for a UI, though bump-maps could definitely be a thing at some point for rotating elements Hearthstone-card style. The way I set up the EventHandlers you should be able to do just about whatever you want without changing the fundamental code.

Sahuagin posted...
have you extracted out the "property grid" there?
The Property grid is a generic class that will create one of my Grids (derived from Widget) that contains a grid of Widgets (Layouts by default). The PropertyGrid object there inherits Grid and manually sets the fields (for a total inheritance of 3 classes, I'm pushing it but that's also how Microsoft did it with their PropertyGrid. Funnily enough I was already done with it before I realized it was almost identical.) It'll take any object and display the Properties along with their values, and in the future will be able to edit them. Right now it just displays the base Layout of the project.

Sahuagin posted...
are you extracting your graphics code to make it more convenient and reusable?
Not sure exactly with this question, almost all drawing code is contained in Widget (Widget being 1317 lines long, most derived classes being around 200), derived classes can draw any content they want in an area they're unable to draw outside of (unless they add an event to the OnDrawNoClip EventHandler)

Focus is an object contained in the DWindow class, where if a Widget is hovered it will add itself to a list of hovered widgets. This is done for all Widgets in an UpdatePriority method, then in the normal Update() they can check to see if they're the primary hovered Widget.

The ParentWindow and ParentWidget properties are both IParents, which will both initialize any graphic related content on setting, which after much painstaking tweaking seem to work seemlessly, and I'm really happy about that.

I designed it to be as close to Windows Forms as possible (except the parts I don't like about Windows Forms), so you can either add new Widgets in the code (the only way atm) or in the future design a form in the designer, which will serialize the Widget to a .cs file and add it to your project on saving. (Serializer is mostly finished but broken, I posted it here a while back and I remember you telling me I was botching the ref keyword, I haven't touched it much and it breaks a lot so it's still bad)

Sahuagin posted...
are those light grey rectangles on the property grid scroll bars? do they work? (if the scroll bars work with mouse control, are you handling input, detecting clicks, applying mouse movement to the scroll %, etc.etc.?))
Yup, once you're able to accurately calculate the offsets taking into account scroll it's very easy (as a matter of fact too easy) to put that in a property and easily tell where anything is. (6% of my CPU usage goes in that function atm)

Another cool thing I like about it is the behavior system which basically handles plugins for the Widgets that act independently from them. The grid that pops up isn't a natively coded thing, it's a behavior that was added to it, as the dragging and dropping behavior, and most animations. I did that so I can set up an online hub where users can preview download and upload Widget behaviors, as well as to keep more complicated flashy stuff modular and away from the core. They're designed in a way that intentionally makes it unfeasible to have them interacting with each other.

Sahuagin posted...
I might recommend trying to focus on the structure and keeping things clean and be careful not to bog things down too much with special effects. but it doesn't matter that much as long as you're learning and practicing.
All the basic stuff is done atm, albeit a lot of it broken. I just realized that recently and it's very relieving knowing that I'm not fighting with Rectangle spacing anymore. It's harder than you would think.

---
... Copied to Clipboard!
Sahuagin
04/10/20 12:00:51 AM
#17:


Yellow posted...
They're not 3D, I don't know why I'd get into 3D for a UI, though bump-maps could definitely be a thing at some point for rotating elements Hearthstone-card style. The way I set up the EventHandlers you should be able to do just about whatever you want without changing the fundamental code.
I can't remember but I recall that "2D" these days is really just 3D with a projection that gives you a 1-1 relationship between surface pixels and screen pixels. by "3D" I just mean in "3D land" where you don't have access to any O/S stuff and have to use Monogame/DirectX. it's a much lower-level place to work from. (a long time ago graphics was actually 2D but these days with video cards, there's not really any such thing as 2D graphics, just the appearance of 2D in 3D. sort of "emulated" 2D.)

Yellow posted...
The Property grid is a generic class that will create one of my Grids (derived from Widget) that contains a grid of Widgets (Layouts by default). The PropertyGrid object there inherits Grid and manually sets the fields (for a total inheritance of 3 classes, I'm pushing it but that's also how Microsoft did it with their PropertyGrid. Funnily enough I was already done with it before I realized it was almost identical.) It'll take any object and display the Properties along with their values, and in the future will be able to edit them. Right now it just displays the base Layout of the project.
very cool

Yellow posted...
Sahuagin posted...
are you extracting your graphics code to make it more convenient and reusable?
Not sure exactly with this question, almost all drawing code is contained in Widget (Widget being 1317 lines long, most derived classes being around 200), derived classes can draw any content they want in an area they're unable to draw outside of (unless they add an event to the OnDrawNoClip EventHandler)
just thinking about it, my design juices start flowing. I would think of doing something like trying to inject the dependency on "drawing" so that Widget is not bound to any particular implementation or framework. and any "drawing" that Widget does should be delegated off to some drawing framework. Widget just knows that it needs a drawing service to draw things, and that drawing service could be anything. and the drawing service should be as convenient to use as possible. etc. (damn, I really want to dig into something like this now...)

but regardless what I have to say, it sounds like you're already doing great. I've done some of what you're doing before myself, and you're doing some things I haven't done (and vice-versa).

I can't remember, are you working on a degree or anything? I haven't seen your code I guess, but it seems you're definitely not just some random guy fiddling with a language, you definitely have skill.

---
... Copied to Clipboard!
Yellow
04/10/20 1:57:06 PM
#18:


Sahuagin posted...
I can't remember, are you working on a degree or anything? I haven't seen your code I guess, but it seems you're definitely not just some random guy fiddling with a language, you definitely have skill.
Thanks, I took an SQL class once got a C and dropped out after much scolding. I hated it. I could have learned what they taught me over 3 months in 2 weeks max. Instead I almost failed because I didn't do the homework or memorize 1st and 2nd nf (because as far as I can tell 1nf and 2nf are useless).

Or rather I'm just bad at attaching formats to something that doesn't need a format and my brain rejects that. Doing that every step of the way in learning, I am weirdly OCD.

If I were to go again I would do it exactly the way they want me to do it and get an A in every single class, because I really should have.

One of my friends tells me to dig up my ACT scores to get a "free ride", and I don't know how to do that because I'm bad at real life. That's why I need a girlfriend tbh, I need someone to keep me focused, but again I suck at real life because the girls I ask out end up pissed at me for being standoffish.

Sahuagin posted...
I can't remember but I recall that "2D" these days is really just 3D with a projection that gives you a 1-1 relationship between surface pixels and screen pixels. by "3D" I just mean in "3D land" where you don't have access to any O/S stuff and have to use Monogame/DirectX. it's a much lower-level place to work from. (a long time ago graphics was actually 2D but these days with video cards, there's not really any such thing as 2D graphics, just the appearance of 2D in 3D. sort of "emulated" 2D.)
I remember that when I glazed over SDL. Monogame doesn't expose any of that logic. Now that you mention it that could be a useful thing to have total control over.

Sahuagin posted...
just thinking about it, my design juices start flowing. I would think of doing something like trying to inject the dependency on "drawing" so that Widget is not bound to any particular implementation or framework. and any "drawing" that Widget does should be delegated off to some drawing framework. Widget just knows that it needs a drawing service to draw things, and that drawing service could be anything. and the drawing service should be as convenient to use as possible. etc. (damn, I really want to dig into something like this now...)
I never thought of that, I just kind of relied on MonoGame to do the porting for me. They do a pretty good job, but yes there is no reason to have Widget directly call Monogame's drawing functions, is there?

There's honestly a good case to be made to completely separate the UI system from Monogame entirely simply because they don't need each other. Monogame's role in my project is to make it easier for the end user (in this case another developer) who wants to use Monogame, as well as making it easier and faster for me to develop, having access to most things I need right away.

I will break it away from Monogame later on, I'd like to have it in Unity and UE4 as well.

---
... Copied to Clipboard!
Sahuagin
04/10/20 10:39:10 PM
#19:


Yellow posted...
Thanks, I took an SQL class once got a C and dropped out after much scolding. I hated it. I could have learned what they taught me over 3 months in 2 weeks max. Instead I almost failed because I didn't do the homework or memorize 1st and 2nd nf (because as far as I can tell 1nf and 2nf are useless).
I had similar issues wanting to do things my own way and not caring about the classes because they teach you things so absurdly slowly. that was especially an issue in first year where you start from "this is an if statement" and "this is a loop", etc.

normal forms are kind of fancy formal rules for things that are basically intuitive. (I'm looking them up to describe them here, I don't have them memorized and never really use them as concepts; I just more or less know them intuitively. I also don't necessarily have this 100%, and there's reasons that a formal description of them is more elaborate.)

first normal form is basically just "don't put multiple values in the same column". basically, keep values separated in separate columns so that you can retrieve only as many columns of data as you need. in other words, you shouldn't be storing data in one column that you then have to pull apart on the client (or at least doing so would be considered de-normalized).

second normal form is basically "don't put fields in your table that would have redundancies in their values". or specifically, don't put fields that "functionally depend" on only a _part_ of that table's primary key, since that means those fields will be the same for every occurrence of the partial primary key, instead of the whole key. those fields should be in another table that has the partial key as its whole key.

Yellow posted...
I never thought of that, I just kind of relied on MonoGame to do the porting for me. They do a pretty good job, but yes there is no reason to have Widget directly call Monogame's drawing functions, is there?

There's honestly a good case to be made to completely separate the UI system from Monogame entirely simply because they don't need each other.
I've been getting better at dependency injection lately so I guess I'm seeing it everywhere now. I can't know for sure that it would be a good idea to do that to your code.

but theoretically you could write UI code that has the dependency on a particular graphics framework completely decoupled, and then you could switch graphics frameworks as desired using the same UI code, and you could also test the UI code without having to make a "real" graphics framework (you could inject a fake one just for testing purposes).

it's the kind of thing that sounds awesome in theory, but isn't necessarily so easy to accomplish in practice. it's something I'm working on getting better at.

(more specifically, I guess you would have some kind of drawing interface in its own library. you would then implement this interface in your drawing library. you would then inject the particular drawing implementation into your UI code.)

(this is the kind of thing that takes a lot more work to do, but allows for much larger scaling of your system.)

(to summarize dependency injection quickly: rather than just write a dependency right into your class by instantiating a type or calling a static method when you need to access that external (heavy) resource, you instead accept something (a [hopefully lightweight dependency-free] interface) in your constructor which provides the services you need. this defers the dependency to somewhere else. if you keep doing this, eventually you defer the creation of the dependency all the way to the entry point of the application. somewhere around there you create what is called the "composition root", which is where you instantiate all of your dependencies and inject them. (then there is the issue of lifetime of the dependencies. maybe one kind of service could live for the duration of the whole program, but another would need to be created anew each time, and so then you'd maybe pass a factory method of some kind, etc.))

---
... Copied to Clipboard!
Yellow
04/12/20 9:10:49 AM
#20:


That explains that better than my professor could, he just got mad at me for not knowing it late in the class and told me to read the book. It was less of a "what is this" and more of a "why is this" question.

I think I'll do dependency injection too, but right now I'm still struggling to get these monogame dependant Effect shaders to compile. I'll probably make a post on the monogame forums after scrubbing some more online articles explaining it.

---
... Copied to Clipboard!
Yellow
04/13/20 1:58:30 AM
#21:


Nevermind it literally just started working with no explanation after re-ordering things and removing code I wasn't using. >_>

Ok, that's good I guess, HSHL is wonky. Glad I spent 30 seconds randomly changing things after 3 days of no progress. The order you declare variables does make a difference I think.

---
... Copied to Clipboard!
Yellow
04/13/20 11:23:51 PM
#22:


Shaders now work, woo, but also break text. Hopefully I don't have to dig into MonoGame's source to find out why. Probably shouldn't seeing how it's breaking textures. Maybe I can just change the way I'm calling Draw. I'll figure it out later, for now this is pretty fun.

(old rendering, no shaders)
https://i.imgur.com/drqMnpz.png

(current GPU rendering, shaders amplified to see effect)
https://i.imgur.com/2DSfv0k.png

(desired result, manual software rendering)
https://i.imgur.com/qiD90Do.png

Here's something else, MonoGame.Extended is looking for a new repository owner. <_< That's basically the standard for MonoGame/XNA development, you immediately install MonoGame.Extended.

It's very similar to what I'm doing... expanding and developing new MonoGame features past MonoGame's goal of preserving the library. I do know MonoGame in and out at this point. But I've only forked their code once? No one else has stepped up, their Discord is dead. I don't want the Patreon money. If I were to take it up I would shut that down or leave it with the old developer. To say you run the repository of MonoGame.Extended though, that's something to brag about...

There are a couple things I would like to add? Mostly just extensions I made myself. I'd be like a kid in a candy shop.

---
... Copied to Clipboard!
Yellow
04/16/20 11:27:18 PM
#23:


This turned out soo good.

https://github.com/jamieyello/DownUnder-UI/blob/master/Images/good_ui8.gif

That black edge shader is a programmable shader with a C# wrapper, not built into the Widget class at all, inheriting an abstract class WidgetBehavior

https://github.com/jamieyello/DownUnder-UI/blob/master/DownUnder/UI/Widgets/Behaviors/ShadingBehavior.cs

that is added as easily as this

widget.Behaviors.Add(new DrawPixelGrid());
widget.Behaviors.Add(new ShadingBehavior());

And is Clone()'ed with the Widget.

And it will have parameters like BorderColor and the such to be set at any time. I think this kind of structure is unique to my UI framework... as far as I know. I think this is going to be a pretty intuitive system.

I'll probably let this topic die now, I'm just happy with the results. I'll get my 4 hours of sleep now.

---
... Copied to Clipboard!
Sahuagin
04/17/20 4:26:22 AM
#24:


definitely cool 8)

didn't realize I can browse a lot of your code there. here's some random comments that you didn't ask for:
(obviously for all I know this is code you don't even use anymore; this is just random unsolicited advice that may or may not be helpful)

you should use using blocks instead of calling Dispose manually. in UIImages.cs:

FileStream af_fs = new FileStream("UI/Images/add folder.png", FileMode.Open);
AddFolder = Texture2D.FromStream(graphics, af_fs);
af_fs.Dispose();

becomes

using (var af_fs = new FileStream("UI/Images/add folder.png", FileMode.Open))
...AddFolder = Texture2D.FromStream(graphics, af_fs);

and in C# 8 it can be written with a using statement as:

using var af_fs = new FileStream("UI/Images/add folder.png", FileMode.Open);
AddFolder = Texture2D.FromStream(graphics, af_fs);

and then it should be extracted to a method

Texture2D ReadTexture(GraphicsDevice graphics, string filename) {
...using var fileStream = new FileStream(filename, FileMode.Open);
...return Texture2D.FromStream(graphics, af_fs);
}

if possible the method should be put somewhere

and now that I notice, you seem to be assigning to AddFolder 4 times rather than assigning to each of AddFolder, BrowseFolder, etc.

the constructor of UIImages then would look something like:
(though another note would be, isn't there a content manager for loading graphical resources?)

public UIImages(GraphicsDevice graphics) {
...AddFolder = ReadTexture(graphics, "UI/Images/add folder.png");
...BrowseFolder = ReadTexture(graphics, "UI/Images/browse folder.png");
...Folder = ReadTexture(graphics, "UI/Images/folder.png");
...OpenedFolder = ReadTexture(graphics, "UI/Images/opened folder.png");
}

Dispose pattern should be something like this:

bool mDisposed;
public void Dispose() {
...if (mDisposed)
...return;

...AddFolder.Dispose();
...BrowseFolder.Dispose();
...Folder.Dispose();
...OpenedFolder.Dispose();
...mDisposed = true;
}

You shouldn't need to use safe navigation operator. You shouldn't need to use a finalizer which is for unmanaged resources. (Dispose pattern can actually get pretty messy, but as long as you're dealing with managed resources, all you really need to do is call Dispose on managed resources up to one time in the Dispose method.)

---
... Copied to Clipboard!
Sahuagin
04/17/20 5:13:50 AM
#25:


one thing I would suggest is to try to use vertical space more efficiently. it took me a hugely long time to figure it out, but every line of vertical space wasted makes your code harder for you to read. there are good times to use up some vertical space to make thing _easier_ to read, like parameter and argument stacking (basically, breaking up long lines is fine).

(and again, don't listen to me just-because. it's up to you whether anything I say is actually useful or not.)

the main two things are:
  • K&R braces. these waste a line for no good reason everytime you have an opening brace. I used to like the way that the braces lined up, helping me to make sure that everything was indented properly, but eventually I realized it wasn't worth the wasted vertical space.
  • C sharp xml comments. except in some very specific cases (basically a class that has a necessarily and surprisingly complex interface) you should avoid these. they waste tons of vertical space, take time to write, aren't code so they decay with time (the code gets updated but the comments do not) and/or take effort to maintain, and often don't even tell you anything useful about your code.


rule of thumb for writing any comment is to ask yourself: could I convey this information by using better variable/method names instead of adding a comment? if the information could be put into the name instead of into a comment, that's pretty much always better than a comment.

as an example, DiagonalDirections2D.cs is approaching 300 lines long. (259 specifically). Here it is without sacrificing vertical space, now at only 162 lines long. saved almost 100 lines.

https://pastebin.com/dUWtvCBV

(also made a lot of use of expression syntax in places; also note that I didn't compile this so who knows if I got it right)

(and that's not looking at how maybe the implementation there could be improved; that's just whitespace and comments)

---
... Copied to Clipboard!
Sahuagin
04/17/20 6:02:13 AM
#26:


in my first post, I neglected to rename af_fs to fileStream

I also meant to say, if possible the method should be put somewhere... else for easy access if this is something you do regularly.

another thing is, in monogame, shouldn't there be a content manager that you can use to load resources like textures?

---
... Copied to Clipboard!
Yellow
04/17/20 4:16:21 PM
#27:


Sahuagin posted...
you should use using blocks instead of calling Dispose manually. in UIImages.cs:
I didn't know using called Dispose.

Sahuagin posted...
using var af_fs = new FileStream
That will also call dispose? I always overlooked using.

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-statement

"Provides a convenient syntax that ensures the correct use of IDisposable objects."

Huh, it looks like that's their sole purpose. What a niche thing.

I guess I could turn it into a method, but looking back I should never have it loading from a PNG. Like you said, Monogame has a content manager, I just avoided it because it's a library with no entry point and I thought that might complicate things, but it turns out ContentManager is very modular and can be used anywhere. I probably shouldn't even put that method in my library, I get the feeling Monogame forces users to jump through a small hoop so they realize they shouldn't do it that way, which is bad practice.

That whole UIImages class was just incredibly lazy and slapped together to test something else out and I sort of forgot about it.

K&R braces. these waste a line for no good reason everytime you have an opening brace. I used to like the way that the braces lined up, helping me to make sure that everything was indented properly, but eventually I realized it wasn't worth the wasted vertical space.
I agree on this one, I only had it that way because of a "code maintainer" extension I had that turned all of my

void method() {
}

and

void method() => stuff.stuff();

into clunky

void method()
{
}

Which I agree is dumb, but I didn't want to give up the formatter and was basically doing anything I could to make my code more "correct" despite my opinions on it. Now that you bring it up I will probably make a huge commit changing it. (and my precious line count total, of course 4000 lines of code = 4000 lines of hard work)

C sharp xml comments. except in some very specific cases (basically a class that has a necessarily and surprisingly complex interface) you should avoid these. they waste tons of vertical space, take time to write, aren't code so they decay with time (the code gets updated but the comments do not) and/or take effort to maintain, and often don't even tell you anything useful about your code.
I am very particular about my comments, as I very often forget what a method or field does, they do help me a lot, even if they are so simple they don't need an explanation (at least so I think when writing it). It might just be OCD when it comes to the ones that obviously don't need an explanation. Discerning which ones do and don't need an explanation seems too subjective to be orderly to me.

I would be less liberal with my commenting, but this is a library intended for other people to not edit, but use a compiled dll of. I always thought it was strange to use Monogame and have a very common class to not have any description. So for this project I may let it get silly, just for the sake of making my project appear more polished. I do always keep them at a one line <summary></summary>, at least.

Sahuagin posted...
https://pastebin.com/dUWtvCBV

(also made a lot of use of expression syntax in places; also note that I didn't compile this so who knows if I got it right)

(and that's not looking at how maybe the implementation there could be improved; that's just whitespace and comments)
It did work perfectly on the first try. I'll take that, thank you. Your version is much better. I can definitely see what you mean by line count clutter, my code isn't nearly as complicated as I thought it was.

Sahuagin posted...
(and again, don't listen to me just-because. it's up to you whether anything I say is actually useful or not.)
Haha, my life philosophy is to be very receptive of anything being said to me, because it's most often true. Then someone can tell you something else and you have both first person viewpoints to judge. On a side note when people feel like they are being taken seriously they are more introspective themselves, and less like brick walls. I don't act that way on this forum, I just go full scorched earth here

I use to watch nl_kripp (one of the best Hearthstone/WoW players in the world) and I thought it was crazy how often he just took some random guy in his chat of 10,000 people's word on some decision. Of course you're not some random guy, though.

Sahuagin posted...
there are good times to use up some vertical space to make thing _easier_ to read, like parameter and argument stacking (basically, breaking up long lines is fine).
Well I'm definitely taking this seriously because your version is much easier to read.

---
... Copied to Clipboard!
Yellow
04/17/20 5:11:14 PM
#28:


Oh and heads up don't quote the part where I typed

void method "parenthesis parenthesis bracket bracket"

because that was detected as an exploit and I got a temporary ip ban.

---
... Copied to Clipboard!
Sahuagin
04/18/20 9:51:01 AM
#29:


man, click one button and I've forked the entire thing to my own account with no confirmation or question or anything...


---
... Copied to Clipboard!
Topic List
Page List: 1