Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for bunch of Quality Of Life data #130

Closed
lefouvert opened this issue Feb 29, 2024 · 51 comments
Closed

Request for bunch of Quality Of Life data #130

lefouvert opened this issue Feb 29, 2024 · 51 comments
Labels
enhancement New feature or request stale Issue has not seen activity for 60 days

Comments

@lefouvert
Copy link

lefouvert commented Feb 29, 2024

version 0.5.3.4 (Ckan)
gessed tag : Question, Enhancement

Hi !
Maybe I didn't be able to found thoses, in that case, «My bad», but I miss some acces to definitions datas.

Fairing (feels important to me)

There is 2 kind of fairing : the conveniences ones, and the wanted ones.
I mean, when you put a stage under an engine, this one is covered by a fairing. It's thoses I call the conveniences ones.
And there is obviously the fairing you put to protect your payload, have better aerodynamics etc aka the wanted ones.

Since vessel.parts.filter(fn(p) -> p.fairing.defined) is not able to distinguish them, I would like to know if there is an other way I didn't think about.
At first, I was thinking «Nah, easy, I collect fairings, I substract engines, and i'm good to go»
BUT ! Because there is a 'but', obviously, engines are not the only ones to have «conveniences» fairings. Heatshields too. And structural hollow tubes. And probably some others parts I didn't think about. And all thoses delicious parts don't have any modules to identify them :)
As part.is_fairing is probably an equivalent of part.fairing.defined, his behavior is unsurprizingly the same.
I'm not feeling good at the idea to look at the name of a part to identify it. I think it's not reliable.
If I didn't miss a way, maybe a part.fairing.value.is_jettisonable could be a good idea (since I wasn't able to jettison «convenience» fairing)

Solar panels (feels important to me)

I have a nice piece of code which is able to give the one of best vectors to expose to the sun.
But in order to be able to do it, I needs to know max output of each solar panels. Maybe I miss it, but I haven't be able to found it.
I had to write this kind of things :

pub const SolarPanel: (Name: string, MaxFlow: float)[] = [
    (Name: "solararray_0v_flat", MaxFlow: 0.145209029316902), // OX-STAT
    (Name: "solararray_1v_1x6", MaxFlow: 0.968068957328796), // OX-4L
    (Name: "solararray_1v_3x2", MaxFlow: 0.968069076538086), // OX-4W
    (Name: "solararray_1v_shielded_1x6", MaxFlow: 0.968068957328796), // SP-4L
    (Name: "solararray_1v_shielded_3x2", MaxFlow: 0.968069076538086), // SP-4W
    (Name: "solararray_1v_flat", MaxFlow: 1.21007525920868), // OX-STAT-XL
    (Name: "solararray_1v_circular", MaxFlow: 3.3882417678833), // OX-10C
    (Name: "solararray_1v_circular_shielded", MaxFlow: 3.3882417678833), // SP-10C
    (Name: "solararray_2v_accordion", MaxFlow: 11.6168279647827), // SP-XL 'Gigantor'
    (Name: "solararray_3v_large", MaxFlow: 33.8824119567871), // SP-XXL 'Colosse'
]

As said, I don't think it's a reliable way to gather data.

Resources / Engines (seems to be a good idea)

Did I miss a way to connect an engine with the fuel it burn ?

I wrote this :

pub type ResourceConst = int

pub const Resource: (MP: ResourceConst, SF: ResourceConst, Air: ResourceConst, H: ResourceConst, CH4: ResourceConst, Ox: ResourceConst, EC: ResourceConst, Xe: ResourceConst, Ab: ResourceConst) = (
    MP: 1,  // "ME"->"MP" Monopropellant
    SF: 2,  // "ES"->"SF" Solid Fuel
    Air: 3, // "Air"->"Air" Air
    H: 6,   // "H"->"H" Helium
    CH4: 7, // "CH4"->"CH4" Methane (Liquid Fuel)
    Ox: 8,  // "Ox"->"Ox" Oxygen
    EC: 12, // "CE"->"EC" Electrical Charge
    Xe: 13, // "Xe"->"Xe" Xenon
    Ab: 15  // "Ab"->"Ab" Ablator
)

