Skip to content

Release 1.0.0 - #11

Open
CoderGamester wants to merge 19 commits into
masterfrom
develop
Open

Release 1.0.0#11
CoderGamester wants to merge 19 commits into
masterfrom
develop

Conversation

@CoderGamester

Copy link
Copy Markdown
Owner

Added

  • Initial release of consolidated Mobile Services package.
  • Native UI: Alerts, action sheets, and toasts for iOS/Android, plus OS review request and a share sheet (text / URL / image).
  • Notifications: Local notification scheduling and management (channels, queueing, fluent Schedule().In(...).Title(...).Body(...).Channel(...).Send() builder).
  • Gestures: Advanced swipe detection with velocity and consistency tracking.
  • iOS Audio Session: Override the iOS silent switch so audio keeps playing.
  • Haptics: Zero-dependency cross-platform haptic feedback with 9 presets, custom intensity, and time-bounded looping.
  • Device: Umbrella facade over SafeArea, ScreenWake, Battery (with LPM awareness), AudioSession, Permissions, Att, and DeepLink sub-services.
  • Permissions: Unified iOS+Android runtime permissions (Camera, Microphone, Location, Photo Library, Notifications) with Task-based async and a multi-permission RequestAsync(params AppPermission[]) overload.
  • App Tracking Transparency: iOS 14.5+ ATTrackingManager bridge with zero dependency on com.unity.ads.ios-support.
  • Deep Links: Application.deepLinkActivated wrapper with cold-start link queueing for the first subscriber.
  • Deep Link Router: Path-pattern routing over IDeepLinkService with captured params (/promo/:id).
  • Mobile Service umbrella: IMobileService — single DI registration aggregating NativeUi / Notifications / Haptics / Device.
  • Native UI instance interface: INativeUiService + NativeUiServiceInstance forwarder for mockable consumer code.
  • Device Simulator Plugin: A DeviceSimulatorPlugin embedded in Unity's Device Simulator window that drives platform-shaped native-UI mocks into the simulated phone screen (edit + play), with live diagnostics and a per-preset haptic envelope graph.
  • Mobile Services Config asset: Editor ScriptableObject (open via Tools > GameLovers > Mobile Services > Select Mobile Services Config) for per-permission localized usage descriptions, capability toggles, Android manifest opt-ins, and the Play In-App Review Gradle auto-injection.
  • Build Postprocessor: Auto-injects iOS Info.plist usage descriptions (+ per-locale <locale>.lproj/InfoPlist.strings for device-language localization), entitlements, Android manifest entries, and the Play In-App Review Gradle dependency; fail-fast validation lists every missing key.
  • Samples: Four code-only samples — MobileServicesPlayground, HapticsPalette, NotificationsScheduler, DeepLinkRouter.
  • Docs: Per-subsystem deep-dive references under docs/ plus editor-tooling guides for the Device Simulator panel and build pipeline.

Changed

  • Refactored all namespaces to GameLovers.MobileServices.*.
  • Updated assembly definition to GameLovers.MobileServices.
  • Updated dependencies to target Unity 6 (6000.0+).

Removed

  • Removed legacy tap detection — use Unity Input System's TapInteraction.
  • Removed gamepad input management — out of scope for mobile services; configure it via the Input System directly.

Fixed

  • Runtime/GameLovers.MobileServices.asmdef was the only asmdef in the repo missing the noEngineReferences key — added (false, matching every other asmdef in the package family).

Migration

This package consolidates three previously separate packages:

  • com.gamelovers.nativeui (v0.2.5) -> GameLovers.MobileServices.NativeUi
  • com.gamelovers.notificationservice (v0.1.7) -> GameLovers.MobileServices.Notifications
  • com.gamelovers.inputextensions (v0.1.0-preview.4, swipe detection only) -> GameLovers.MobileServices.Gestures
  • AlertButtonStyle.Positive -> AlertButtonStyle.Destructive; AlertButtonStyle.Negative -> AlertButtonStyle.Cancel. Underlying iOS/Android platform mapping is unchanged; pure rename for iOS-native vocabulary.

