Game Development 16 min read

Design and Automation of OneSDK and Packaging Tool for Global Game Distribution

The article describes how Bilibili created OneSDK and a macOS packaging tool that automatically selects and inserts the appropriate regional game SDKs, unifying APIs, eliminating manual configuration, and cutting integration effort by roughly 60% through Ruby‑based project manipulation and a Flutter UI.

Bilibili Tech
Bilibili Tech
Bilibili Tech
Design and Automation of OneSDK and Packaging Tool for Global Game Distribution

The article introduces the Bilibili Game SDK, a core component of the game technology platform that provides account, payment, compliance, social, and marketing capabilities. It explains how the SDK simplifies the implementation of underlying business functions, reduces development effort, and helps game teams focus on content creation while ensuring security and compliance.

To meet regional market strategies and regulatory requirements, Bilibili adopts differentiated publishing strategies. Games are packaged by region and entity, forming a "publishing plan". The Game SDK must adapt to these plans, leading to the proliferation of multiple SDKs for overseas releases.

The author sets two goals: (1) a single integration point that automatically adapts to global regions, and (2) a configuration‑free experience where developers do not need to manually set SDK parameters.

Two solution directions are discussed:

Refactor and merge existing SDKs – not feasible due to regional compliance and business differences.

Create an aggregation layer (OneSDK) that unifies all SDK APIs. OneSDK acts as a bridge: the game calls OneSDK, which selects the appropriate underlying SDK via an AdapterProtocol. Each underlying SDK has its own Adapter that handles parameter conversion and invokes the actual game logic.

OneSDK provides a unified API for common capabilities such as account, payment, customer service, and advertising attribution. The integration workflow becomes: developers integrate only OneSDK, while a packaging tool handles the actual insertion and configuration of the underlying SDKs.

The packaging tool is a macOS application built with Flutter for the UI and Ruby scripts for Xcode project manipulation. Its responsibilities include:

Authenticating the user and retrieving the publishing plan.

Automating the removal of old SDK files and insertion of new ones.

Modifying Info.plist to add required parameters.

Updating build settings and linking required system libraries.

Key technical components:

Project.pbxproj manipulation

The tool uses the xcodeproj Ruby gem to parse and edit the project.pbxproj file, which stores all Xcode project configurations. Example of a simplified project.pbxproj structure:

// !$*UTF8*$!
{
    archiveVersion = 1;
    classes = {};
    objectVersion = 46;
    objects = {
        ...
    };
    rootObject = E6A557831C22979700A81AD5 /* Project object */;
}

Ruby script for deleting old SDK files

def delete_group(group)
    group.files.each do |file|
      if file.real_path.to_s.end_with?('.m', '.mm', '.cpp', '.h', '.swift')
        @code_target.source_build_phase.remove_file_reference(file)
        delete_path(file.real_path)
        file.remove_from_project
      elsif file.real_path.to_s.end_with?('.a') || file.real_path.to_s.end_with?('.framework')
        @code_target.frameworks_build_phases.remove_file_reference(file)
        delete_path(file.real_path)
        file.remove_from_project
      elsif file.real_path.to_s.end_with?('.plist', '.bundle')
        @main_target.resources_build_phase.remove_file_reference(file)
        delete_path(file.real_path)
        file.remove_from_project
      end
    end
    group.version_groups.each do |child|
      if child.real_path.to_s.end_with?('.xcdatamodeld')
        @main_target.resources_build_phase.remove_file_reference(child)
        delete_path(child.real_path)
        child.remove_from_project
      else
        delete_group(child, delete_files)
      end
    end
    group.groups.each do |child|
      delete_group(child)
    end
end

Plist modification for permission strings

# Add permission description strings
def add_app_permissions(target_name, permissions)
    return if permissions.nil?
    plist_full_path = info_plist_path(target_name)
    info = Plist.parse_xml(plist_full_path)
    permissions.each do |key, value|
      puts 'key : ', key, 'value:', value
      info[key] = value
    end
    Plist::Emit.save_plist(info, plist_full_path)
end

The packaging workflow proceeds as follows: after authentication, the tool fetches the publishing plan, then uses the scripts above to delete old SDK artifacts, import the new SDK, edit Info.plist , adjust build settings, and add required system libraries. The UI, built with Flutter, guides developers through three simple steps to complete the packaging.

Future plans include integrating compliance checks, SDK self‑diagnostics, and additional automation features to further reduce integration time. The current OneSDK reduces the number of SDKs a game needs to integrate from up to two to a single OneSDK, and the packaging tool is expected to cut integration effort by about 60%.

iOSAndroidAutomationGame developmentSDK integrationPackaging ToolXcodeproj
Bilibili Tech
Written by

Bilibili Tech

Provides introductions and tutorials on Bilibili-related technologies.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.