pub const EngineFuel: (Fuel: int, Engine: string)[] = [
    (Fuel: Resource.MP, Engine: "MonoProp"), // "ME"->"MP" Monopropellant
    (Fuel: Resource.SF, Engine: "SolidBooster"), // "ES"->"SF" Solid Fuel
    (Fuel: Resource.Air, Engine: "Turbine"), // "Air"->"Air" Air
    (Fuel: Resource.H, Engine: "Nuclear"), // "H"->"H" Helium
    (Fuel: Resource.CH4, Engine: "Methalox"), // "CH4"->"CH4" Methane (Liquid Fuel)
    (Fuel: Resource.CH4, Engine: "Turbine"), // "CH4"->"LF" Methane (Liquid Fuel)
    (Fuel: Resource.Ox, Engine: "Methalox"), // "Ox"->"Ox" Oxygen
    (Fuel: Resource.EC, Engine: "Electric"), // "CE"->"EC" Electrical Charge
    (Fuel: Resource.Xe, Engine: "Electric") // "Xe"->"Xe" Xenon
]

which is far more reliable than looking at part's name.
It connect part.engine_module.value.current_engine_mode.engine_type to a part.resources.list.map(fn(r) -> r.resource.id).
This is way less an issue than others topics, but just in case I miss something... :). But I don't think it's a bad idea to have a way to know what input/output each part are able to.
For example, most Liquid Fueled engines have Oxygen and Methan as Input, and have Electric charges as output.
Propellant Tanks have their propelant as output
Solar panels have Electric charges as output
etc

The cherry on the cake would be able to ignite individualy each engine, especially since part.engine_module.value.independent_throttle have appeared ^^

Heatshield (feels accessory)

Maybe thoses parts would have benefits to have their very own module, since they can be deployed, they have resources (Ablator), fairing, etc
It would be a shame to inadvertently deploy one of those (Yes, I look at you, inflatable heatshield) while expecting deploy antennaes, solarpanels, cargoholds etc :)
At the time, I'm able to filter them on the resources the part hold. If their is 'Ablator' in it, it's a heatshield.

Edit : typo, grammar etc

@PhilouDS
Copy link
Contributor

If I may add:

ENGINES: access to engine's thrust limiter (R/W).
WARP: it's possible to get current_rate and current_index of the actual warp. Is it possible to change them?

@PhilouDS
Copy link
Contributor

@lefouvert I don't understand how Resource and EngineFuel work. What are the numbers next to the resources?

@lefouvert
Copy link
Author

lefouvert commented Feb 29, 2024

@PhilouDS The numbers in Resource are the ingame ids of the resources.
When you look at a part's resources, you may access to this id
part.resources.list.map(fn(r) -> r.resource.id)
ResourceContainer
ResourceData
ResourceDefinition
Displayed names are more user friendly, but id's are more efficient to link datas.

EngineFuel is just an array that describe which engine burn which fuel.

So if I run a «LV-1 'Ant'» engine, I'm able to know it's a Methalox engine type
part.engine_module.value.current_engine_mode.engine_type
ModuleEngine
EngineMode
EngineType
which will burn CH4 and Ox. I just have to search for parts inside the decouple stage I consider thoses which have CH4 and Ox.

With thoses two datas, you can know the mass a part will lost, and deduce lot of things as deltaV, isp, burntime etc.
Kontrol System give us access to most of thoses datas, but I gess they are retrieved directly from the game, which implies some are missing.
image
This nice little thing is able to achieve a circular orbit around Kerbin, at any inclination. However KSP2 and Kontrol System vessel.delta_v.stages[].get_deltav(DeltaVSituation.Vaccum) are undivided : the 4 firsts stages aren't able to deliver any thrust, and don't provide any delta V.
And I can garantee you that LV-1 'Ant' didn't lift it in the sky.
image

@PhilouDS
Copy link
Contributor

Thank you for all those explanations. Nice log in the Console. Too bad we can't save that in a txt file... yet ;-)
In the BAV, I've created an UI and I compute myself the effective velocity of a stage to calculate then the delta-v. Maybe, I could look deeper of what you did to improve that.

At least, my stage info window (at the bottom) is better than the one from MicroEngineer (which only uses the numbers from KSP).

image

@lefouvert
Copy link
Author

lefouvert commented Mar 1, 2024

@untoldwind I see you ^^
Thoses things_array.reduce(<Foobar>[], fn(flat, things) -> flat + things.filter(fn(t) -> t.defined)) seems to had given you some inspiration :)
Thank you very much.
For that and all.

