# HoshinoBot Configuration System: How to Enable and Configure Modules

> Learn to configure HoshinoBot modules using its Python-based system. Rename config_example to config, define network settings, and customize plugins with Python or JSON files.

- Repository: [ice9coffee/hoshinobot](https://github.com/ice9coffee/hoshinobot)
- Tags: how-to-guide
- Published: 2026-03-03

---

**HoshinoBot uses a Python-based configuration system where you rename `config_example` to `config`, edit [`__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/__bot__.py) to define network settings and the `MODULES_ON` set, and optionally create per-module Python or JSON files to customize individual plugin behavior.**

The HoshinoBot configuration system is a pure-Python architecture built on top of the nonebot framework that manages global settings and selective module loading. Located in the `ice9coffee/hoshinobot` repository, this system relies on a centralized config package located at `hoshino/config` (renamed from `config_example`) to control everything from network ports to which plugins are active at runtime.

## How the Configuration System Works

The bootstrap process begins in [`hoshino/__init__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/__init__.py), where the `hoshino.init()` function loads the global configuration package and registers enabled modules as nonebot plugins.

When you first deploy the bot, you must rename the `hoshino/config_example` directory to `hoshino/config`. This allows Python to resolve `import hoshino.config` during startup. The config package’s own [`__init__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/__init__.py) validates constants like `RES_DIR`, ensures required directories exist, and imports per-module configurations for every entry listed in `MODULES_ON`.

According to the source code in [`hoshino/__init__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/__init__.py) (lines 52-70), the startup sequence follows these steps:

1. **Load global config** – `nonebot.init(config)` receives the imported `hoshino.config` package
2. **Validate environment** – The config package expands resource paths and creates `~/.hoshino` for user data
3. **Import module configs** – The system iterates over `config.MODULES_ON` and runs `importlib.import_module('hoshino.config.' + module)`
4. **Register plugins** – `nonebot.load_plugins()` loads each module under `hoshino/modules/<module>/` as an active plugin

## Global Configuration File ([`__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/__bot__.py))

The file [`hoshino/config_example/__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/config_example/__bot__.py) serves as the template for your global settings. After renaming the folder, edit this file to define network parameters, permission lists, and the active module set.

Key configuration variables include:

- **PORT** and **HOST** – Define the listening address (use `0.0.0.0` for public access, though `127.0.0.1` is safer for local testing)
- **SUPERUSERS** – A list of QQ numbers with administrative privileges
- **BLACK_LIST** and **WHITE_LIST** – Optional ban and allow lists for user IDs
- **COMMAND_START** – Prefix characters for bot commands (empty string `''` matches any message)
- **RES_PROTOCOL** and **RES_DIR** – Control how static resources (images, audio) are served (`file`, `http`, or `base64`)
- **MODULES_ON** – A Python set containing the folder names of modules to load at startup

```python

# hoshino/config/__bot__.py

PORT = 8080
HOST = '127.0.0.1'

SUPERUSERS = [10000]
BLACK_LIST = []
COMMAND_START = {''}

RES_PROTOCOL = 'file'
RES_DIR = r'./res/'

MODULES_ON = {
    'botmanage',
    'dice',
    'groupmaster',
    'pcrclanbattle',
    'priconne',
    # 'setu',        # uncomment to enable

    # 'twitter',     # uncomment to enable

}

```

## Enabling and Disabling Modules

Module activation is controlled entirely by the `MODULES_ON` set in your global configuration. To enable a module, add its directory name (case-sensitive) to this set. To disable it, remove the entry or comment it out with `#`.

The directory name must match exactly the folder located under `hoshino/modules/`. For example, to enable the `setu` image-search module:

```python
MODULES_ON = {
    'botmanage',
    'dice',
    'groupmaster',
    'setu',          # newly enabled module

}

```

After modifying `MODULES_ON`, restart the bot with `python run.py`. The bootstrap code in [`hoshino/__init__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/__init__.py) will dynamically import any existing configuration for that module and register its plugins.

## Per-Module Configuration Methods

HoshinoBot supports two methods for configuring individual modules: Python-based config files and JSON-based data files.

### Method 1: Python Config Files

Create a file named `hoshino/config/<module>.py` to store module-specific constants. The module’s code imports this file directly from the config package.

For example, to configure API keys for the `setu` module, create [`hoshino/config/setu.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/config/setu.py):

```python

# hoshino/config/setu.py

API_KEY = "your_api_key_here"
PROXY = "http://127.0.0.1:7890"

```

The module source retrieves these values using:

```python
from hoshino.config import setu as cfg
api_key = cfg.API_KEY

```

### Method 2: JSON Config Files

For modules requiring structured data (such as gacha pools or translation dictionaries), place a [`config.json`](https://github.com/ice9coffee/hoshinobot/blob/main/config.json) file inside the module’s directory. The helper function `hoshino.util.load_config()` reads this file into a Python dictionary.

As implemented in [`hoshino/util/__init__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/util/__init__.py) (lines 28-36), this helper resolves the path relative to the calling module’s `__file__` and returns an empty dict if the file is missing.

Example usage within a module:

```python
from hoshino.util import load_config
cfg = load_config(__file__)          # reads <module_dir>/config.json

greeting = cfg.get('greeting', 'Hello!')

```

The **priconne gacha** module demonstrates this pattern with its [`hoshino/modules/priconne/gacha/config.json`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/modules/priconne/gacha/config.json) file, which defines summon pools and rarity rates:

```json
{
    "default": ["pool_a", "pool_b"],
    "pool_a": {
        "name": "Standard Pool",
        "rarity": {"5": 0.5, "4": 3.5}
    }
}

```

## Step-by-Step Configuration Guide

Follow these steps to configure a fresh HoshinoBot deployment:

1. **Clone and install dependencies**:
   ```bash
   git clone https://github.com/ice9coffee/hoshinobot.git
   cd hoshinobot
   pip install -r requirements.txt
   ```

2. **Prepare the configuration directory**:
   ```bash
   mv hoshino/config_example hoshino/config
   ```

3. **Edit global settings** in [`hoshino/config/__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/config/__bot__.py):
   - Set `SUPERUSERS` to your QQ ID
   - Configure `RES_DIR` and `RES_PROTOCOL` for your environment
   - Populate `MODULES_ON` with the modules you want active

4. **Add module-specific configs** (optional):
   - Create `hoshino/config/<module>.py` for API keys and secrets
   - Create `hoshino/modules/<module>/config.json` for data-driven modules

5. **Launch the bot**:
   ```bash
   python run.py
   ```

The bot will validate the global config, import each enabled module’s specific configuration, and start listening on the configured `HOST:PORT`.

## Summary

- **HoshinoBot configuration** is pure Python; rename `config_example` to `config` to activate the system
- **Global settings** live in [`hoshino/config/__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/config/__bot__.py), including the `MODULES_ON` set that controls which modules load
- **Module activation** requires adding the exact folder name to `MODULES_ON` and restarting the bot
- **Per-module configs** can be Python files (`hoshino/config/<module>.py`) for code constants or JSON files ([`config.json`](https://github.com/ice9coffee/hoshinobot/blob/main/config.json)) for structured data
- **JSON loading** uses the `load_config(__file__)` helper from `hoshino.util`, which safely handles missing files

## Frequently Asked Questions

### Where is the main configuration file located in HoshinoBot?

The main configuration file is [`hoshino/config/__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/config/__bot__.py). However, you must first rename the `hoshino/config_example` directory to `hoshino/config` when deploying the bot. This renaming step is required so that Python can import the configuration as the `hoshino.config` package during startup.

### How do I enable a new module in HoshinoBot?

Add the module’s folder name (exactly as it appears under `hoshino/modules/`) to the `MODULES_ON` set inside [`hoshino/config/__bot__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/config/__bot__.py). For example, to enable the `twitter` module, add `'twitter'` to the set, save the file, and restart the bot with `python run.py`. The bootstrap code in [`hoshino/__init__.py`](https://github.com/ice9coffee/hoshinobot/blob/main/hoshino/__init__.py) will then import the module’s config and register it as a nonebot plugin.

### What is the difference between Python and JSON config files in HoshinoBot?

Python config files (`hoshino/config/<module>.py`) are used for code-level constants like API keys, database URLs, and feature flags that the module imports directly. JSON config files ([`config.json`](https://github.com/ice9coffee/hoshinobot/blob/main/config.json) placed inside the module directory) are used for structured data like item lists, gacha pools, or message templates, and are loaded at runtime using `hoshino.util.load_config(__file__)`. Python configs are imported during bootstrap, while JSON configs are read dynamically when the module executes.

### Can I run HoshinoBot without configuring every module?

Yes. The `MODULES_ON` set controls exactly which modules load, and you can leave unused modules out of this set. Additionally, if a module looks for a JSON config file via `load_config()` and the file does not exist, the function returns an empty dictionary without raising an exception, allowing the module to use default hardcoded values. However, some modules may fail to function correctly if they require specific API keys defined in a Python config file that is missing.