#API Discussions Conventions

254 messages · Page 1 of 1 (latest)

shut forum
#

Topic of this thread:

  • What conventions do we want?
    • Any naming schemes?
    • Style rules? (Enforceable through git, for example)
    • Etc...
maiden heart
#

GUID Naming should start with org.lcmodding.api or org.lcmodding-api

shut forum
#

I think org.lcmodding.api is nice. It gives us future flexibility in case we would for whatever reason release non-API mods as an org. (For example tools or whatnot)

maiden heart
#

Register/Unregistering method should be named

 // parameter are optional, if there is a parameter put them in
public static bool Register()
public bool Register()
public static bool Unregister()
public bool Unregister()
#

any suggestion?

shut forum
#

How often would APIs have this?

#

Also, @mellow raven defo needs to provide input on this

maiden heart
mellow raven
#

otherwise what are you registering

shut forum
#

I think Ozzy is moreso referring to the name of the method

maiden heart
shut forum
#

Rather than the signature

mellow raven
#

I think for registering commands from an instance, the terminal library should still stick to RegisterFrom

#

there is still a .Register method to register a specific TerminalCommand instance

maiden heart
#

All assembly must be contained within the root namespace LCAPI or LC_API

#

@shut forum @mellow raven how do you guy feel 'bout this?

shut forum
#

LC_API is already used by the dependency for the BiggerLobby mod.

#

That being said, do we want a single namespace?

#

Remind me, can you nest namespaces in CSharp?

maiden heart
shut forum
#

Then I'm not sure if a single namespace is a good idea tbh? What about potential naming conflicts?

maiden heart
shut forum
#

Hm, fair

maiden heart
#

just everything must be contained within LC_API namespace as a root

shut forum
#

Considering the pre-existing mod with that name. Go for LCAPI?

maiden heart
#

let create the repo right now

shut forum
#

LC_Mod_API?

maiden heart
maiden heart
#

naming?

shut forum
#

Was spitballing namespace ideas

maiden heart
#

i have just setup the core project

#

not yet got anything in it

shut forum
#

Hold up, we'll want to create it in the org for the wiki

#

And discuss what APIs to create

maiden heart
#

let the repo named LC Modding API

shut forum
#

We probably shouldn't do a monorepo if we plan on having different APIs?

shut forum
#

Hence, we should decide what APIs we want to create, do some minimal planning, and then create repos for each

#

Just gotta decide the split first

mellow raven
shut forum
#

I was just spitballing, Ozzy suggested using a common namespace

mellow raven
#

yea, that would be best

#

though you don't typically use underscores in namespaces

maiden heart
shut forum
#

I'm not sure if I love it, yeah

maiden heart
#

LCAPI is enough for now

shut forum
#

It's a bit long

#

LCAPI sounds good to me

mellow raven
#

yea, LCAPI works

#

so my one would be LCAPI.Terminal or LCAPI.TerminalCommands

maiden heart
#

yeah

shut forum
maiden heart
#

if you found that you may get naming conflict

#

just nest another namespace

mellow raven
#

I figured you were getting that from another lang lol

maiden heart
#

like LCAPI.Terminal.OtherClassOrObject

mellow raven
#

yea, namespaces are meant to be hierarchical

maiden heart
#

just don't nest it like java

mellow raven
#

all under the root Monogon namespace

#

makes it easier to find similar/grouped APIs, rather than trying to figure out what namespace a certain mod/library is using

#

just use intelisense after typing LCAPI.

balmy spade
balmy spade
mellow raven
#

yea, not sure either

maiden heart
#

but as least thatt is long enough for it to not conflict with other bepinex plugin

balmy spade
#

guid should follow the namespace

mellow raven
#

honestly not the biggest fan

balmy spade
#

imo

mellow raven
maiden heart
#

even bepinex docs example also use it

#

so i just put it like what they suggest

balmy spade
#

the docs aren't always the best convention

#

see harmony for example

maiden heart
balmy spade
maiden heart
balmy spade
#

yeah

#

as long as it's not the one LC_API uses lol

maiden heart
balmy spade
#

😨

shut forum
lean kestrel
#
LCAPI/
  - API/
    - Networking / 
      ~
    - Items /
      ~
    - Moon /
      ~
  - Patches /
    ~ 
shut forum
#
  • 1️⃣ Separate repositories for each API
  • 2️⃣ Monorepo with single solution but different projects
  • 3️⃣ Other - please elaborate
#

@lean kestrel @balmy spade @maiden heart @mellow raven @unreal lintel

lean kestrel
#

this is my organization thoughts

#