@untoldwind
Copy link
Owner

That are a lot of wishes and unluckily I messed my games-saves I use for testing. So there is just a pre-release for now: https://github.com/untoldwind/KontrolSystem2/releases/tag/v0.5.3.5
Updated documentation: https://kontrolsystem2.readthedocs.io/en/prerelease/

From top to bottom (mostly):

  • I added a .filter_map to array, which is similar to .map but the function should return an Option and only the defined value end up in the result.

    • So to get a list of all the solar_panels one can now just do vessel.parts.filter_map(fn(part) -> part.solar_panel)
    • Similarly all the other things like fairing/air intakes etc.
  • Also added a .flat_map, in which the function returns an array, that as then concatenated in result.

    • E.g. to get all the resources of a vessel: vessel.parts.flat_map(fn(part) -> part.resources.list)
  • As for the fairing: I checked the current implementation, part.fairing seems to be working as intended. Maybe you have a cargo-bay instead, which can be found and controlled via part.deployable?

  • As for solar panels: The energy-flow is actually a bit more complicated:

    • There is now a .base_flow_rate and .efficiency_multiplier which seem to be constants of the model
    • Additionally there is the .star_energy_scale which changes with the distance to the star (and probably also depends on the type of star once we get the interstellar patch)
    • The .max_flow is a shortcut for base_flow_rate * star_energy_scale * efficiency_multiplier
    • And eventually: .energy_flow is the current energy flow which is a fraction of .max_flow depending on sun-exposure (and angle I guess)
  • As for the propellant/resource information of the engine: Again a bit more complicated

    • There is now a .current_propellant which is the currently used propellant depending on the engine mode
    • Additionally .propellants returns all the potential propellants in the same order as .engine_modes (if the engine only has one mode there should be only one element)
    • Unluckily it gets even more complicated: The propellant might be a mixture different resources.
    • E.g. most engines will have .current_propellant.name == "Methalox", which is a mix of two resources
    • In these cases .current_propellant.is_recipe is true and .current_propellant.recipe_ingredients will contain a list of all the ingredients and their ratio.
  • The heatshield has been added with some basic fields: is_deployed is_ablating is_ablator_exhausted ablator_ratio

    • ... maybe this can be a bit more detailed
  • As for the thrust limiter: This should now be tweakable via engine.thrust_limiter

  • As for warp: Some basic information should have be already available in the ksp::game::warp module: https://kontrolsystem2.readthedocs.io/en/prerelease/reference/ksp/game_warp.html

    • At the moment this is read-only. I will check if there is an easy way to make tweakable as well

@lefouvert
Copy link
Author

lefouvert commented Mar 1, 2024

Undoubtly, you may say me 'no' at anytime, if it's bad ideas or too much work. Besides, I'm blown away by the speed you implement all thoses !
From top to bottom ;) :

  • .filter_map & flat_map smell like candies. I'll have to re-read all my code to add this, it will be way more readable :)
  • Fairings : I'm not saying they don't work as intended. They absolutly work as intended. I was just seeking an idea to differenciate the "explicit" fairing as 'AEFF000' part or 'AEFF375' part, and the "implicit" fairing, as the one which cover an engine or a heatshield.
    issue130
    I have a .check_fairing() method which is unable to see any difference between both, and after having successfully jettisoned the AEFF125, try desperately to jettison the engine fairing. In vain, obviously, since it will be automaticly jettisoned at the staging, not before, not after.
  • solar panels : I understand why you had to take care of all thoses parameters. I must admit it was an untold wish to have access to all of them. I'm fulfilled. I had some testings on solar panels, so I can answer you : Yes, .energy_flow is totaly dependent of the angle :)
  • Engines' propellants : as solar panels, your implementation is above expectations. Does .recipe_ingredients contains a list of 1 ingredient if it's not a recip, (for monoprop, for example) ?
  • Heatshield : at the time, I don't see more which could be usefull.
  • thrust limiter : Oh that's a cheating parameter x). Solid Booster powered launcher with in flight variable thrust will appear soon. I can garantee it ^^. I'll try for fun, but not in main code base.
  • Warp : PhilouDS oriented gift. At the time, I do not have any needs on this topic, since I do not have ended my ship.park() method which is , for me, a mandatory to warp. I will not let my vessel deplete all EC while time warping because of bad sun exposure :)

