KeenSoftwareHouse / SpaceEngineers

2.94k stars 894 forks source link

In-game scripting API (re)design #60

Open cwc opened 9 years ago

cwc commented 9 years ago

So I read @lord-devious's comments in #4, and I am also of the opinion that the API used for in-game scripting could use some refactoring so as to be more immersive. Names like IMyCubeGrid could be changed to e.g. IVessel or something that fits the game's flavor. The actual implementation classes could keep their current names, as I believe they are used directly by modders, so it makes sense for those names to be more in touch with the real world. Or perhaps it'd be better to completely duplicate the interfaces into a separate in-game-only namespace? Then there's no overlap, and it would be easier for the game designers to control what's available to players in-game, while giving the modders lots of freedom.

Expanding on that, there are other design improvements (#29) that people would like to see in the in-game API, that would need to be taken into account in any redesign. As another example, I'm not really a fan of the extension methods on IMyTerminalBlock. These exist so that scripters don't have to cast from e.g. IMyCargoContainer to IMyInventoryOwner in order to look at contained items. Personally, I would have just made the cargo container/assembler/refinery interfaces extend from IMyInventoryOwner, so neither casting nor type checking would be needed.

Anyway, I'd like to hear others' opinions. I know @Spartan322 had some comments in the original thread. Maybe we could get a general feel of what the community thinks the scripting APIs should look like.

MMaster commented 9 years ago

Redesign of APIs after they have been published and used in many in-game scripts & mods already on workshop needs to provide backwards compatibility. Redesigning APIs just to change names is not a good reason. Also issue #29 does not need redesign - it's basically new feature request.

Spartan322 commented 9 years ago

Well, we could call the current names deprecated for scripts add new versions with names like IVessel. An issue is that, if we deprecate the old (current) design, then 1, all current scripts are considered obsolete, and 2, we redesign it without purpose, they wouldn't add features, and even if you keep those ones up to date, you kind of isolates the old deprecated versions on scripts. In reality, this isn't a big issue, but changing names even by extension is not worth much if it won't provide different functionality, and would really just confuse people. Now if we did a redesign of the system by actually changing the way it is done, the maybe, but right now it is not a great idea. (Also KSWH need to provide better docs on this, it be cool to have it similar to DoxyGen)

cwc commented 9 years ago

Backwards compatibility with existing scripts is definitely something to be concerned about. If serious changes are made, the nice thing to do would be to deprecate and keep the old API active for awhile, rather than cry "#yolo #EarlyAccess" and just break everything.

@MMaster #29 may not necessitate a redesign on its own, but I think it's worth considering ideas like that when discussing what our ideal API looks like. The knowledge that folks want the API to be more event-driven informs discussion around the API's design.

rockyjvec commented 9 years ago

@Spartan322, I was already using DoxyGen for my EasyAPI abstraction script, so I decided to try running it on the Space Engineers source code. Here is the result: http://spaceengineers.io/spaceengineers/doc

Spartan322 commented 9 years ago

@rockyjvec Yeah, that's cool but its not actually documented, if it was documented on DoxyGen, that be the best.

stafyniaksacha commented 9 years ago

We need to think how to introduce multi files scripting. This will be a good reson for in-game scripters to update their scripts.

zrisher commented 9 years ago

:+1: for multiple files, I think that would really help people that are halfway between ingame-scripting and mod-ready logic

malware-dev commented 9 years ago

What is extremely important for ingame scripting is to keep it as simple as possible. No unnecessary complications. It should serve as a starting point for people who want to learn to code. Also one should consider the golden 80/20 rule. If less than 20% of people are going to use a specific feature, don't include it.

Spartan322 commented 9 years ago

I agree with the multi-file but the system needs to be approachable as @lord-devious means.

alex-davidson commented 9 years ago

+1 for sharing common logic between scripts. C# really does not make that easy to achieve (other than string concatenation of source) since Java/C++/C# love to mix code and data, but a 'mixin-like' system would be nice. It should be fairly straightforward to do in a structured fashion with MS Roslyn but SE's current compiler is CodeDom-based, so string concatenation might have to do for now.

Sharing data between script instances is a much trickier problem and probably shouldn't be allowed for now, generally speaking. Guaranteeing serialisability is easiest if everything has string type, and that's doable with block names.

Incidentally, are there any plans to replace the CodeDom compiler with a Roslyn-based one? Technically it shouldn't be too awkward but I'm not sure about the licensing.

rockyjvec commented 9 years ago

Yeah, in the mean time, I'm working on a dependency manager for "mixin" scripts. Each script will need something like the following example data:

{
    "name": "EasyLCD",
    "description": "Class that makes drawing to LCDs easy.",
    "type": "library",
    "version": "1.0",
    "require": {
        "EasyAPI"
    },
    "conflict": {
    },
    "suggest": {
        "EasyMenu": "Make menus to display on the LCD."
    }
}

I'm hoping to make it so I can just select a bunch of "library" scripts and it will automatically concatenate all the dependencies into one script that I can paste into the game. It could maybe even minify the scripts to help with the script length limitation.

plaYer2k commented 9 years ago

I dont understand the issue with a name like IMyCubeGrid. After all each CubeGrid is exactly that, a 3D Grid with Cubes.

A name like IMyVessel would be very misleading because that would imply that each ship consists of multiple "Vessels" separated by rotors/pistons.

A single ship in API terms is the tree of a parent IMyEntity and all its Children. So a tree of IMyCubeGrids (as they are the block structure) from the core to all extremities.

That said, renaming the IMyCubeGrid seems wrong as the name is best fitting already. Renaming it to like IMySegment would be the best alternative fit and yet far too general and ambiguous, using further explicit names like IMyShipSegment or IMyStationSegment would be wrong too as stations and ships are the same with just one difference, one is static while the other is dynamic in terms of the applied physics.

Spartan322 commented 9 years ago

@plaYer2k The only reason IMyVessel was used was cause it was the first example name used, but @cwc's point was that we name the objects that are accessible by in-game scripts as something that does not break the 4th wall.