CoderGamester and others added 19 commits January 14, 2026 00:19
feat(gestures): add swipe and tap detection using Input System
refactor(native-ui): migrate to unified namespace and assembly
chore(mobile-services): consolidate packages and update to Unity 6
docs(mobile-services): update documentation and add AGENTS.md
…ct state

docs: add MIT LICENSE disclaimer to this project
feat(gestures): add TapInput struct for tap detection
docs(gestures): update agent guide for new gesture architecture
chore(gestures): remove obsolete input abstraction files
- Add CLAUDE.md + .meta at package root; thin @AGENTS.md import wrapper
- AGENTS.md: add Companion-files blockquote
- README.md: remove obsolete PointerInputManager / Controls / "Input System
  Integration" marketing (source uses EnhancedTouch only); document Tap
  gestures alongside Swipe (TapInput struct, Tapped event); trim to Option B
  shape (470 -> 210 lines); add Related docs footer

Made-with: Cursor
- Add IDeviceService umbrella facade with 8 sub-services: SafeArea,
  ScreenWake, Battery (with iOS/Android low-power-mode awareness),
  Connectivity, IosAudioSession, Permissions (unified iOS+Android,
  Task-based async), App Tracking Transparency (zero ads-ios-support
  dep), Deep Link (with cold-start link queueing). One shared internal
  MonoBehaviour host (DeviceServicesHost) for all event-driven children.

- Add IHapticsService with 9 cross-platform presets, custom intensity,
  and time-bounded looping. iOS UI*FeedbackGenerator + Android
  VibrationEffect bridges, no third-party plugin dependency.

- Add NativeUiService.RequestReview() (iOS SKStoreReviewController +
  Android Play Core In-App Review) and NativeUiService.Share() (iOS
  UIActivityViewController + Android Intent.ACTION_SEND).

- Add 5 iOS native bridges (Att.m, Battery.m, Haptics.m,
  iOSAudioSession.m, Permissions.m) under Plugins/iOS/.

- Add Runtime/AssemblyInfo.cs granting InternalsVisibleTo to both test
  assemblies for black-box-internal access.

- Bootstrap NUnit test suite: 28 fixtures, 106 active tests
  (75 EditMode + 31 PlayMode), all green. Codify black-box-only testing
  policy in a new Tests/AGENTS.md (fourth per-package tests guide in
  the repo, after services/uiservice/gamedata).

- Rewrite README/AGENTS/CHANGELOG to document the v1.0.0 surface and
  gotchas.

Co-authored-by: Cursor <cursoragent@cursor.com>
Adds two new rendering surfaces feeding the existing MobileSimulatorState
broker so the truth-mirror mocks can paint right inside Unity's Game /
Simulator view next to the simulated phone screen:

- `MobileSimulatorRuntimeOverlay` (editor-only `[InitializeOnLoad]` bootstrap):
  spawns a `[EditorOnly]` `DontDestroyOnLoad` GameObject with a programmatic
  `PanelSettings` (`sortingOrder = short.MaxValue`, `ConstantPixelSize`,
  `clearColor = false`) carrying a `UIDocument` on `EnteredPlayMode`, tears
  down instantly on `ExitingPlayMode`. Opt-in via the new
  `MobileServicesSettings.EnableRuntimeSimulatorOverlay` toggle (default OFF,
  surfaced under a new "Editor tooling" section in Project Settings). Root
  is `pickingMode = Ignore` + `Color.clear` so an empty stage is transparent
  to clicks; active mock scrims re-absorb input for modal behaviour.

- `MobileServicesDeviceSimulatorPlugin`
  (`UnityEditor.DeviceSimulation.DeviceSimulatorPlugin` subclass): embeds a
  slim Control Panel inside Unity's Device Simulator window. Sections per
  subsystem (Native UI / Notifications / Device state / Permissions / ATT /
  Deep Links) with a top-row "Open full Explorer →" button. Auto-syncs
  `MobileSimulatorState.Platform` from `Application.platform` on a 500 ms
  `schedule.Execute(...).Every(...)` poll (chosen over
  `DeviceSimulator.deviceChanged` due to inconsistently-documented delegate
  signature across Unity 6 minor versions). Flips a new
  `MobileSimulatorState.IsActivePluginConnected` flag while alive; the
  Explorer's `Render as: iOS | Android` dropdown subscribes to
  `PluginConnectedChanged` and greys out (+ tooltips) while the plugin
  owns the platform skin — handoff is bidirectional and symmetric.