Can I say enough 'thank you' to illustrate how much I'm happy with all thoses addings ?

Edit typo, grammar etc as usual

@untoldwind
Copy link
Owner

Ah ok, the engine fairing was not on my radar. Quick workaround would be to filter out the engines before using .filter_map. E.g.

vessel.parts.filter(fn(part) -> !part.is_engine).fitler_map(fn(part) -> part.fairing)

But I understand that this is somewhat confusing. I'll probably split the API in .fairing and .engine_fairing

As for the the propellants: If .is_recipe is false than the propellant is just the resource that is used, i.e. .receipe_ingredients should be empty. Otherwise this would be just a reference to self.

@lefouvert
Copy link
Author

As said, I had think about excluding engine parts, howerver, this behavior is also true for heatshield (nice we can recognize them and exclude them now ^^) AND at least thoses parts :

  • Structure/MountPlate/MEM-XXX
  • Structure/Tube/TUUB-XXX
    And maybe some other I could had miss.

@untoldwind
Copy link
Owner

untoldwind commented Mar 2, 2024

Created a new pre-release: https://github.com/untoldwind/KontrolSystem2/releases/tag/v0.5.3.6

  • part.fairing should now only cover fairings
    • EDIT: Sorry saw that last comment too late, only engines are excluded. I will try to find a stable way to only get "real" fairings.
  • For engines: part.engine.fairing or part.engine.has_fairing
  • To get cargo bay (which are deployables) there is now also a part.is_cargo_bay
    • Note: There is no corresponding part.cargo_bay because cargo bays do not really have any interesting values to tweak that are not covered with part.deployable

As for the time-warping:

@untoldwind
Copy link
Owner

Hopefully this is the one: https://github.com/untoldwind/KontrolSystem2/releases/tag/v0.5.3.7

I added part.part_category and .fairing should now only contain fairings in the Payload category

@lefouvert
Copy link
Author

Just did few testings :
Notice deployable.value.deploy_state became a constant instead of a string. Nice touch ^^
Legitim fairings respond positively to .is_cargo_bay.
Will test others aspects later, but it smell good.

@lefouvert
Copy link
Author

Little engine test.
With is_recipe false, .recipe_ingredients is not even instancied (Not really surprizing).
Out of curiosity, why .recipe_ingredientsis not an Option<ResourceReceipeIngredient[]> ? (Just to get a better understanding ! )

@untoldwind
Copy link
Owner

Yes good point that should be an option.

@untoldwind
Copy link
Owner

I merge it all into the 0.5.4.0 release.
.recipe_ingredients is now Option<ResourceReceipeIngredient[]> as suggested

@lefouvert
Copy link
Author

