Sign up Calendar Latest Topics
 
 
 


Reply
  Author   Comment   Page 1 of 3      1   2   3   Next
TheGrimReaper

Avatar / Picture

Registered:
Posts: 26
Reply with quote  #1 
Okay, so I might have gone mad, trying to do scripting with a programming language when its not a scripting language.
Here is my story: 
    I started production of a air lock chamber. After creating it, I realized how much manual work I had to do with it, so I decided to look towards Programmable Blocks to make it more automated, since I knew how to program in several languages. I went and saw that it was in C#, which, is close enough to Java and C++ for me, so I started programming. One of the first noticeable things I saw, was that it was super, duper, ultra, restricted (this was annoying to me because I need Thread.sleep(), which, I emulate later using Timers). The second, was that the ingame IDE was pretty much notepad.exe, except that it glitches and double arrow overs often. So I went to Visual Studio, since Eclipse doesn't have support for C# and I didn't feel like adding another plugin. Visual Studio had all of these uncomfortable syntax solutions that got in my way and drove me half insane. Once I got started programming, I got a decent flow. There were some things that really, REALLY, REALLY F**King aggravated me, for example, the scripting API is so poorly done that it made my stomach overturn. For instance, WHY, in all retrospect, do I have to use reflection to get ahold of functions of blocks? I'm dead serious here, why are the functions not there? ALSO, while I'm at it, why don't I have a simplified method in the parent class for, getBlock(String Block); or even getBlock(int ID);? The reason why I'm so aggravated at the actions of the block relying on reflection and not basic functions is that I spent hours (I'm exaggerating) trying to debug my program properly, trying to figure out why a door wasn't opening, and it was due to it being "Open_on" instead of "Open_On". 

Here is an example of what I'm so mad about, if you haven't caught on. 

var Var = GridTerminalSystem.GetBlockWithName("Door");
if (Var != null && Var is IMyDoor)
{
    ((IMyDoor)Var).GetActionWithName("Open_On").Apply(Var);
}

Should be.....


var Var = getBlock("Door");
if (Var != null && Var is IMyDoor)
{
    ((IMyDoor)Var).Open_On();
}


Look how nicer it looks. Plus it's harder to screw up.

TL;DR:
I ranted about programming nonsense. I think that Scripting should be focused on, for at least a little bit. If Space Engineers is going to use a full Programming Language, such as C#, then it needs to make sure it is easy to use and powerful. I know that the developers are working hard on the latest updates, but this area in particular really needs some work.

My Request:
API file for Devs: Basically just interfaces like a real API for Devs to import into Visual Studio or whatever IDE to easily make scripts, because lets face it, your ingame IDE isn't a real IDE.
Improved Classes and Cases: C# is Object Oriented. I should be able to get Blocks' objects with a single, easy method, and then do abilities easily. Having us do reflection (use a string to get actions), makes it very limited, in my opinion. When there are only methods, people who use text-complete IDE's get the advantage of being able to find methods without consulting a Doc. (Look above).
Debug Function: World.Broadcast("Hello, World!"); There should be an easier way to be able to debug. Maybe have an actual output area in the Programmable Block? Shouldn't be too hard.
Permission System: Idea is simple: Players with certain permissions can use certain lower leveled functions, possibly maybe even IO, but this would take a long time to implement so I don't expect it.
Real Functions: It might be redundant for me to put this here, but every action that there is, I want there to be a function. For instance, if on a Button a player can write a name, give the script a possibility to write a name for the button. 
Permission System2: (edited in) The programmable blocks have the same permissions as who ever compiles it?

After Thoughts:
Halfway through this, I forgot that this is only a script. But at the same time, I remembered that even though it is just a script, there is still so much more it can (should) do!


Thank you for reading.

Gloin the Dark

Registered:
Posts: 1
Reply with quote  #2 
To simplify things, couldn't you just do this...
 
 
IMyTerminalBlock block = GridTerminalSystem.GetBlockWithName("Door");
block.GetActionWithName("Open_Off").Apply(block);

I know its not as simple as what you are looking for. But its not too bad.

Orange_Slime_

Registered:
Posts: 211
Reply with quote  #3 
Rant, RANT IT ALL!

/fakerant
Jewboii

Registered:
Posts: 76
Reply with quote  #4 
I use notepad++.  Lightweight, works fine.  Timer blocks are how you effectively Thread.Sleep() by design.  My suggestion to everyone using the programmable block is to write their own boilerplate code that is common to all projects.  

