Package: selang
# Space Engine modding language abstractionUsing python, define complete systems in SpaceEngine.For motivations, see [my blog entry about this repository](lucas.bourneuf.net/blog/se-lang.html).## Short exampleLet's say you want to reproduce a simple solar system with a sun, an earth and a moon.You can write in `mysimplesystem.lp` the following lines:```asproot(sun,"MySimpleSystem").orbit(sun,orbit(earth,moon,"0.005"),1).```You now run selang on it:python -m selang mysimplesystem.lp -o ~/path/to/SpaceEngine/install/dirYou can now run SpaceEngine and press F3 to search and go to `MySimpleSystem`.## Installpip install selangOn random error, add `no-cache-dir`.To get the ASP part working, install [clingo 5](https://github.com/potassco/clingo/releases) in you $PATH.## CLI ExampleFirst, lookup some example of input data in [data/](data/), for instance the reproduction in JSONof [the full 4 Kalgash systems](data/kalgash.json) from [planetplanet.net]().Now, run the command:python -m selang data/kalgash.json8 files will be created : two for each of the four Kalgash systems defined in `data/kalgash.json`.The two files correspond to the SpaceEngine modding interface, that needs a star record (which should be named system record) and a planet record (which should be named object record).Note that the star record, ending in `.star.sc`, is quite trivial.Also, if you have the path to your SpaceEngine installation directory, for instance `~/games/SpaceEngine/`:python -m selang data/kalgash.json -o ~/games/SpaceEngineThis way, selang will directly put the generated files into the expected directories, i.e. `<SpaceEngine installation directory>/addons/catalogs/{star,planet}/`.There is some help about this CLI if you need it:python -m selang --help## API ExampleLet's say you want to reproduce a simple solar system with a sun, an earth and a moon.Using python and se-lang, you would write:```pythonfrom selang import ref, orbit, Model, model_to_semodel = Model('My little system',{  # structure of the system'sun': (1, orbit(1, eccentricity=0.04)),1: ('moon', orbit(0.05)),},{  # non explicit objects1: ref('earth', earth_mass=1.2),  # super earth})model_to_se(model, '~/games/space_engine/SpaceEngine/')```### Alternative typingThe internal model used by se-lang is quite simple, and therefore may be used directly:```pythonfrom selang import ref, orbit, Model, model_to_semodel = Model('My little system',(('sun', 1, orbit(1, eccentricity=0.04)),(1, 'moon', orbit(0.05))),{1: ref('earth', earth_mass=1.2),  # super earth})model_to_se(model, '~/games/space_engine/SpaceEngine/')```## Interest of se-lang over the modding languageThe modding language of SpaceEngine is very well documented and powerful. However, beyond the simple cases described in the doc,you end up writing python scripts [to automatize some standard things, like rings](lucas.bourneuf.net/blog/uess.html).Instead of rewriting new python scripts each time, here it is: an internal model to rule them all. An internal model to be created by any format.An internal model to use for any case.## Input formatsThe internal model can be directly built by client code.However, to simplify the input, further work will focus on building the internal model usingother languages.### ASPASP is (logical) programming language, like prolog.It allows the high-level expression of logical relations, which is quite interesting for DSLs.It leads to very short programs, as show the following reproduction of all 4 Kalgash systems:```asp% Common to allroot(black_hole,"Kalgash").% Kalgash 2 systemorbit(black_hole,ring(sun,8),20).orbit(black_hole,orbit(red_dwarf,earth,"0.2"),10).% Kalgash 3 systemorbit(black_hole,ring(sun,12,orbit(1,earth,1)),20).% Kalgash 4 systemorbit(black_hole,ring(sun,8),1,retrograde).orbit(black_hole,earth,"2.5").orbit(black_hole,ring(sun,8),"4").% Kalgash 5 systemorbit(black_hole,ring(sun,8),1,retrograde).orbit(black_hole,earth,"2.5").orbit(black_hole,ring(blue_giant,8),20).```See other examples in [data/](data/).### JSONJSON is really close to Python basic types, and as such enablesa quasi-obvious mapping to the python API.As for ASP, previous implementation handled JSON-based input. It was verbose, but simple:```json{"name": "Kalgash 3","UID": "Kalgash","type": "black hole","childs": {"type": ["ring", 12, "sun"],"distance": 20,"childof": {"1": {"type": "earth","distance": 1}}}}```See other examples in [data/](data/).#### ASP vs JSONASP is (logical) programming language, JSON is a text format, so they differ in so many ways,you can assume they are different things.The ideal language to abstract modding of SpaceEngine is probably not one of these two,but i had fun making the corresponding interpreters, and using them for some [use cases](lucas.bourneuf.net/blog/se-lang.html).## dev- [x] ASP input: short and simple.- [x] JSON input: not programmable, but useful for simple work.- [x] Python input: good enough- [ ] lisp input.- [x] read input from file- [x] reproduce Kalgash systems from [planetplanet.net](https://planetplanet.net/2018/03/21/asimov-kalgash-take2/): [see blog entry](https://lucas.bourneuf.net/blog/se-lang.html)- [x] reproduce [UESS](https://lucas.bourneuf.net/blog/uess.html)- [x] find a way to simplify UESS encoding: python do the job.- [x] user-made spacing for rings- [x] specific treatment for elements of rings- [x] allow use of standard name for objects: `sun`, `earth`,…- [x] allow use of non-standard name for objects: `planet` and `star` functions.- [ ] injection of arbitrary SpaceEngine script code.- [x] full orbit definition- [ ] testing suite- [ ] handle star barycenter as object (bottom line: necessary to handle binary objects)## FAQ### Dinopython support ?No.### Contributions ?Yes.### Other things i did for SpaceEngine ?[se-pioneer](https://github.com/Aluriak/se-pioneers), for asynchonous multiplayer.