Sorry, I was a bit busy this week-end, so I can't look at all I was expecting on KSP2 & KS2.
Browing datas and engines, I was thinking about propellants.
EngineMode govern which propelant is used, this is why an array is needed for part.engine_module.propellants. After had read your source code (and what I assume to be KSP2 .dll api's files like Data_Engine.cs), I assume index of part.engine_module.propellants match index part.engine_module.engine_modes.
Would it make sense that propellants be a property of EngineMode (not array, therefore, but keeping the notion of recipe and the recipe array) rather than ModuleEngine?
It's just an idea to talk about.

@untoldwind
Copy link
Owner

I just noticed that the underlying structure of EngineMode also has a propellant definition, have to check if that is in sync with the the one on the engine though.

@untoldwind
Copy link
Owner

untoldwind commented Mar 8, 2024

@lefouvert I guess the problem is that you opened/started the editor on the KontrolSystem2 folder and not the to2Local folder. If your workspace is just the to2Local folder a lot of those errors should go away.
Under the hood the plugin has to scan two folders:

  • The to2 folder with the std:: modules, which can be configured in the settings
  • ... and the to2Local folder, which is implicitly assumed to be the root-folder of the editor workspace (and cannot be configured yet).

I will add some better heuristics, or at the very least make the latter configurable as well.

Speaking of the std:: module: That one is still underdeveloped. Would it make sense to integrate some of your to it?

As for the programming language debate:

  • Most elements of to2 are inspired by rust, but there are some elements of typescript as well. The main goal was to have a strictly typed language that is async by default, so that it can run as a coroutine in the unity engine, and can be compiled/updated in the game itself
  • The parser/compiler is obviously written in c# (which in itself is not so far of from java or c++). Main reason is that c# is the primary language for unity and pretty much the entire game is written in it as far as I can tell.
  • ... where is becomes very specific (and complicated) is the code emitter. Under the hood there is heavily use of the System.Reflection.Emit package so that to2 is translated into byte-code
    • Upside to this: to2 scripts are almost as fast as corresponding c# code
    • Downside to this: Its very hard to understand and its where all these funny "Negative Stack count" errors come from.
  • And to round things up: The vscode extension is written in typescript

@lefouvert
Copy link
Author

You'r right :
My workspace is at KontrolSystem2 level and not to2Local. It was to be able to browse to2 folder at any time I need a hint about how things works.
Switching to to2Local kind of solve some issues. Modules are found, type hints are visible, however, a lot of things are <unknown> type leading to error message
image

About std:: (do not confuse with Sexual Transmissible Disease. Sorry, the joke just pass through my brain, it's the first time I see initials match), I have 2 considerations :

  • Does people enjoy KS to have a friendly tool to code for a game they love, or do they want a ready-made script to automate missions ?
  • I'm afraid my own libs are underdeveloped too.

In anycase, I would to git publish my work (when it's done), but maybe you are right, maybe instead I wait to think it's perfect, it's time to share, even if some things are clunky. (Even with years of collaborative work, I still want to reach the unreachable 'perfection' and often solowork. Bad habits. Not good to evolve.)
As soon as I found how to properly publish my work on git, I give you the link. Don't expect to much, I have A LOT of things missing (I'm just able to circularize properly) and maybe some code are just duplicates of existing tools in KS ( I've just seen this afternoon they are a ksp::control::MovingAverage which could be an evolved version of my math::tools::Derivative, for exemple) and things are still cluncky (maneuver::takeof::sanityCheck is my first work, in parallel with ship::stage.to2. It's obvious with hindsight it should return a Result type)

And does it make sense to combine efforts to enrich KS ? -> Yes. Yes yes yes.

programing debate :

The main goal was to have a strictly typed language that is async by default, so that it can run as a coroutine in the unity engine, and can be compiled/updated in the game itself

It's all to your credit. Everything in this sentence is beautifull.

inspired by rust

Hahaaaa ! My sight is still fonctional.

typescript as well

Feel like you had seen and wrote typescript (the only respectable usage of javascript :P) as daily routine. Not surprizing it pop out in this mod :)

The parser/compiler [...] in c#

Obviously, as said. Not sure their is an other sane way to do it. As I use frequently C# in my current job's project (in an 'not encline to code' tool, UiPath. Not my jam, UiPath. I would prefer wrote codelines. It look like Scratch), I can confirm : not so far from java. A bit more from modern C++, I feel, but mains concepts are the same.

System.Reflection.Emit package so that to2 is translated into byte-code

Wow. I was suspecting something like that because of the smoothness of the execution. That's why code is so fast, so. I can imagine both the joy of the performances and the pain of the maintenance and evolving.

The vscode extension is written in typescript

Didn't know it could be done in other way, but I don't doubt any second it's very specific to VSC, well documented, and poorly accessible (Not your work, the VSC incorporation)

@untoldwind
Copy link
Owner

There were actually a bunch of array methods missing. Should be fixed in:
https://github.com/untoldwind/KontrolSystem2/releases/download/v0.5.5.3/to2-syntax-0.0.31.vsix

I also added a simple logic to automatically look for "to2" and "to2Local" subfolders if the editor is opened on the plugin dir.

@lefouvert
Copy link
Author

lefouvert commented Mar 8, 2024

Hello MyJunkCode.
You can take a look if you want. As it's in 'work in progress' state, it may be not properly tidy. (lol, nope. It's just a mess)
Ask as many question you want. I'm open to ... no, I HOPE (constructives) criticisms.

And obvioulsy, you can take anything which seems usefull.

@untoldwind
Copy link
Owner

untoldwind commented Mar 9, 2024

Wow, that is actually a lot ;)
Would it be okay to link that repo in a "Code examples"/"Community projects"/"Cool things you can do with this mod" section either to the README or the docs?