Use an LCD for your console output.

You can also extend the default interfaces to make things a bit more intuitive.  There's a post somewhere in the forum that shows you how to abuse extra closing braces to achieve these result.  I can post an example when I get home.
joemorin73

Avatar / Picture

Registered:
Posts: 324
Reply with quote  #5 
I'm using VS2013 and haven't had much issues.  Adding in the right libraries and creating a fake gridsystem in the class works pretty well.  Let's Intellisense work.

I definitely agree that the Programming block is not perfect.  But over time, you'll find the tools that work for you.
Two

Registered:
Posts: 87
Reply with quote  #6 
The reason why the API is so bad is very simple: those who designed it did it for the first time. What we need now is Keen to agree that it is pretty bad, followed by a proper rewrite, if possible with the help of the community.

And btw my favorite way of opening a door would be:
local door = getBlock("Door") or error("Door not found")
door.setOpen(true)
TastyWheat

Registered:
Posts: 14
Reply with quote  #7 
I don't mind the GridTerminalSystem part, but doing this is not only cumbersome it's downright confusing:

((IMyDoor)Var).GetActionWithName("Open_Off").Apply(Var);
LordDevious

Avatar / Picture

Registered:
Posts: 998
Reply with quote  #8 
You don't need to do it quite so complicated anymore:

Var.ApplyAction("Open_Off");


but I would prefer it to simply be

Var.Close()


That said, I have been creating a replacement API to give me the ability to do things like:


// Find all reactors starting with the text "Terrestris.Reactors." and shut them off
var reactors = Platform.FindDevices<IMyReactor>("Terrestris.Reactors.*");
reactors.ForEach(reactor => reactor.Disable());

// Find the first text panel ending with ".Console"
var console = Platform.FindDevice<IMyTextPanel>("*.Console");
// This is a custom extension which automatically refreshes the display
console.WriteLine("Reactors Disabled");


I just wish I didn't have to copy it to every single PB I use. Which is a lot. Also it uses instructions and characters that could be used for other things.

[Edit] Just to add your initial code as available from my framework:

var door = Platform.FindDevice<IMyDoor>("Door");
if (door != null)
    door.Open();
TheGrimReaper

Avatar / Picture

Registered:
Posts: 26
Reply with quote  #9 
Quote:
Originally Posted by Gloin the Dark
To simplify things, couldn't you just do this...
 
 
IMyTerminalBlock block = GridTerminalSystem.GetBlockWithName("Door");
block.GetActionWithName("Open_Off").Apply(block);
I know its not as simple as what you are looking for. But its not too bad.


That's not the point that I am making. Of course I can do that, but that just makes for a shitty API. Plus you aren't checking if the block is null, or if it actually is a door. And using that method, you ASSUME that the object in question has the action "Open_Off". ALSO, the fact that you have to restate what object the action belongs to, after getting it from the object in question, is just wrong. 


Quote:
Originally Posted by Jewboii
I use notepad++.  Lightweight, works fine.  Timer blocks are how you effectively Thread.Sleep() by design.  My suggestion to everyone using the programmable block is to write their own boilerplate code that is common to all projects.  

Use an LCD for your console output.

You can also extend the default interfaces to make things a bit more intuitive.  There's a post somewhere in the forum that shows you how to abuse extra closing braces to achieve these result.  I can post an example when I get home.

I already know most of this, but remember, scripting is supposed to be for the average player so it should be a bit more readable to the regular non-programmer. 
Edit: I think the amount of programmers playing Space Engineers is less than 10%, but correct me if I am wrong.

Quote:
Originally Posted by Two
The reason why the API is so bad is very simple: those who designed it did it for the first time. What we need now is Keen to agree that it is pretty bad, followed by a proper rewrite, if possible with the help of the community.

And btw my favorite way of opening a door would be:
local door = getBlock("Door") or error("Door not found") door.setOpen(true)

They need to find someone who actually knows how to create an API for public use.


Quote:
Originally Posted by TastyWheat
I don't mind the GridTerminalSystem part, but doing this is not only cumbersome it's downright confusing:
 ((IMyDoor)Var).GetActionWithName("Open_Off").Apply(Var); 

Its not really confusing. Just annoyingly redundant. 


Quote:
Originally Posted by LordDevious
-snip-