(my model is this framework because of how much i've used it, and how well maintained it is)

shut forum
#

Yeah, I can see the allure.

#

@mellow raven @maiden heart

Could you elaborate on why you voted 1️⃣?

maiden heart
#

well i dont like look at a solution that have 12 project in them

mellow raven
#

Since they are independent libraries/modules of the same system, there I don't see any reason to have one big monolith repository

#

Microsoft doesn't keep all of it's APIs in a single repo after all

#

splitting them into their own github repositories helps reduce project file bloat, simplifies merging, and also allows per-library permissions and rules

shut forum
#

Merges and repo management was one thing I was worried about for a monorepo. So I'm glad I'm not the only one.

mellow raven
#

plus it also provides segregation of libraries, and responsibilities

#

makes it easier to deignate someone as the manager/active maintainer of a library

shut forum
#

That's a fair point.

#

I hope that's agreeable, @lean kestrel?

lean kestrel
#

I suppose

#

I just personally find it tougher to have to work on multiple repos, vs having a combined one (at least for frameworks)

As long as we bundle it into a one file release, I dont have a problem, but it is really annoying to have to upload more than one file just to update the api

#

I suppose if its a standalone library with a very specific purpose, there may be just cause to do that, but I believe it is bad practice for a framework

mellow raven
#

each of these libraries, while they might have dependencies, are independent and optional

#

and being able to make releases for them individually means we don't have to do a whole new release on every library when 1 breaks

#

we can bundle it all together though a specific website

lean kestrel
#

even if you combine libraries, this shouldnt be a problem

#

harmony patches should be patched independetly

mellow raven
#

but repository wise I think individual repos are best

shut forum
#

Git workflow makes it easy enough to do a combined build and release on an empty repo

lean kestrel
#

even if we did multiple projects this would be the case

shut forum
#

Each API has its own release, for people who want to just use that API.

The bundled API is released in an empty repo that pulls from all API repos.

We just have to make sure the bundled API can stand in for individual APIs.

#

Best of both worlds

lean kestrel
#

so the empty repo is for players

#

the individual repo is for devs

shut forum
#

All of them technically are for both. But players will most likely download the bundled one in practice I suppose.

#

That sound agreeable to everyone?

lean kestrel
#

yeah

#

as long as devs pull, it shouldnt be a problem

#

I think we should release the sub-libraries as individual nuget packages

#

We can add a config for each repo that enables / disables the plugin, and then a debug log one

#

that way if one does break, or players dont need it, they can disable it

shut forum
#

Let's start with getting some APIs off the ground, then we can work on how to deploy / distribute them easily.

#

Also, keep in mind we'll have Thunderstore / R2ModMan support now, so dependencies are installed and loaded automatically.

pulsar whale
#

Have you guys used external aliases at all before? I found it kinda annoying that LC dumps a lot of its classes in the root namespace

#

I've never actually used them in C# but you can define them like this:

      <Reference Include="Assembly-CSharp">
          <Aliases>LethalCompany</Aliases>
        <HintPath>$(LC_REFERENCES)\Assembly-CSharp.dll</HintPath>
      </Reference>

and then you can use them like this:

extern alias LethalCompany;

public class Item : IObjectWrapper<LethalCompany::Item>

I'm not sure if there is some other way to use/alias references in the root namespace of other assemblies, but this seemed like a very quick way

lean kestrel
#

lmk what you think

#

I think we should include these in all projects. If we intend to maintain this api, it will probably be necessary to keep it clean and up to date. It will help if we start off strong in this manner.

#

These are the prs I made to the original LCAPI but I can adjust them to the new one

#

also what are your thoughts on putting patches in separate files. I think it makes it more maintainable

lean kestrel
lean kestrel
#

ill take a look tomorrow morning

#

if i have some time, ill try to start helping some implementations but right now im stuck in a juggling act of life

vital socket
#

I'll give a rundown of why I feel some of the APIs need to be in the same plugin

#

For example, the moons API needs access to a saves api

#

The saves api is does using a very large amount of transpilers

#

The item API and creature API all need to communicate with that same save system

#

Then on top of that the terminal API would be utilized by all three

#

While it could be separate it would feel easier atleast to avoid race conditions and similar by keeping them in the same plugin

#

The server API would require access to registered mods

#

Which might also be needed by items, moons, or creatures

#

There's also the config mod which I was planning on making seperate

#

But it requires access to the saves api

#

And must be seperate

#

Effectively separating apis makes it alot harder to get them to communicate

maiden heart
#

There is 2 version of this, first it will split APIs into different plugins and the second is the combination of all of them into one for user

vital socket
#

And worst of all there is a very specific instruction order these plugins have to run at

shut forum
#

If the APIs are designed properly, there's really no reason they wouldn't communicate properly.

vital socket
#

I'm worried about the instruction order

#

Especially with transpilers

shut forum
#

Could you give a concrete example?

vital socket
#

So config api needs to be initialized after the save api

#

But the items API needs to be initialized after the config api

shut forum
#

Why does it have to be initialised after a save API?

vital socket
#

And any item mods need to be initialized after the config api

shut forum
#

Likewise with items?

vital socket
#

The config api needs to retrieve saved configs

#

From the modded lcgeneralsave

shut forum
#

Oh, we discussed how to handle modded savedata over at #1172376083216220304

vital socket
#

The item API needs to be initialized after for settings w/ it

#

How exactly are you planning on doing it

shut forum
#

A config also really should not rely on savedata. BepInEx provides config systems out of the box

maiden heart
#

there is a reason why BepInEx is the one handling them and not us

shut forum
#

^

vital socket
#

I agree but adding a 4th save location for users feels a bit annoying

#

Well technically 3rd I suppose

shut forum
#

We're not adding a 4th save location

vital socket
#

Third it would be (considering modded saves)

#

What else

shut forum
#

We're adding paired ModData for each save. That way, vanilla saves remain "safe" in case of an update, mod breaking / removal, etc...

vital socket
#

Ah

#

That's not how I've done it

shut forum
#

Well, that's how we're discussing it in #1172376083216220304

vital socket
#

That would potentially cause discrepancies with a bunch of shit

shut forum
#

No?

maiden heart
#

it won't affect much

vital socket
#

Yes

maiden heart
#

unless those 25 mods all use custom save data

vital socket
#

I suppose you're right

#

I just feel it makes it harder to manage saves

#

And let's say a user plays with a mod that gives them 10k credits by accident or

maiden heart
vital socket
#

Corrupts their save

#

S

#

Es3 is an easy to use library

maiden heart
#

we only care about saving the vanilla save

#

to protect against modder craze

vital socket
#

I like my modded saves system so having the three extra saves feels really nice

shut forum
#

That shouldn't be part of an API IMO

#

Should just be a mod that adds more save slots

vital socket
#

Well you see

#

The extra saves would be required to be accessed by the item api

shut forum
#

Why would it do that?

vital socket
#

So they'd have to be permanently attached

vital socket
shut forum
#

That seems like very prone-to-breaking design

vital socket
#

Because the main item IDs is stored in a list

maiden heart
#

let continue in #1172376083216220304

shut forum
#

Agreed

maiden heart
#

@lean kestrel @shut forum how do you guy think we rename Plugin.cs to EntryPoint.cs and it will be the point where the plugin/mod will do it startup and patching

lean kestrel
#

Plug-in has to call events.onenabled

#

Also patching for events may just become dynamic

#

I think plug-in is fine

#

It could be called bootstrap but plug-in feels more fitting

#

Since it’s in the root project folder, it should be pretty distinguishable

#

Max is asleep for the night and I’m about to go to bed as it is 2 am for me

#

I’ll push my event api ra

maiden heart
#

it just the startup call that may create conflict

#

like for example one is pr-ing terminal and modify the entrypoint to call something.setup() and then the other pr call something2.setup()

#

anyway let this sink down for now

lean kestrel
#

I am fine with that then. The startup method needs to follow proper naming conventions, and should probably be static for api usage. Let’s add a singleton and a bool to prevent double loading

#

Also make it public

#

I like using costura a lot which can embed dependencies straight into the file, but there has to be code that is called at runtime to unembed the dependencies.

#

I typically name the unembed code something like “setup dependencies”

#

So setup is a pretty good name

maiden heart
#

anyway i think we probably need to rename it to EntryPoint first and then the other will be decide later

lean kestrel
#

Check out my event repo

#

It clarifies the patching scheme

#

All patches will probably end up in the events/patches/general folder

#

I made three folders for different patch types, generic, fixes, and events

#

Next I make 800000 transpiler patches

maiden heart
#

not just (original name).cs in there?

lean kestrel
#

I might name them transpiler prefix and postfix at some point or put them in separate directories

lean kestrel
#

Patches can be applied only when they are are first subscribed to, which means that unnecessary patches may not even be patched in the first place

#

It will help prevent bugs, and the implementation is pretty clean and works well

maiden heart
lean kestrel
#

I prefer to use transpilers but I won’t be able to make them for awhile because we will need lots of patches very fast to keep up with the game

#

So prefixes and postfixes will be used for now

maiden heart
#

well i think you should go to sleep now

lean kestrel
#

I can probably make 2 - 4 transpilers a day

maiden heart
#

leave this for latter discussion

lean kestrel
#

Yeah good point

maiden heart