Skip to content

Add shared ModuleNameTag part module#23

Merged
SofieBrink merged 9 commits into
KSPModdingLibs:mainfrom
djungelorm:add-nametag-module
Jul 18, 2026
Merged

Add shared ModuleNameTag part module#23
SofieBrink merged 9 commits into
KSPModdingLibs:mainfrom
djungelorm:add-nametag-module

Conversation

@djungelorm

@djungelorm djungelorm commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Add a shared ModuleNameTag part module so kOS and kRPC can stop each shipping their own copy.

Background

kOS and kRPC each define a part module named KOSNameTag (kRPC's is an adaptation of kOS's). Two loaded assemblies defining the same simple type name is only safe by load order - KSP resolves a type-by-name lookup against loadedAssemblies in order, and it currently picks the right one only because kOS happens to sort first. A recent KSPCommunityFixes change (KSPModdingLibs/KSPCommunityFixes#307) showed this breaks as soon as anything perturbs load order. See krpc/krpc#829, where moving the module here was suggested.

This PR brings the module into KSPCommunityPartModules as ModuleNameTag; companion PRs on kOS and kRPC drop their own copies and depend on this mod.

What's here

The commits are sequenced so the history separates what was imported from what changed:

  1. Import kOS's KOSNameTag part module and its editor window verbatim (provenance snapshot - see licensing note below).
  2. Adapt it to build here (namespace, drop kOS-only dependencies, inline the small camera/career helpers, wire into the project).
  3. Rename the class to ModuleNameTag (persistent field kept as nameTag, the save key). User-facing strings neutralised.
  4. Fix two long-standing editor bugs the copies shared:
    • Click-through - the window locked editor input with EditorLogic.fetch.Lock(false, false, false, ...), whose all-false flags never lock part pick/place, so clicking Accept/Cancel dragged whatever part sat behind the button. Now uses InputLockManager.SetControlLock(ControlTypes.EDITOR_LOCK, ...).
    • Lock-id collision - the editor lock id was a fixed string, so closing one open name-tag window released the lock for all of them. The lock id is now per-window.
  5. Simplify for shared use - drop the isEnabled=false PAW workaround (the field is guiActive), keep the OnAwake duplicate-removal guard (kOS #2764).
  6. Backwards-compatibility migration - a Harmony prefix on Part.LoadModule rewrites a legacy MODULE { name = KOSNameTag, ... } node to ModuleNameTag before KSP binds it, so name tags on existing craft and saves are preserved. Both the editor craft path (ShipConstruct.LoadShip) and the flight path (ProtoPartModuleSnapshot.Load) funnel through Part.LoadModule, so the one hook covers both. It is skipped if a real KOSNameTag type is still loaded, so an un-migrated kOS/kRPC install is not misrouted.

I verified in-game: with this mod installed and craft that still contain old KOSNameTag nodes, the tags load onto ModuleNameTag.

Licensing - needs your call

kOS is GPLv3 and this mod is MIT, so the imported file (commit 1) can't simply be relicensed. Two options: get the kOS name-tag author's agreement to relicense that file under MIT, or carry it here under GPLv3 with an explicit per-file header + a note in LICENSE.md.

Left out for you to decide

I intentionally did not bump the version or edit the README, since those are release/maintainer calls. For dependents (kOS and kRPC) to require the build that contains ModuleNameTag, the KSPAssembly version in AssemblyInfo.cs would need bumping (the kOS/kRPC draft PRs currently declare KSPAssemblyDependency("KSPCommunityPartModules", 0, 5), i.e. they expect a 0.5.0 release).

And here is a suggested README entry:

  • ModuleNameTag
    Adds a user-editable name tag to a part, set through an in-game window. Shared by kOS (part:TAG) and kRPC (Part.Tag) so a tag assigned by one is visible to the other. Consuming mods add the module to parts with their own ModuleManager patch; legacy KOSNameTag tags from older kOS/kRPC saves are migrated automatically.

Companion PRs

Copies kOS's KOSNameTag part module and its KOSNameTagWindow editor UI
unchanged from the kOS repository (src/kOS/Module/KOSNameTag.cs and
src/kOS/Screen/KOSNameTagWindow.cs) as the starting point for a shared
name-tag module. This commit is a faithful byte-for-byte snapshot; it is
not yet wired into the build. Subsequent commits adapt it for
KSPCommunityPartModules.

Provenance: adapted from the kOS mod (https://github.com/KSP-KOS/KOS),
which is licensed under the GPLv3. See issue krpc/krpc#829.
Moves both files into the KSPCommunityPartModules.Modules namespace,
removes kOS-only dependencies (SafeHouse.Logger becomes Debug.Log with a
[MODULENAME] prefix; the camera helper and editor-building career gate are
inlined so kOS's Utils/Career/Safe assemblies are no longer needed), and
wires the two files into the (non-globbed) project file. The class name
KOSNameTag and the persistent nameTag field are unchanged for now; a later
commit renames the module.
Renames the part module class KOSNameTag to ModuleNameTag (and its files
and the window/activation-manager helper types) to follow the
KSPCommunityPartModules Module* naming convention and to drop the
kOS-specific name. The persistent nameTag field is deliberately unchanged
so it remains the save key; a Harmony shim in a later commit migrates old
KOSNameTag save nodes to the new module name. User-facing strings are
neutralized (window title and PAW group).
The window locked editor input with EditorLogic.fetch.Lock(false, false,
false, ...), whose all-false flags never lock part pick/place, so clicking
Accept/Cancel dragged whatever part sat behind the button. Use an
InputLockManager EDITOR_LOCK instead, which includes pick/place, and pair a
matching RemoveControlLock in Close().

The lock ID was also a fixed string shared by every window, so closing one
open name-tag window released the lock for all of them. Make the lock ID
per-window (keyed on the instance id).
Removes the isEnabled=false optimization and the NameTagActivationManager
KSPAddon that existed only to re-show the field in the part action window
after that optimization hid it. The field is guiActive already, so it shows
in the PAW directly. The OnAwake duplicate-removal guard (kOS #2764, for
parts that get the module added twice) is kept.
Adds a Harmony prefix on Part.LoadModule that rewrites a saved
MODULE { name = KOSNameTag } node to name = ModuleNameTag before KSP binds
it to a prefab module. Both the editor craft path (ShipConstruct.LoadShip)
and the flight path (ProtoPartModuleSnapshot.Load) go through
Part.LoadModule, so this single hook preserves tags from craft and saves
made with the old kOS/kRPC modules. The nameTag value key is unchanged, so
it binds directly once the module name matches.

The rewrite is skipped if a real KOSNameTag PartModule type is still loaded,
so an old kOS/kRPC or the retired standalone NameTag mod is not misrouted.
@SofieBrink

Copy link
Copy Markdown
Collaborator

Hey! Thanks for this detailed PR, it all looks pretty good on first glance but I'd like to have another look at it later when I'm at a pc before merging anything. I'll approve the workflows so they can at least so their validation already.

The 0.0.2-alpha.7 package did not provide the .NET Framework 4.8
reference assemblies, so the Linux CI build failed with MSB3644.
Version 0.0.4 supplies them, matching the build workflow which
already targets KSPBuildTools 0.0.4.
@djungelorm

Copy link
Copy Markdown
Contributor Author

Thanks.

Looks like CI was failing due to a change on dev branch to the build tools not being on main branch. I bumped KSPBuildTools to 0.0.4 matching the fix already on dev - hopefully it passes now.

@SofieBrink

Copy link
Copy Markdown
Collaborator

Looking at Dunbaratu's activity I feel it's unlikely we'll be able to get the permission we'd need to relicense the files in a timely manner. So to make things easier I've just kept the GPLv3 license for those files.
As per CKAN convention a mod with multiple licenses should have the most restrictive license used for the metadata, hence the ckan changes.
I'll merge this now, remove some files from a deprecated module and write a wiki article for this new module then put out a release.

Thanks for the contribution!

@SofieBrink
SofieBrink merged commit 1a63fd4 into KSPModdingLibs:main Jul 18, 2026
@djungelorm

Copy link
Copy Markdown
Contributor Author

Excellent, thanks for the very prompt review and merge!

@SofieBrink

Copy link
Copy Markdown
Collaborator

No worries, the release should now be public on GitHub and Spacedock. I expect it will come to CKAN within the hour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants