Pengu Loader Documentation

website·Indexed 31 days ago

https://pengu.lol

Developer documentation for Pengu Loader (formerly League Loader), a tool for restyling the League Client. Includes guides on creating JavaScript plugins and CSS themes, as well as the Runtime API for accessing window.Pengu, window.Settings, window.Effect, PluginFS, DataStore, and LCU Socket observation.

Tokens
13.2K
Snippets
86
Records
114
Agent score
60%

What's inside Pengu Loader

  1. Overview of DataStore persistent storage

    The DataStore namespace allows plugins to store user data on disk. The entire store is read from disk into memory before any plugins run, making read operations (get, has) synchronous and safe to call during a plugin's init phase. Writes are updated in memory immediately and committed to disk using a short debounce to optimize performance during bursts of updates.
  2. Overview of Pengu Loader for League of Legends

    Pengu Loader (formerly League Loader) is a plugin loader specifically designed for the League of Legends Client. It allows users to load JavaScript plugins as dependencies to personalize the client's appearance, add custom content, and implement new features. Because the League Client UX is an embedded Chromium web browser, JavaScript plugins integrate seamlessly and can be debugged using Chrome DevTools. Key capabilities include easier interaction with the LCU API and support for modern JavaScript features.
  3. Understand Pengu Loader's technical operation and safety

    Pengu Loader functions by loading JavaScript and CSS into the League Client's interface (which is an embedded Chromium browser), similar to how a browser extension styles a web page. It only runs inside LeagueClientUx.exe and does not interact with the game process, read/write game memory, automate gameplay, or access account credentials.
  4. Understand PluginFS availability and scoping

    The fs namespace is a capability object provided to plugins to perform filesystem operations within the plugin's own directory.

    Availability:

    • Folder Plugins: Plugins located in plugins/my-plugin/index.js or plugins/@author/my-plugin/index.js receive the fs object scoped to that folder.
    • Single-file Plugins: Plugins located at plugins/my-plugin.js do not have access to fs because they do not own a dedicated directory.
    • Top-level Plugins: Do not have this namespace.

    Security & Constraints:

    • All paths are relative to the plugin root.
    • Absolute paths, .. components, and symlinks are rejected.
    • Reads and writes are capped at 16 MB.
    • The plugin's own index.js is protected: it cannot be written to or removed.
    • fs is a capability object; passing it to third-party code grants that code full access to your plugin's folder.
    export function init({ meta, fs }) {
      if (!fs) return // top-level or single-file plugin
      await fs.write('state.json', JSON.stringify({ ok: true }))
    }
  5. Access host operating system information

    The window.os read-only object provides details about the operating system the Client is running on. This is useful for OS-specific code paths or checking minimum OS build requirements. Available since v1.2.0.
    interface OsGlobal {
      name: 'win' | 'mac'
      version: string
      build: string
    }
    console.log(window.os)
    // Example: { name: 'win', version: '10.0', build: '19045' }
    
    if (window.os.name === 'mac') {
      // macOS-only code path
    }
  6. Get file status using context.fs.stat

    Retrieve metadata about a file or directory. If the path is omitted, it stats the plugin root. Returns a FileStat object or undefined on failure.
    interface FileStat {
      fileName: string
      length: number // 0 if isDir is true
      isDir: boolean
      isFile: boolean
    }
    
    // Usage
    const stat = await context.fs.stat('a/b')
    if (stat && stat.isDir) {
      console.log("it's a directory")
    }
  7. Understand Pengu Loader safety and usage

    Pengu Loader is a third-party tool designed specifically to restyle the League Client. It does not modify or touch the game files themselves. Users are responsible for the behavior of the plugins they install and should review the official Usage Policy before downloading.
  8. Access Pengu Loader runtime information via window.Pengu

    The window.Pengu namespace object provides read-only information about the current Pengu Loader version, system environment, and user settings. It is used to detect the operating system, check for specific performance modes, and identify loaded plugins.
  9. Use local assets in a CSS theme module

    When a theme is imported as a module, you can use relative paths within the url() function to reference assets located in your plugin directory.
    /* theme.css */
    .some-div {
      background-image: url(./assets/background.png);
    }
    
    .another-div {
      background-image: url(./assets/some-image.jpg);
    }

    // File structure: your-plugin/ |__assets/ |__background.png |__some-image.jpg |__theme.css

  10. Update plugin project structure for Pengu Loader v1.0

    Since v1.0, top-level JS files in the plugins folder are no longer executed as plugin entry points. Each plugin must now reside in its own dedicated subfolder. Resources specific to a plugin should be placed in an assets folder within that plugin's directory and can be accessed via the //plugins/ domain. The global //assets/ domain is now reserved for large, common, unique resources.
    plugins/
      |__your-plugin/
        |__assets/
          |...         <- resources
        |__index.js    <- plugin entry
        |...           <- other utils
  11. Convert dynamic require() to dynamic import()

    Because ES import statements must be top-level, any require() calls previously used inside functions or conditional scopes must be replaced with the asynchronous import() operator.
    // Option 1: Using async/await
    async function load() {
      const utils = await import('./utils')
    }
    
    // Option 2: Using Promise .then()
    function load() {
      import('./utils').then((module) => {
        const utils = module.default
        // ...
      })
    }
  12. Manage local plugin assets using the module system

    Plugins should store assets in a dedicated assets/ folder within the plugin directory. While assets can be accessed via a direct path (e.g., //plugins/your-plugin/assets/background.png), it is recommended to use the module system for better reliability.
    // In index.js
    import background from './assets/background.png'
    
    // Usage
    const img = document.getElementById('some-img')
    img.src = background
    /* In theme.css (which must be imported by index.js) */
    .some-div {
      background-image: url('./assets/background.png');
    }