Skip to content

ScriptDev 1.1.0 - #265

Merged
viktor-ferenczi merged 2 commits into
mainfrom
script-dev-1.1.0
Oct 21, 2026
Merged

viktor-ferenczi merged 2 commits into
mainfrom
script-dev-1.1.0

Conversation

@viktor-ferenczi

@viktor-ferenczi viktor-ferenczi commented Oct 21, 2026 •

Copy link
Copy Markdown
Collaborator

ScriptDev 1.1.0, pinned to viktor-ferenczi/se-script-dev@daf5e5c, the head of viktor-ferenczi/se-script-dev#8, which keeps the vanilla menu layout and puts the Publish button next to Load Game. #8 isn't merged yet, so re-pin to its merge commit once it is. Features from #5 and #6 (already merged).

  • A Publish button next to Load Game in the main menu (next to Options in the in-game menu) opens a dialog that lists your local scripts and mods, shows which ones changed since their last upload, and publishes or updates them on the Workshop through the game's own publish screens.
  • New items can be published as Private first; the game itself always makes them Public.
  • Tooltip and description updated to match the plugin's manifest.

Tested on Linux (Pulsar Interim, .NET 10) with Steam: two private test items created and republished through the dialog. The .NET Framework 4.8 build compiles (Linux; the plugin source at 2dce778 is identical to the tested 06087a0), but Pulsar Legacy on Windows isn't tested yet.

@viktor-ferenczi viktor-ferenczi left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scope: version bump review of hub head 3b434595a01b23e3c7d7bfc106bbde7ed25675c0, Plugins/ScriptDev.xml, target viktor-ferenczi/se-script-dev, direct diff bf56ad22fbd49eac1964d71f97a50cdc4a380873..2dce778445b6ff44223bf194154c31dea40e2918.

No agent-detected blockers. The one note below is non-blocking.

Manifest

  • Only Tooltip, Description and Commit change. Id, SourceDirectories (Shared, ClientPlugin), no NuGetReferences, no assets, no dependencies.
  • The manifest has no <RepoId>. Pulsar falls back to Id (GitHubPlugin.RepoId => _repoId ?? Id), so viktor-ferenczi/se-script-dev is the source repo, as before.
  • python3 test.py Plugins at the hub head: All files validated. The xml-check CI job passes too.
  • The repo's backup ScriptDev.xml at the pin matches the hub manifest except for <Commit>.

Repository and pin provenance

  • Public, MIT, default branch main. main is at the pin (compare: identical), so there's no drift. The repo has no tags.
  • Range: 7 commits, 28 paths, +1748/−995. 11 of those paths are in the compiled Shared + ClientPlugin dirs (+1071/−979). The rest is dev tooling and docs outside SourceDirectories: setup.py, clean.sh, deploy .bat files, .run, AGENTS.md, the Dedicated/Torch projects and Directory.Build.props/Version.Build.props.

Security

The compiled changes are four new files plus a restyle of two shared helpers:

  • LocalItem.cs lists folders under MyBlueprintUtils.SCRIPT_FOLDER_LOCAL and MyFileSystem.ModsPath and reads file timestamps. It writes nothing.
  • Publisher.cs calls only vanilla public MyWorkshop APIs: FilterWorkshopIds, PublishIngameScriptAsync/PublishModAsync, GenerateModInfo and ReportPublish. Uploads start only after the user picks an item and confirms the vanilla tag screen. The only file the plugin causes to be written is the vanilla modinfo.sbmi, written by GenerateModInfo in the published folder, the same as the vanilla publish flows.
  • PublishDialog.cs gets item details through MyWorkshop.GetItemsAsync and marshals the result to the game thread with MySandboxGame.Static.Invoke. "Open in Workshop" uses MyGuiSandbox.OpenUrlWithFallback(workshopItem.GetItemUrl()).
  • Not found in the compiled diff: process execution, own networking, reflection on external input, dynamic code or encoded payloads. RecordCode in TranspilerHelpers writes .il files only under #if DEBUG and has no callers. VerifyCodeHash and [EnsureCode] aren't used by this plugin.
  • Hashing.Hash(string) replaces string.GetHashCode() with FNV-1a, so string operands hash the same way across runs on .NET Core. No [EnsureCode] hashes in this plugin depend on it.
  • Project references: packages.config and the 0Harmony reference go away in favor of PackageReference Lib.Harmony 2.3.3, which Pulsar supplies anyway. The Krafs.Publicizer and Publicize items are inside XML comments, so they aren't active. Every API the new code uses is public in the game. No committed binaries or native files are in the range.

Vanilla behavior checked (decompiled SE 1.210.014)

  • MyWorkshop.PublishItemBlocking replaces title and visibility with the existing item's values when the item already exists. So the dialog's tooltip "Updates keep the visibility the item has on the Workshop" matches the game. Vanilla calls always pass MyPublishedFileVisibility.Public, so the visibility selector only matters for new items.
  • GetWorkshopIdFromMod(path) reads the same modinfo.sbmi as vanilla GetWorkshopIdFromLocalScript. The owner check mirrors MyGuiScreenMods.OnPublishModQuestionAnswer. Passing "" as the script description is harmless because MySteamWorkshopItemPublisher sends the description only when it's non-blank.

Compatibility

MainMenuPatch postfixes MyGuiScreenMainMenu.CreateMainMenu and CreateInGameMenu (out Vector2 lastButtonPosition taken as ref). It shifts the buttons above the last one up and puts Publish one slot above the last. Pulsar's Patch_CreateMainMenu/Patch_CreateInGameMenu (Legacy, category Late) move the last button down and put Plugins in its place. I traced both postfix orders and each gives … Publish, Plugins, Exit without overlap. The only other hub plugin patching CreateMainMenu is LinuxCompat, and its postfix only changes the exit button text. No multiplayer authority surface: the feature uploads the user's own local content through vanilla Workshop calls.

From-source build

dotnet build ClientPlugin/ClientPlugin.csproj -c Release on Linux, .NET 10 SDK, net10.0, game DLLs from the local Steam install: 0 warnings, 0 errors. This is an MSBuild build, not the Pulsar Roslyn path. It compiles the same ClientPlugin + Shared sources, and the C# 14 features in them match Pulsar's LanguageVersion.CSharp14. I didn't run a load test.

Non-blocking notes

  • Note: LocalItem.GetLastChange enumerates every file under every local script and mod folder on the UI thread each time the dialog opens or Refresh is clicked. With large mod folders this could cause a visible hitch, and the dialog is also reachable from the in-game menu. An exception from an unreadable subfolder (UnauthorizedAccessException, a broken link) would also escape the button handler. This only runs when the user acts, so it isn't a blocker. If it becomes a problem, catching per item, or computing the timestamps off-thread and filling the table afterwards, would cover both.

@viktor-ferenczi
viktor-ferenczi merged commit 73c11f0 into main Oct 21, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant