Appearance
Incremental migration from the reference games
Game Master and Sakura Serenade are read-only references for this development goal. The following steps are guidance for a future project-owned migration branch. They do not authorize modifying either reference checkout. Preserve existing Git changes and gameplay behavior; introduce one UI flow at a time with an immediate rollback path.
Keep game design and gameplay in the game
Game Master's layouts, styling, frames, artwork, and animations remain exclusive to Game Master. A game-owned widget may keep that design while using InterfaceForge; it must not be moved into the distributable plugin or standalone examples. Audit every hard/soft asset dependency before any redistribution. Mixed AshenForge/SoftMage headers and purchased packs in the references are not ownership-transfer evidence.
The new Outpost/Emberwatch examples are original designs with separate small providers. Inventory storage, equipment authority, combat rules, quests, production and selection remain owned by the game. The UI consumes data and requests actions; replacing a widget must not silently replace those systems.
Game Master: move ownership, retain CommonUI
The inspected UGMUI_UserInterfaceSubsystem is GameInstance-scoped and holds CreatedPrimaryLayout after RegisterCreatedPrimaryLayoutWidget. UGMUI_PrimaryLayout uses CommonUI composition. InterfaceForge instead provides IFLocalPlayerSubsystem → Create Root → Register Layer / Push Screen for each owning local player.
- In a separate migration branch, create a project-owned IFRootLayout Blueprint and register HUD/Menu/Modal stacks. Keep the existing game layout as a separate fallback.
- From the local PlayerController, get IFLocalPlayerSubsystem and Create Root. Route only the chosen pilot flow through it. Do not keep two active CommonUI roots competing for the same player's navigation/modal focus.
- Create a project-owned IFScreen Blueprint for one menu/HUD panel. Set its Initial Focus, call parent Initialize Screen, and retain game-specific art/layout in that project asset.
- Add a provider implementing IFDataSource. Get UI Model returns stable observable objects; Request UI Action forwards requests to the current gameplay controller/subsystem after its existing validation. Publish changed fields with Notify Data Changed rather than recreating models or polling the whole entity population.
- Replace repeated widget-local handling of FGMUI_InputPresentationState with IFInputPresentationSubsystem → On Input Presentation Changed. Keep engine CommonInput controller data and project glyph art. Preserve meaningful pointer/keyboard distinction, focus restoration and cursor policy; test the pilot while a modal is open and after returning from a screen.
- Keep current game save/audio/graphics policies. Route staged UI scalar preferences through IFSettingsSubsystem only where intentionally migrated. EnhancedInputUserSettings still owns remaps; CommonUI Accept/Back rows are separate.
The standalone examples opt into CommonGameViewportClient, IFNavigationInputData and Trigger Click. Evaluate the reference game's existing equivalents before changing project settings. A source-level compatibility cast is not a reason to duplicate the frontend controller architecture inside the plugin.
Sakura: adapt controller outputs, preserve the tint
The inspected SSWidgetControllerBase binds to ASSPlayerController, ASSPlayerState, USSAbilitySystemComponent and USSAttributeSet, with initial broadcasts followed by updates. Keep those gameplay bindings inside Sakura's provider. Translate their output to stable IFPresentationData or your own UObject models, then drive IFEntry/IFScreen widgets through public lifecycle events.
For an action entry: Initialize Entry → assign the game Action Source; On Entry Refreshed updates label, availability, remaining fraction and countdown. On Entry Released clears the previous source/subscriptions. Request UI Action remains a request to Sakura's existing ability system. The UI must not grant an ability or decide server authority.
The requested cooldown is a center-origin angular tint over the icon, not a perimeter tube. The independently authored InterfaceForge Center Tint consumes normalized remaining fraction and configurable opacity/tint/direction. See center-tint controls, original behavior/provenance, and the saved RPG action recipe. Preserve the game's existing timing and hide-on-ready behavior when adapting it. Keep third-party icon/frame/art dependencies in Sakura; use original or project-owned art in any distributable example.
Sakura has both SSUI and main-module UI/settings code, including SSUISubsystem. Choose one migrated owner for each settings/remap transaction and retire duplicate bindings only after the pilot passes. Do not reorganize unrelated systems to make the new UI fit.
Optional MassForge path
MassForge0.2 uses FMFEntityHandle with Index + SerialNumber and explicit world context. Use Get Mass Forge Entity from Actor for represented actors; actorless entities use their originating world-scoped handle. A bare index is unsafe. GetAttribute can report Mass Is Processing, missing schema/fragment or stale entity; preserve a pending reading rather than treating busy as destroyed.
The separate InterfaceForgeMass integration is being implemented against those actual APIs. It does not become a dependency of InterfaceForge or the default examples. Its presentation source must observe only selected/visible handles, coalesce native attribute events, release stale entities and forward game actions to project-owned handlers. See RELEASE_ACCEPTANCE.md for its current unverified gates; installation/runtime claims await actual adapter evidence.
Prove the pilot before expanding
Exercise main/settings/HUD/pause/return, Apply/Cancel/defaults/failure, current save compatibility, genuine gameplay responses, screen cleanup, list recycling, and controller/pointer/keyboard transitions. Compare behavior before/after in the game branch. Physical controller testing is deferred in this environment and must not be inferred from software events. Keep an explicit switch back to the original flow until the game-owned pilot is accepted.