It would be better to have Door.setOpen(boolean b); so you can do things like this, Door.setOpen(!Door.isOpen());
Edit: Also, I haven't spent much time around C# devs, but generally first letter caps should be reserved for classes, so start method names with a lower case. So instead of Door.Open(), have Door.open()
phoenixcorp13

Avatar / Picture

Registered:
Posts: 524
Reply with quote  #10 
Quote:
It would be better to have Door.setOpen(boolean b); so you can do things like this, Door.setOpen(!Door.isOpen());
you not in C++, C#  have propertries.
so.

door.Open:=true;
door.Open:=!door.Open;

but for actions i also prefer have method way.
door.Close();
door.Open();
door.OpenClose();


text actions as i say somewhere look like they looked into pure scripting environment, and try to repeat it into strict C# environment, which is wrong.

TheGrimReaper

Avatar / Picture

Registered:
Posts: 26
Reply with quote  #11 
Quote:
Originally Posted by phoenixcorp13
Quote:
It would be better to have Door.setOpen(boolean b); so you can do things like this, Door.setOpen(!Door.isOpen());
you not in C++, C#  have propertries.
so.
 door.Open:=true; door.Open:=!door.Open; 

but for actions i also prefer have method way.
door.Close(); door.Open(); door.OpenClose();


text actions as i say somewhere look like they looked into pure scripting environment, and try to repeat it into strict C# environment, which is wrong.



From my understanding, directly accessing a property or field is not only not thread safe, but also limited in the fact that you can't call anything so you would have to wait for an updater tick to see that the door's value has been changed to open rather than calling the updater yourself. 

There is absolutely nothing wrong with having individual methods for a boolean operator, ie open and close, but make sure that when a value has 3 possibilities you have the method setThing(Object o) vs each one individual. C# isn't improper here, it is just that they limited it too far, because they were too lazy to write their own API since they push updates once a week (That's my guess). 

As for the lower case first letter, Microsoft thinks that it should be capitalized, seen here, which, I completely disregard for bullsh*t.
phoenixcorp13

Avatar / Picture

Registered:
Posts: 524
Reply with quote  #12 
inside property Open will be a pair of get_Open set_Open methods, so there nothing about thread safe.
just as usual.

property works like fields, but more complex inside.
Quote:
As for the lower case first letter, Microsoft thinks that it should be capitalized, seen here, which, I completely disregard for bullsh*t.

C# have own rules, and good practive to use them.


TheGrimReaper

Avatar / Picture

Registered:
Posts: 26
Reply with quote  #13 
Quote:
Originally Posted by phoenixcorp13
inside property Open will be a pair of get_Open set_Open methods, so there nothing about thread safe.
just as usual.

property works like fields, but more complex inside.
Quote:
As for the lower case first letter, Microsoft thinks that it should be capitalized, seen here, which, I completely disregard for bullsh*t.

C# have own rules, and good practive to use them.




I looked here. I still think that setOpen(Boolean b) is nicer looking, and easier to understand. /*I Hate C#*/
Shabazza

Avatar / Picture

Registered:
Posts: 129
Reply with quote  #14 
It's a commonly accepted code rule to start method names with lower case and class names with upper case.
For C, C++, C#, Java and a bunch of other languages. So this is a point that irritates me in the API that they use upper case for methods.
Plus there really should be direct public methods to modify stuff. .enable(), .close(), .setLock(true).
I expect this from a C# based API.

If you have a proper documentation you can cope with a sting based operation/attribute set.
But the official docs are not sufficient yet. Without infos drawn by the community about block properties and actions,
we would not be able to do anything useful with the programming block by today.
We have ".ApplyAction(IMyTerminalBlock block, string actionName)" in the API docs. Fine. Now what? [rolleyes]
LordDevious

Avatar / Picture

Registered:
Posts: 998
Reply with quote  #15 
Quote:
Originally Posted by TheGrimReaper

Quote:
Originally Posted by Shabazza


I am a professional dev, proficient in several languages and their coding standards, currently using C# and have been for many years. Part of my job is to make sure people use predetermined coding standards and structures. In C#, lower case identifiers are usually reserved for private fields and method arguments. phoenixcorp13 is quite right.

However, what is important with coding standards is simply to pick one and stick to it. Whether you use upper or lower case letters in your identifiers is irrelevant as long as all your code in that perticular language does.
Previous Topic | Next Topic
Print
Reply

Quick Navigation:


Create your own forum with Website Toolbox!