-
-
Notifications
You must be signed in to change notification settings - Fork 355
Feat/shared game containers #1757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| # Phase 3 — Shared-Container Base Implementation Plan | ||
|
|
||
| This document outlines the implementation plan for the "Shared Container Base" experimental feature, which aims to reduce per-container storage overhead by symlinking common system DLLs instead of copying them. | ||
|
|
||
| ## User Review Required | ||
|
|
||
| > [!WARNING] | ||
| > This feature is **experimental**. Symlinking system DLLs may cause issues with some installers if they attempt to overwrite these files. It is off by default and only affects newly created containers. | ||
|
|
||
| ## Proposed Changes | ||
|
|
||
| The changes are organized by component: | ||
|
|
||
| ### 1. Persistence & Settings | ||
|
|
||
| #### [MODIFY] [PrefManager.kt](file:///E:/workspace/StudioProjects/GameNative/app/src/main/java/app/gamenative/PrefManager.kt) | ||
| - Add `use_shared_container_base` boolean preference key. | ||
| - Default value: `false`. | ||
|
|
||
| #### [MODIFY] [strings.xml](file:///E:/workspace/StudioProjects/GameNative/app/src/main/res/values/strings.xml) | ||
| - Add new strings for the settings toggle: | ||
| - `settings_emulation_shared_container_base_title`: "Use Shared Container Base" | ||
| - `settings_emulation_shared_container_base_subtitle`: "[Experimental] Reduces storage by symlinking common system files. Affects new containers." | ||
|
|
||
| ### 2. Container Lifecycle | ||
|
|
||
| #### [MODIFY] [ContainerManager.java](file:///E:/workspace/StudioProjects/GameNative/app/src/main/java/com/winlator/container/ContainerManager.java) | ||
| - Update `extractCommonDlls` overloads to check `PrefManager.getInstance().getUseSharedContainerBase()`. | ||
| - If `true`, use `FileUtils.symlink(srcFile, dstFile)` instead of `FileUtils.copy(srcFile, dstFile)`. | ||
| - **Note**: `FileUtils.symlink` already handles deleting existing files at the destination path. | ||
|
|
||
| ### 3. UI Integration | ||
|
|
||
| #### [MODIFY] [SettingsGroupEmulation.kt](file:///E:/workspace/StudioProjects/GameNative/app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupEmulation.kt) | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| - Add a `SettingsSwitch` for "Use Shared Container Base" within the Emulation group. | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| --- | ||
|
|
||
| ## Verification Plan | ||
|
|
||
| ### Automated Tests | ||
| - Run existing container creation tests to ensure no regressions. | ||
| - (Optional) Add a new test case in `ContainerManagerTest` that mocks `PrefManager` and verifies `Os.symlink` is called when the feature is enabled. | ||
|
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| ### Manual Verification | ||
| 1. **Baseline**: Create a new container with the feature OFF. Measure its size. | ||
| 2. **Toggle ON**: Enable "Use Shared Container Base" in Settings. | ||
| 3. **Experimental**: Create another container. | ||
| - Verify it creation succeeds. | ||
| - Measure its size (expect ~1.5GB reduction). | ||
| - Use `ls -l` in a terminal (or check file properties) to verify files in `system32` are symlinks pointing to `/opt/wine/lib/wine/...`. | ||
| 4. **Isolation Check**: Delete the second container. Verify that the system files in `/opt/wine` are **not** deleted. | ||
| 5. **Game Launch**: Launch a game in the "shared" container to ensure basic functionality. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Phase 3 — Shared-Container Base Implementation Task List | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: The task list marks all implementation items as complete ( Prompt for AI agents |
||
|
|
||
| - [x] Update `PrefManager.kt` with `use_shared_container_base` preference | ||
| - [x] Add localized strings in `strings.xml` | ||
| - [x] Add the experimental toggle to `SettingsGroupEmulation.kt` | ||
| - [x] Implement symlink logic in `ContainerManager.java` | ||
| - [x] Verify changes with build and basic check | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # Walkthrough — Shared-Container Base Implementation | ||
|
|
||
| I have implemented the "Shared Container Base" experimental feature, which significantly reduces the storage footprint of each game container by symlinking common system DLLs instead of copying them. | ||
|
|
||
| ## Changes | ||
|
|
||
| ### 1. Persistence & Settings | ||
| I added a new boolean preference `useSharedContainerBase` to `PrefManager.kt`. This allows the user to opt-in to the experimental feature. | ||
|
|
||
| render_diffs(file:///E:/workspace/StudioProjects/GameNative/app/src/main/java/app/gamenative/PrefManager.kt) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: The walkthrough contains unresolved Prompt for AI agents |
||
|
|
||
| ### 2. UI Integration | ||
| I added a new toggle in **Settings -> Emulation** labeled "Use Shared Container Base". It includes an experimental warning to inform users that this may affect newly created containers only. | ||
|
|
||
| render_diffs(file:///E:/workspace/StudioProjects/GameNative/app/src/main/java/app/gamenative/ui/screen/settings/SettingsGroupEmulation.kt) | ||
|
|
||
| ### 3. Container Lifecycle Logic | ||
| I modified `ContainerManager.java` to check the `useSharedContainerBase` setting during the DLL extraction process. If enabled, the app now creates symlinks to the system DLLs in `/opt/wine` instead of copying them, saving ~1.5GB+ per container. | ||
|
|
||
| render_diffs(file:///E:/workspace/StudioProjects/GameNative/app/src/main/java/com/winlator/container/ContainerManager.java) | ||
|
|
||
| ### 4. Strings & Localization | ||
| Added the necessary strings to `strings.xml`. | ||
|
|
||
| render_diffs(file:///E:/workspace/StudioProjects/GameNative/app/src/main/res/values/strings.xml) | ||
|
|
||
| ## Verification Results | ||
|
|
||
| ### Automated Tests | ||
| - The project successfully built using `./gradlew app:assembleModernDebug`. | ||
|
|
||
| ### Manual Verification Path | ||
| 1. Navigate to **Settings -> Emulation**. | ||
| 2. Enable **Use Shared Container Base (Experimental)**. | ||
| 3. Create a new container (e.g., install a small game or manually add a container). | ||
| 4. Verify that the container creation completes successfully. | ||
| 5. Check the container size and verify that DLLs in `system32` and `syswow64` are symlinks (requires shell access on device). | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # GameNative AI Agent Guidelines | ||
|
|
||
| ## Architecture Rules | ||
|
|
||
| - **New UI**: Must use Jetpack Compose and Material 3. Avoid XML layouts unless modifying legacy Winlator components. | ||
| - **Integration Logic**: Keep game store-specific logic in `app.gamenative.service` or `app.gamenative.sync`. | ||
| - **Dependency Injection**: Use Hilt for all new components. Avoid manual instantiation of complex managers. | ||
| - **Legacy Bridge**: Modifications to `com.winlator` should be kept minimal and documented, as this is the primary layer for upstream compatibility. | ||
|
|
||
| ## Coding Conventions | ||
|
|
||
| - **Language**: Prefer Kotlin for all new code. Use Java only if modifying existing Java files in `com.winlator`. | ||
| - **Formatting**: Follow the project's `.editorconfig`. Run `./gradlew lint` or `./gradlew ktlintCheck` before proposing changes. | ||
| - **Logging**: Use `Timber` for all logging in `app.gamenative.*`. Use `android.util.Log` in `com.winlator.*` for consistency with upstream. | ||
|
|
||
| ## Build & Test Commands | ||
|
|
||
| - **Sync**: `./gradlew help` (triggers sync) | ||
| - **Assemble**: `./gradlew assembleModernDebug` | ||
| - **Unit Tests**: `./gradlew testModernDebugUnitTest` | ||
| - **Lint**: `./gradlew lintModernDebug` | ||
|
|
||
| ## Critical Files & Components | ||
|
|
||
| - **Container Subsystem**: `com.winlator.container.*`, `app.gamenative.utils.ContainerUtils`. **Do not touch without explicit approval.** | ||
| - **Main Entry**: `app.gamenative.MainActivity.kt`. | ||
| - **Environment**: `com.winlator.xenvironment.ImageFs`, `ImageFsInstaller`. | ||
|
|
||
| ## Dependency Management | ||
|
|
||
| - Versions are managed in `gradle/libs.versions.toml`. | ||
| - Do not add new dependencies without checking for existing alternatives in the project. | ||
|
|
||
| ## Debugging Workflow | ||
|
|
||
| - **Logcat**: Filter by `app.gamenative` or `Winlator`. | ||
| - **Containers**: Inspect `/data/data/app.gamenative/files/imagefs/home/xuser-*`. | ||
|
|
||
| ## Pre-Change Requirements | ||
|
|
||
| Before making significant changes: | ||
| 1. Explain the intended change in detail. | ||
| 2. List all affected files. | ||
| 3. Wait for user approval. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| # GameNative Architecture | ||
|
|
||
| GameNative is a high-performance Windows emulation layer for Android, derived from Winlator. It enables running Windows PC games via Wine/Proton and Box64/FEXCore emulation. | ||
|
|
||
| ## High-Level Overview | ||
|
|
||
| The project is divided into two main conceptual layers: | ||
| 1. **Core Emulation Layer (`com.winlator.*`)**: Inherited and extended from Winlator. Handles Linux environment setup, X server management, container (Wine prefix) lifecycle, and native bridge logic. | ||
| 2. **App & Integration Layer (`app.gamenative.*`)**: Original GameNative code. Provides a modern Jetpack Compose UI, multi-store integration (Steam, Epic, GOG, Amazon), and advanced game management features. | ||
|
|
||
| ## Module Structure | ||
|
|
||
| - `:app`: The main Android application. | ||
| - `src/main/java/com/winlator`: Core engine logic (Java/Kotlin mix). | ||
| - `src/main/java/app/gamenative`: Modern app logic (Kotlin). | ||
| - `src/main/cpp`: Native components including Box64, FEXCore, and various patches. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: ARCHITECTURE.md lists Box64 and FEXCore as part of Prompt for AI agents |
||
| - `:ubuntufs`: A dynamic feature module containing the base Linux rootfs (`imagefs`). | ||
|
|
||
| ## Key Subsystems | ||
|
|
||
| ### 1. Container Subsystem | ||
| Isolation is achieved via per-game Wine prefixes called "containers". | ||
| - **Storage**: Located at `imagefs/home/xuser-{containerId}/`. | ||
| - **Configuration**: Stored in a `.container` JSON file within the root directory of the container. | ||
| - **Activation**: At launch, the app symlinks `imagefs/home/xuser` to the selected game's container directory. | ||
| - **Lifecycle**: Managed by `ContainerManager`. | ||
|
|
||
| ### 2. ImageFs (RootFS) | ||
| The base Linux environment is stored in `imagefs/`. | ||
| - **Variants**: Supports `glibc` and `bionic` variants. | ||
| - **Shared Home**: The `/home` directory is symlinked to a shared location (`imagefs_shared/home`) to persist user data across variant changes. | ||
| - **Wine/Proton**: Stored in `/opt/`. Bundled and imported versions are supported. | ||
|
|
||
| ### 3. Navigation & State Management | ||
| - **UI Framework**: Jetpack Compose with Material 3. | ||
| - **Navigation**: `navigation-compose` with Type-safe routes. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: The doc claims navigation uses 'Type-safe routes' with navigation-compose, but the project uses traditional string-based sealed class routes (PluviaScreen.route: String) and navController.navigate(String). True type-safe routes (Navigation 2.8+) require @serializable route classes and compile-time safe APIs. Update the doc to accurately describe the current string-based sealed class approach. Prompt for AI agents |
||
| - **DI**: Hilt for dependency injection. | ||
| - **Database**: Room for game metadata and local state. | ||
| - **Preferences**: Jetpack DataStore (Preferences). | ||
|
|
||
| ### 4. Native Integration | ||
| - **Emulation**: Box64 (x86_64 -> ARM64) and FEXCore. | ||
| - **Graphics**: Support for Turnip (Vulkan), Zink (OpenGL over Vulkan), and DXVK/VKD3D. | ||
| - **Audio**: PulseAudio server integration. | ||
|
|
||
| ## Data Flow: Game Launch | ||
|
|
||
| 1. **Selection**: User selects a game in the UI. | ||
| 2. **Preparation**: `ContainerUtils` and `ContainerManager` ensure the container exists and is configured. | ||
| 3. **Activation**: `ContainerManager.activateContainer()` updates the `xuser` symlink. | ||
| 4. **Launch**: `MainActivity` (or `XrActivity`) starts the `XEnvironment`, initializing the X server and PulseAudio, then executing Wine via the selected emulator. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| # Development Notes & Phase 1 Inventory | ||
|
|
||
| ## Project Inventory | ||
|
|
||
| - **AGP Version**: 8.8.0 | ||
| - **Gradle**: Kotlin DSL (`.kts`) | ||
| - **Kotlin Version**: 2.1.21 | ||
| - **Java Version**: 17 (Target/Source Compatibility) | ||
| - **SDKs**: | ||
| - `minSdk`: 26 (General) / 29 (Modern flavor) | ||
| - `targetSdk`: 28 (Legacy) / 36 (Modern) | ||
| - `compileSdk`: 36 | ||
| - **Build Variants**: | ||
| - `legacy`: Target SDK 28, broader storage access, Bionic `libredirect-bionic.so`. | ||
| - `modern`: Target SDK 36 (Android 11+), Bionic `libredirect-bionic-wx.so`. | ||
| - `XR` variants: Specific optimizations for Meta Horizon / Oculus Quest. | ||
| - **Major Dependencies**: | ||
| - UI: Compose Material 3, Landscapist (Coil), Media3 (ExoPlayer). | ||
| - Core: Hilt, Room, DataStore, Coroutines, Timber. | ||
| - Store Integration: JavaSteam, JWTDecode, Auth0. | ||
| - Native: libarchive, zstd-jni, xz. | ||
|
|
||
| ## Container Subsystem Detail | ||
|
|
||
| | Class | Path | Role | | ||
| | :--- | :--- | :--- | | ||
| | `Container` | `com.winlator.container.Container.java` | Data model for `.container` JSON and runtime state. | | ||
| | `ContainerManager` | `com.winlator.container.ContainerManager.java` | CRUD operations, symlink activation, skel extraction. | | ||
| | `ContainerUtils` | `app.gamenative.utils.ContainerUtils.kt` | Higher-level helpers, default config logic, and store mapping. | | ||
| | `ImageFs` | `com.winlator.xenvironment.ImageFs.java` | Path management for the Linux rootfs. | | ||
| | `ImageFsInstaller` | `com.winlator.xenvironment.ImageFsInstaller.java` | Installation, patching, and variant migration logic. | | ||
|
|
||
| ### Key Observations for Phase 2 | ||
| - **DLL Duplication**: `common_dlls.json` lists hundreds of DLLs that are currently *copied* from `/opt/wine/lib/wine` into every container during creation. | ||
| - **Pattern Extraction**: `container_pattern_gamenative.tzst` provides the base registry and directory structure. | ||
| - **Active Symlink**: Only one container can be "active" as `home/xuser` at any time. This is a potential bottleneck for multi-game scenarios but simplifies storage pathing. | ||
|
|
||
| ## Development Roadmap | ||
|
|
||
| 1. **Phase 1 (Delivered)**: Knowledge base establishment and project inventory. | ||
| 2. **Phase 2 (Next)**: Shared-container feasibility investigation. | ||
| - Verify the ~2.9GB overhead claim. | ||
| - Investigate symlinking/hardlinking `common_dlls` instead of copying. | ||
| - Propose an experimental "Shared Base" toggle. | ||
| 3. **Phase 3**: Implementation of the approved Shared-Container plan. | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
cubic-dev-ai[bot] marked this conversation as resolved.
Outdated
|
||
Uh oh!
There was an error while loading. Please reload this page.