Status: Research / proposal only (no implementation in this repo yet)
Audience: Future PR to ifBars/S1API + maintainers of this mod
Date: 2026-07-23
Related code: this repo (Schedule_I_Autocomplete); S1API console module under S1API/Console/
Desired end state (as requested):
Anyone who has S1API installed gets console autocomplete “for free,” whether or not other mods currently use S1API — i.e. shipping autocomplete with S1API (or as a tightly coupled default feature) so the Mods/Plugins layout of S1API enables it automatically.
Secondary goals:
- Autocomplete must see both vanilla/
Console.Commandsand S1APIBaseConsoleCommandsubclasses (today those are invisible to this mod). - Mod authors should be able to declare arg suggestions in a managed, Mono/IL2CPP-safe way (same spirit as
BaseConsoleCommand). - Stay consistent with S1API’s design rules: cross-backend builds, don’t leak game/Il2Cpp types in the public API, PRs →
bleeding-edge.
| Concern | Approach |
|---|---|
| Command discovery | Live index of native ScheduleOne.Console.Commands / Il2Cpp equivalent |
| Custom S1API commands | Not indexed (they never enter the native list) |
| Arg suggestions | Local IArgProvider + game registries (items, vehicles, …) |
| UI | Harmony on ConsoleUI + TMP overlay under the input bar |
| Packaging | Own MelonMod + Loader (Mono + IL2CPP DLLs) |
| Concern | Approach |
|---|---|
| Custom commands | Subclass S1API.Console.BaseConsoleCommand (CommandWord / Description / ExampleUsage / ExecuteCommand) |
| Registration | Auto-discover subclasses on Console.Awake → internal CustomConsoleRegistry |
| Execution | Harmony prefix on Console.SubmitCommand: if not in native commands dict → run managed command |
| Help UI | CommandListScreen.Start postfix adds rows (TMP) for custom commands |
| Native list | Custom commands are intentionally not added to Console.Commands (avoids subclassing Il2Cpp abstracts) |
| Public surface | BaseConsoleCommand, ConsoleHelper; registry is internal |
This is deliberate and good for S1API’s abstraction goals — but it means any autocomplete that only reads Console.Commands will miss every S1API command (MultiDelivery, etc.).
S1API already ships:
Plugins/S1APILoader*.dllMods/S1API.*.dll(Mono + IL2CPP, loader picks one)
Autocomplete today is a separate MelonMod. “Just having S1API” does not currently enable autocomplete.
Ship ConsoleUI Harmony + overlay + suggestion engine as part of the S1API MelonMod.
| Pros | Cons |
|---|---|
| True “install S1API → autocomplete works” | Large UI PR; fights “API layer, not product UX” |
| One dependency for players who already need S1API | Couples TMP/ConsoleUI deeply into S1API internals forever |
| Can see managed registry natively | Harder to iterate UX without S1API releases |
Violates spirit of “don’t leak game UI types” even if kept internal |
|
| Players who want autocomplete without S1API lose out unless feature is split again |
Fit with S1API standards: Poor as a first PR. Maintainers may reject scope.
Option B — S1API exposes metadata + arg-provider API; UI stays a separate mod (recommended foundation)
S1API gains a small public console catalog / provider API. Autocomplete (this mod, or a thin “S1API.ConsoleUX” package) consumes it.
| Pros | Cons |
|---|---|
| Aligns with S1API’s role (abstraction + discovery) | “Having S1API alone” does not enable UI until something ships the UX |
Unlocks autocomplete for all BaseConsoleCommands |
Two packages unless you also ship Option C |
| Easy to PR in phases | Soft dependency / version negotiation |
| Matches PhoneApp-style auto-discovery patterns |
Fit: Excellent for an initial PR.
Option C — Hybrid: API in S1API + optional bundled UX package (best match to the user’s “default feature” ask)
- Land Option B APIs in S1API.
- Either:
- C1: S1API release zip also includes
ConsoleAutocomplete.*.dll(same loader story as dual backends), or - C2: New MelonMod
S1API.ConsoleAutocompleteliving in the S1API repo / solution, enabled by the same loader, default-on.
- C1: S1API release zip also includes
| Pros | Cons |
|---|---|
| Matches “install S1API → autocomplete on” | Bigger release / support surface for ifBars |
| UI can still be disabled or replaced | Need clear ownership of bugs (API vs UX) |
| Autocomplete can soft-depend on S1API APIs and degrade gracefully | Versioning: UX feature vs API semver |
Fit: Best long-term product story; propose after Option B lands or as a follow-up PR series.
Register Il2Cpp/RegisterTypeInIl2Cpp shells (like CommandProbe) into the game list.
| Pros | Cons |
|---|---|
| Existing Autocomplete indexes them with zero S1API API change | Fragile on IL2CPP; S1API explicitly avoided this |
| Duplicates SubmitCommand routing | |
| Unlikely to be accepted upstream |
Fit: Not recommended for an S1API PR.
Phased approach:
-
Near-term (this mod, no S1API merge required)
- Optional reflection soft-hook into
CustomConsoleRegistryif S1API assembly is present (fragile; stopgap only). - Prefer waiting for a public API.
- Optional reflection soft-hook into
-
S1API PR #1 (API-only, high chance of merge) — Option B
- Public read-only command catalog.
- Optional arg-provider / structure metadata.
- Zero ConsoleUI code.
-
S1API PR #2 / release packaging (Option C) — discuss with ifBars first
- Bundle or sibling-ship autocomplete UX so S1API installs enable it by default.
- Keep UX code in a dedicated project under the S1API solution (or this repo as a submodule / NuGet consumed by S1API packaging).
Do not lead with a giant ConsoleUI PR into S1API.
Aligned with BaseConsoleCommand and coding standards (managed types only, XML docs, PascalCase, #if only inside Internal).
namespace S1API.Console
{
/// <summary>Snapshot of a registered console command (vanilla wrappers optional later).</summary>
public sealed class ConsoleCommandInfo
{
public string CommandWord { get; }
public string CommandDescription { get; }
public string ExampleUsage { get; }
public string? StructureHeader { get; } // optional; else tooling parses ExampleUsage
public string SourceLabel { get; } // e.g. Melon mod name / "S1API"
}
/// <summary>Public read-only view over custom (and eventually unified) commands.</summary>
public static class ConsoleCommandCatalog
{
public static IReadOnlyList<ConsoleCommandInfo> GetCustomCommands();
// Future: GetAll() merging documented built-ins via ConsoleHelper metadata
}
}Implementation: thin wrapper over existing CustomConsoleRegistry (promote listing, keep mutate paths internal).
namespace S1API.Console
{
public sealed class ConsoleArgCandidate
{
public string Value { get; init; }
public string? DisplayLabel { get; init; }
public string? SourceLabel { get; init; }
}
/// <summary>
/// Implement and expose a public parameterless constructor;
/// auto-registered similarly to BaseConsoleCommand.
/// </summary>
public abstract class BaseConsoleArgProvider
{
public abstract string CommandWord { get; }
public abstract int ArgIndex { get; } // 0 = first arg after command word
public abstract IEnumerable<ConsoleArgCandidate> GetCandidates(
IReadOnlyList<string> tokensSoFar);
}
}Mirror this mod’s IArgProvider / ArgCandidate without referencing game item types in the public signature (providers that need Registry stay in the UX mod or use S1API item wrappers if those exist).
Additive, non-breaking:
public virtual string? StructureHeader => null;
// or
public virtual IReadOnlyList<BaseConsoleArgProvider>? ArgProviders => null;Prefer separate BaseConsoleArgProvider discovery so existing commands need no changes.
ConsoleUI,TMP_InputField, overlay GameObjects- Harmony patches for Tab / caret
- Direct
ScheduleOne.*/Il2CppScheduleOne.*in public method signatures
Those remain in Internal (if ever) or in the UX assembly.
Independent of merge politics — harden this mod so an upstream handoff is cleaner:
| Area | Why |
|---|---|
| Split “engine” vs “UI” | SuggestionEngine, command index, arg providers vs SuggestionOverlay / ConsoleUI patches — engine can later call S1API catalog |
| Pluggable command sources | ICommandSource (NativeCommands, S1ApiCommands, …) instead of only CommandIndex → game list |
| Pluggable arg providers already exist | Keep managed-only candidate DTOs; move game-specific providers behind adapters |
| Soft S1API reference | Detect S1API assembly; use catalog API when version ≥ X; no hard compile dependency required for players without S1API |
| Attribution | Label S1API commands as Melon mod assembly (same as today for ProbeCommand) |
| Strip debug probes | Packaging ID probes / verbose dbg for Release packaging before upstreaming UX |
| Tests / fixtures | Pure managed unit tests for tokenize / rank / structure normalize (no game) |
| Docs | Keep player-facing CHANGELOG quality; link S1API dependency matrix |
When proposing Option C, the UX project should compile against public S1API only (not InternalsVisibleTo), same as any other mod.
From CONTRIBUTING.md / coding standards:
| Rule | How this proposal complies |
|---|---|
PR target bleeding-edge |
Open discussion issue + PR there first |
| Build Il2CppMelon + MonoMelon | API-only PR is easy; UX project needs both configs too |
| Don’t casually change GitHub Actions | Leave their CI alone unless asked |
| No leaking Il2Cpp/game types in public API | Catalog + arg DTOs are managed-only |
Internals in S1API.Internal.* |
Keep Harmony SubmitCommand / Awake patches internal; add public façade |
| XML docs on public API | Required for catalog / providers |
| Naming / folders | S1API.Console next to BaseConsoleCommand |
Process tip: Open a GitHub Issue / Trello note on ifBars’ board before a large PR: “Public ConsoleCommandCatalog + optional Console Autocomplete bundling.” Get buy-in on Option B vs C.
[Players]
MelonLoader
└─ S1API (loader + API) ← almost everyone with content mods
└─ ConsoleAutocomplete UX ← today separate; later bundled (Option C)
[Mod authors]
Reference S1API NuGet / DLL
└─ BaseConsoleCommand (+ optional BaseConsoleArgProvider)
SemVer:
- Catalog / provider API → minor bump of S1API (additive).
- Bundling UX → packaging/release notes, not necessarily API break.
- Autocomplete soft-depends:
S1API >= 3.xwith feature detection.
Thunderstore: if bundled, declare ifBars-S1API_Forked-x.y.z as dependency of the UX package, or ship both in one zip with clear Mods/Plugins layout (same as S1API’s current dual DLL pattern).
- Product scope: Is console UX in-scope for S1API, or should it stay a sister mod with a hard recommendation?
- Default-on: If bundled, can players disable autocomplete via MelonPreferences without removing S1API?
- BepInEx builds: S1API also has BepInEx configs — does autocomplete need those targets or Melon-only?
- Performance: Catalog is tiny; arg providers that scan full item registries should stay lazy / cached (lesson from this mod).
- CommandListScreen vs live console: Catalog helps both; UI work is ConsoleUI-only.
- Ownership: Who maintains overlay bugs after merge — S1API maintainers or Autocomplete authors as CODEOWNERS of a subproject?
| PR | Repo | Contents |
|---|---|---|
| 0 | Schedule_I_Autocomplete | Refactor: ICommandSource, soft S1API detection stub, engine/UI split (optional prep) |
| 1 | ifBars/S1API | ConsoleCommandCatalog.GetCustomCommands() + docs + samples |
| 2 | ifBars/S1API | BaseConsoleArgProvider auto-discovery + register/list API |
| 3 | Schedule_I_Autocomplete | Consume catalog/providers; document “works best with S1API ≥ …” |
| 4 | ifBars/S1API (discussion) | Bundle or sibling-ship UX as default in S1API release zip / loader |
- Yes, it can become a default companion to S1API, but stuffing the full ConsoleUI overlay into S1API as the first PR is the wrong shape for that codebase.
- Best path: standardize on S1API’s existing console pattern (managed commands + Harmony routing) by exposing a public catalog + arg-provider API, then either keep UX as this mod (soft-dependent) or bundle it in S1API’s release once maintainers agree (Option C).
- Critical gap today: Autocomplete only sees native
Console.Commands; S1API commands will never appear until catalog API (or fragile reflection) exists. - Standards fit: Option B is fully compatible with ifBars’ MIT project, dual Melon builds, and “no game types in public API” rule.
When ready to engage upstream: draft an issue on ifBars/S1API linking this doc and asking for preference between API-only vs API + bundled UX.