One minor (hopefully constructive) criticism: You use a lot of return in you functions. The final return in a function is not necessary, since every expression has a result and a { code } block has the result of the last expression in that block.

E.g.:

pub sync fn latitude_from_angle(angle: float) -> float = {
    return asin_deg(sin_deg(angle))
}

is the same as

pub sync fn latitude_from_angle(angle: float) -> float = {
    asin_deg(sin_deg(angle))
}

And that can be shorted to:

pub sync fn latitude_from_angle(angle: float) -> float = asin_deg(sin_deg(angle))

Edit: Takeaway for me is that the vscode-plugin still has a lot of problems with inline-comments (i.e. the parser in vscode is slightly out of sync with the parser in the mod)

@untoldwind
Copy link
Owner

I was not able to fix all the issues in the vscode extension yet, but
https://github.com/untoldwind/KontrolSystem2/releases/download/v0.5.5.5/to2-syntax-0.0.33.vsix
should have some improvements (at least it is not all red ;) )

Also I found: https://github.com/lefouvert/ToTheMoon/blob/0ecfbb5e239a7e5195866633a60bf427010d9b13/ship/ship.to2#L207

Due to the restructuring in for ksp::oab this should be now

fn() -> vessel.command_modules[0].part.global_position,

@lefouvert
Copy link
Author

Have to go for tonight, so short answer :

Wow, that is actually a lot ;)

thx ^^

Would it be okay to link that repo in a "Code examples"/"Community projects"/"Cool things you can do with this mod" section either to the README or the docs?

Of course, yes, it's okay.

One minor (hopefully constructive) criticism: You use a lot of return in you functions. The final return in a function is not necessary, since every expression has a result and a { code } block has the result of the last expression in that block.

Totaly true and understood, I work (not enough) on myslef to correct this bias. ship.isp is what I should do more.

(hopefully constructive) criticism:

The 'constructive' precision is because in my native language, this word is by default 'negative'. I know for sure here is a caring space. And yes, it's a constructive answer.

should have some improvements (at least it is not all red ;) )

Thx !

Due to the restructuring in for ksp::oab this should be now
fn() -> vessel.command_modules[0].part.global_position,

Noted. Will be updated. Thx :)

@untoldwind
Copy link
Owner

This one is almost there: https://github.com/untoldwind/KontrolSystem2/releases/download/v0.5.5.5/to2-syntax-0.0.34.vsix

The only remaining problem is that ship.stages sometimes does not resolve correctly.

@untoldwind
Copy link
Owner

The 0.0.36 version in 0.5.6.0 should have ironed out most of the issues. (Thanks for the project btw, that helped a lot finding all the hidden cracks).
I also added long overdue string-interpolation (like here:

CONSOLE.print_at(console_row , 0, $"DV remaining: {dv_min.value,10:N1}")
)
... that should make formatting all the string output much easier.

@lefouvert
Copy link
Author

lefouvert commented Mar 10, 2024

Yay ! Happy to know I've done something helpfull :) (but not very proud you have seen how much i'm struggling to just turn my vessel in the direction I want ^^)
I assume string interpolating work in similars ways of core::str ? (Hû, sorry, i'm dumb, it's in the patch note ^^)

About parser for your compiler and for VSC, speaking with a friend today, he reminds me it exists some meta-language usefull to describe the grammar and the syntax of a language, which are able to automaticly generate code for your lexer and parser in various programming language. ANTLR is one of thoses, able to generate C# and typescript. The advantage of this is you decribe one time 'to2', you get as many lexer/parser you want in different language. I'm sure you see why it could be usefull when you have compiler in C# and a VSC extention in Typescript :)
I'd never used them so I can't be very helpfull, but now you know :) (At time when I'v done a parser, it was a parser for KOs' KSP1 '.ks' script... in '.ks' script, and ANTLR don't know this language ^^)

Edit :
VSIX parser :
ksp::console::CONSOLE.print_at(17, 15, $"roll: {core::math::clamp_degrees180(testdir0.roll),5:N2}") everything goes fine
ksp::console::CONSOLE.print_at(17, 15, $"roll: {core::math::clamp_degrees180(testdir0.roll), 5:N2}") it's apocalypse because of a whitespace after the coma :D. Compiler compile but don't consider the display hint ^^

@untoldwind
Copy link
Owner

I probably should update the language documentation as well and not just leave it with a brief patch note ;)
In short: Yes, under the hood a string interpolation is converted into a c#/.dotnet string.Format call (which pretty much what core::str does as well).

I will fix the space after comma thing. I wanted to prevent runtime error (string::Format crashed if there is anything but a number after the comma) and was a bit zealous with the parser.

Speaking about parsers:

  • ANTLR comes along with a pretty big runtime library, i.e. the generated code does not work without it. If I remember correctly there was as version conflict with the dotnet ANTLR needed and what unity had back then (the whole project started started about 5 years ago for KSP1).
    • ... plus I was somewhat hesitant to rely on a third-party library inside a game-mod (i.e. "what happens if there is another mod requiring the same library but in a slightly different version?" ... or am I over-thinking it?)
  • The alternatives (there are a whole bunch of LL/LR/LALR parser generators out there ... cough ... yacc/bison ... cough) either did not support c# or had the same problem.
  • So what I went for instead was using a parser-combinator pattern (or rather a "Monadic Parser Combinator" if you want to impress someone ;) ), which can be done in pretty much any language (e.g. Rust: nom, Scala: scala-parser-combinators (duh), Haskell: parsec, C#: Pidgin,ParsecSharp, Java: ParsecJ, java-petitparser, Kotlin: better-parse,konbini ... and so on)
  • ... but yes, parser-recovery and syncing two implementations is cumbersome, so using an off-the-shelf solution might worth another look

@lefouvert
Copy link
Author

Ah... The tedious task of maintaining a documentation... I always run when it's about documentation : Run to read all of it, Run away when I have to write it :D. (Yup, I read the documentation of my calculator, my car, and my washing machine)

ANTLR was just a random example, but as you seem to have a good view of the spectrum of possibilites cough bison meat is savourous cough and limitation, you probably have made the best choice.

As most of my related are essentialy,

  • or way better than me in software engenering (I start way later than them, 10 years of fastfood service have a harsh cost, and I kept in touch mostly with the most ingenious of my classmate)
  • or exclusively inclined towards musical fields

I'm pretty sure if I slip a 'Monadic Parser Combinator' in a chatting, I'm going to trigger some laught. Too easy or too hard according to the context ;)

5 years ago !? How didn't I heard about your project at KSP1 times ? Have heard about kRPC, stick on KOs, but Kontrol System ? I found you when KSP2 became enough 'early access bug free' (and on sales) and intuitively search for the only kind of mod I really care : A tool which allow me to code launcher behaviors. (maybe Remote tech too, but it's less appealing to me), thanks to this post : KSP Forum
I had a lot of fun with KOs, but the language was not enough rigourous, terribly slow, full of memory leak and other kind of memory breaking (some switch between Archives/onboard code source cause leaks between what should be local variables), not maintained anymore. I blame nobody, it's understandable, but if I had a better alternative and KS is a way better alternative, even if it have less possibilities. Yes, I can't make a satelite to interpret 2001 Space Odyssey intro in chip tune tone each time it reach orbit but hey... it's fine ^^, I would have made the transition without any doubt.
I have to admit it was fun to have different source of code, and different limitations bind with thoses (big code at KSC, cheap and slim code onboard) but it lead to bad practice since limitations are on char number (That why I had done a parser, to minify onboard code, and don't have to wrote 1 char variable/function names). It was fun to warp the language enough to be able to make class via lexicon and delegates but still, KOs always have been intrinsically cluncky.
So, thank you (again) for this mod. It's made with, at my sight, the goods precepts and it don't seems to be able to grow in bad ways.

@untoldwind
Copy link
Owner

The 0.5.6.1 release should be a bit more lenient with the alignment part of the format string.

On the other topic: Actually it is good to get challenged from time to time. It is so hard to keep in touch with all the different developments. For example I found this pretty interesting article https://eyalkalderon.com/blog/nom-error-recovery/ with some fresh ideas that might improve the error-reporting a bit.

Copy link

This issue is stale because it has been open for 60 days with no activity.

@github-actions github-actions bot added the stale Issue has not seen activity for 60 days label May 12, 2024
Copy link

This issue was closed because it has been inactive for 14 days since being marked as stale.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request stale Issue has not seen activity for 60 days
Projects
None yet
Development

No branches or pull requests

3 participants