Editor-tooling tests retired: deleted the
`GameLovers.MobileServices.Editor.Tests` asmdef and its 5 test classes
(`EditorPlatformSimulatorTest`, `MobileServicesBuildPostprocessorTest`,
`MobileServicesExplorerWindowTest`, `MobileServicesSettingsTest`,
`MobileSimulatorWindowTest`) plus the `Editor/AssemblyInfo.cs` bridge and
the matching `InternalsVisibleTo("GameLovers.MobileServices.Editor.Tests")`
grant on `Runtime/AssemblyInfo.cs`. Editor tooling is now validated
manually only — codified in `Tests/AGENTS.md` §1 (new "Editor tooling (NOT
tested)" group), §9 (new coverage-gap entry), §11 (new update trigger), and
parent `AGENTS.md` §3 (Tests bullet rewritten). Aligns the package with
what `Tests/AGENTS.md` §10's layout table already implied — `EditMode/Editor/`
was never documented.

Docs: `docs/explorer.md` restructured from "Mobile Simulator Window
(truth-mirror)" into a "Three rendering surfaces" table + per-surface
subsections; stale device-frame line dropped; recommended workflow rewritten
around the Device Simulator + plugin + opt-in overlay; "When to use which"
table extended with a plugin row.

`AGENTS.md`: §2 Editor block describes all three rendering surfaces +
`EnableRuntimeSimulatorOverlay`; §3 Layout convention adds
`Editor/Explorer/DeviceSimulatorPanel/`; §3 `InternalsVisibleTo` paragraph
trimmed; §4 new gotcha entry for the runtime overlay's Play-mode-only,
Editor-asmdef-owned lifecycle; §8 update policy expanded.

`CHANGELOG.md`: folded into the existing `## [1.0.0]` section
(pre-publication versioning rule — no `package.json` version bump) — 2
new `### Added` bullets (Runtime Simulator Overlay, Device Simulator Plugin)
+ new `### Removed` subsection.

Tested: EditMode 790 passed / 0 failed / 1 inconclusive (the documented
`IsOutdatedVersion_DirectInvocation` host-version-parser brittleness);
PlayMode 263 passed / 0 failed. Clean.

Bundled alongside the in-flight v1.0.0 polish work (Phase A-E DX overhaul,
unreleased) that landed in the working tree in a prior session.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replaces the previous "single broker + bidirectional authority handoff"
design (`MobileSimulatorState.IsActivePluginConnected` /
`PluginConnectedChanged` greying out the Explorer dropdown when the
Device Simulator plugin attaches) with per-target routing — resolves
both "Explorer dropdown is greyed when the plugin is alive" and "plugin
clicks paint into the standalone Mobile Simulator window" with one
mechanism. Neither symptom can recur because the surfaces no longer
share state.

Broker (`MobileSimulatorState.cs`):
- New `[Flags] enum SimulatorTarget { None, StandaloneWindow,
  RuntimeOverlay, All }` carried by every `Push*`, default `All` so
  existing call sites keep broadcast semantics unchanged.
- `Platform` / `PlatformChanged` split into per-surface
  `WindowPlatform` (driven by Explorer dropdown) + `OverlayPlatform`
  (auto-synced by Device Simulator plugin from `Application.platform`),
  each persisted to its own `EditorPrefs` key.
- Every `*Requested` event signature widened to
  `Action<SimulatorTarget, TSpec>`. `IsActivePluginConnected` /
  `PluginConnectedChanged` removed entirely.

Renderers:
- `MobileSimulatorWindow` subscribes to `WindowPlatformChanged` + filters
  every payload event on `SimulatorTarget.StandaloneWindow`.
- `MobileSimulatorRuntimeOverlay` subscribes to `OverlayPlatformChanged`
  + filters on `SimulatorTarget.RuntimeOverlay`.

Producers:
- `MobileServicesExplorerWindow`: dropdown writes `WindowPlatform`,
  greying logic gone, dropdown stays interactive forever. Inline italic
  scope-hint label + tooltip ("Controls the Mobile Simulator window
  only.") with new `.explorer-header-hint` USS rule.
- `MobileServicesDeviceSimulatorPlugin`: every push passes
  `SimulatorTarget.RuntimeOverlay` (constant `OverlayOnly`), including
  its `Dismiss all mocks` button (was `EditorPlatformSimulator.
  DismissAllOverlays()` — broadcast). `SyncPlatformFromHost` writes
  `OverlayPlatform` only.
- `EditorPlatformSimulator` untouched — programmatic API stays
  broadcast-by-default for tests / scripted automation.

UX polish (4 items bundled):
- Plugin: new auto-hiding `msp-overlay-hint` amber banner inside the
  Control Panel surfaces the runtime-overlay precondition
  (`EnableRuntimeSimulatorOverlay = true` AND play mode) with a
  one-click `Open Project Settings →` jump button. Same 500 ms poll
  that re-syncs the platform also refreshes the banner so it
  auto-hides the moment both preconditions are satisfied. Without it,
  the overlay-scoped routing made it look like the buttons did
  nothing in edit mode / when the setting was OFF.
- `NativeUiTab`: new `MakePrimaryButtonRow(params Button[])` helper
  wrapping primary buttons so they shrink-wrap to natural width
  (matching the Alerts pair) — applied to Toast / Review / Share +
  the Alert pair refactored through it for consistency.
- `NativeUiTab`: Toast `Long duration` toggle text now interpolates
  `(3.5s vs 2.0s)` from new `ToastShortSeconds` / `ToastLongSeconds`
  constants and carries a tooltip mapping to Android's
  `Toast.LENGTH_SHORT/LONG` (iOS fakes the toast and reuses the same
  timings for editor preview parity).
- `NativeUiTab`: `Show Action Sheet` button greys out reactively when
  `WindowPlatform == Android` with an OS-contract tooltip explaining
  Android has no native action-sheet idiom (both shapes collapse to
  the same Material 3 dialog on a real device). Subscribes to
  `WindowPlatformChanged` and unsubscribes via
  `RegisterCallback<DetachFromPanelEvent>`.

Docs:
- `AGENTS.md` §2: Explorer dropdown + simulator-broker paragraphs
  rewritten for the per-surface scope ("two renderer surfaces, one
  broker" + per-target routing); plugin paragraph "scoped to
  RuntimeOverlay" + new precondition-banner sentence.
- `docs/explorer.md`: Explorer intro + "Three rendering surfaces" +
  Device Simulator plugin section + "Acknowledged overlap" platform-
  toggle row all rewritten for the per-target model.
- `CHANGELOG.md`: folded into existing `## [1.0.0]` section per
  pre-publication versioning rule (verified `git tag --list` shows
  no v1.0.0 tag yet) — terse user-facing bullets only.

Editor tooling validated manually only per `Tests/AGENTS.md` §1 — no
automated tests touched.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ervice

Delete the Mobile Services Explorer window, the standalone Simulator
window, all Explorer tabs + base, and the ConnectivityService (+interface
and its test) as part of consolidating editor tooling onto the Device
Simulator plugin.
… Simulator plugin

Make the Device Simulator plugin the single editor surface and the
in-Game overlay the single canvas (edit + play mode). Collapse the
simulator broker to one Platform skin, redesign the notification heads-up
mock + add a Painter2D intensity-over-time haptics curve, and reduce the
panel to mock previews + state-setting controls (Permissions/ATT state
dropdowns, play-mode gating with per-section banners). Add runtime-settable
INotificationService.Mode and drop ConnectivityService from the IDeviceService
umbrella. Update tests, samples, and docs to match.

Co-authored-by: Cursor <cursoragent@cursor.com>
…panel

Add an "Editor Simulator" header toggle (MobileSimulatorState.Enabled,
persisted to EditorPrefs) that enables/disables every panel section as a
group and shows/hides the in-Game-view [EDITOR SIMULATOR] banner; turning
it off clears any visible mock.

Replace the global "Dismiss all mocks" button with per-section dismiss
buttons: "Dismiss all UIs" in Native UI and "Dismiss Banner" in
Notifications.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ication service surface

Adds 10 black-box/gray-box tests filling Editor-runnable coverage gaps found
by the tests audit (no P0 gaps; all platform/native paths remain documented
manual-only Skips per Tests/AGENTS.md §9):

- EditMode: HapticsService default ctor (Editor backend selection) and
  NotificationBuilder Subtitle/Id/SmallIcon/LargeIcon fluent setters.
- PlayMode: MobileService/DeviceService default-ctor child wiring (new files),
  BatteryService/SafeAreaService default ctors, and MobileNotificationService
  Mode round-trip, empty PendingNotifications, and the two delivery/expiry
  events not firing on Editor schedule.

All 165 tests pass (128 EditMode + 37 PlayMode).

Co-authored-by: Cursor <cursoragent@cursor.com>
The Device Simulator Permissions/ATT controls were instant state-setters;
they now reproduce the on-device flow: the first runtime RequestAsync() /
RequestAuthorizationAsync() on a NotDetermined entry shows the native-style
prompt in the in-Game-view overlay and resolves the Task on answer, then the
decision is cached (EditorPrefs) so repeat requests never re-prompt. The
dropdowns are the Settings surface; reset re-arms the prompt.

- Add editor-only EditorRequestAsyncOverride hooks to PermissionsService and
  AttService (precedence over the sync override; no-override default unchanged).
- Add EditorPrefs-backed NotDetermined decision store + Engage/Disengage and
  prompt-once-then-cache request handlers (usage text from MobileServicesSettings)
  in EditorPlatformSimulator; ATT prompts under the iOS skin only.
- Panel: dropdowns write the store (ungated), NotDetermined reset buttons, and a
  play-mode Allow/Deny fallback for resolving a pending prompt.
- Surface Permissions/ATT guidance in a highlighted banner; lift user-facing
  panel copy into constants.
- Update AGENTS.md, docs/explorer.md, CHANGELOG (Unreleased).
…cesConfig

Native UI / review:
- RequestReview() stays OS-native (iOS SKStoreReviewController, Android Play
  In-App Review); fire-and-forget with request/launch logging and a
  warning/error when the Play flow cannot run (no store-URL fallback).
- Device Simulator renders a faithful per-platform review mock (iOS centered
  star sheet / Android Play bottom sheet), shown only when game code calls
  RequestReview() via the EditorRequestReviewOverride hook (no panel trigger).
- Auto-inject the Play In-App Review Gradle dependency via
  IPostGenerateGradleAndroidProject (default on, conflict-safe, editable
  coordinate) so RequestReview() works zero-config on Android.
- Prefix iOS exports _GameLoversAlertMessage / _GameLoversToastMessage to avoid
  duplicate-symbol linker collisions.

Config refactor:
- Replace the MobileServicesSettings ScriptableSingleton with an editor-only
  MobileServicesConfig ScriptableObject (Instance locator + custom Inspector +
  "Tools > GameLovers > Mobile Services > Select Mobile Services Config").
- Emit per-locale iOS usage descriptions as <locale>.lproj/InfoPlist.strings +
  CFBundleLocalizations for true device-language localization.
- Trim over-engineering: drop BackgroundAudio (Unity Player Settings owns it),
  placeholder soft-mode (validation is now fail-fast), BuildCallbackOrder,
  EnableRuntimeSimulatorOverlay, and ScanPopulatedCapabilities; rename
  DisableBuildPostProcessing -> ManageNativeBuildManually.

Docs:
- Fix stale IMobileService comments (remote notifications / connectivity).
- Rewrite the 1.0.0 CHANGELOG (Unreleased) and update AGENTS / README / docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ty 6 API updates

SerializableNotification uses explicit has-value flags for nullable fields so
background-rescheduled notifications keep their delivery time. SafeAreaContainer
migrates to [UxmlElement]; simulator uses FindAnyObjectByType.

Co-authored-by: Cursor <cursoragent@cursor.com>
Folds into the existing CHANGELOG [1.0.0] section -- 1.0.0 is
unreleased (max tag 0.2.5). No package.json version bump.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@CoderGamester CoderGamester self-assigned this Jul 29, 2026
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