This document describes the organization of configuration files and parsers in the Air-Trap project.
Directory Structure
common/include/RType/Config/
├── SimpleJsonParser.hpp # Low-level JSON parser (no external dependencies)
├── WeaponConfig.hpp # Weapon definitions loader
└── SpriteMapConfig.hpp # Sprite mapping loader (mod system)
config/
├── common/ # Shared configs (server + client)
│ └── weapons.json # Weapon stats and properties
└── client/ # Client-only configs
├── sprite_mappings.json # Custom sprite mod mappings
└── ENTITY_KEYS.md # Valid entity keys documentation
Parser Layer (common/include/RType/Config/)
All configuration parsers are centralized in the common/ directory to ensure consistency and reusability.
SimpleJsonParser.hpp
- Purpose: Lightweight JSON parser with no external dependencies
- API:
bool parse(filepath) - Parse JSON from file path
bool parseContent(jsonString) - Parse JSON from string
getData() - Get parsed key-value pairs
getString(), getInt(), getFloat(), getBool() - Type-safe accessors
WeaponConfig.hpp
- Purpose: Load and manage weapon definitions
- API:
loadWeaponConfigs() - Load all weapons from config/common/weapons.json
getWeaponDef(WeaponKind) - Get weapon stats by type
hasWeaponConfigs() - Check if configs loaded successfully
getWeaponDisplayName(WeaponKind) - Get localized weapon name
SpriteMapConfig.hpp
- Purpose: Load and save sprite mappings for the mod system
- API:
loadSpriteMappings(filepath) - Load sprite mappings from JSON
saveSpriteMappings(mappings, filepath) - Save sprite mappings to JSON
- Returns:
std::unordered_map<std::string, std::string> (entity key → sprite path)
Usage Examples
Loading Weapon Configs (Server/Client)
int damage = weapon.damage;
float fireRate = weapon.fireRate;
std::unordered_map< rtp::ecs::components::WeaponKind, rtp::ecs::components::SimpleWeapon > loadWeaponConfigs(const std::string &path="config/common/weapons.json")
const rtp::ecs::components::SimpleWeapon & getWeaponDef(rtp::ecs::components::WeaponKind kind)
Loading Sprite Mappings (Client Only)
if (mappings.find("shot_6") != mappings.end()) {
std::string customPath = mappings["shot_6"];
}
std::unordered_map< std::string, std::string > loadSpriteMappings(const std::string &filepath="config/client/sprite_mappings.json")
Load sprite mappings from a JSON file.
Saving Sprite Mappings (Client Only)
std::unordered_map<std::string, std::string> mappings;
mappings["shot_6"] = "assets/sprites/custom/projectiles/my_bullet.png";
bool saveSpriteMappings(const std::unordered_map< std::string, std::string > &mappings, const std::string &filepath="config/client/sprite_mappings.json")
Save sprite mappings to a JSON file.
Client Integration
Client code should use the high-level config loaders instead of direct JSON parsing:
- SpriteCustomizer: Uses
SpriteMapConfig::loadSpriteMappings()
- ModMenuScene: Uses
SpriteMapConfig::loadSpriteMappings() and saveSpriteMappings()
- EntitySystem: Uses
WeaponConfig::loadWeaponConfigs() and getWeaponDef()
Benefits of Centralization
- Single Source of Truth: All JSON parsing logic in one place
- Consistency: Same parser behavior across server and client
- No External Dependencies: Custom parser means no nlohmann/json requirement
- Type Safety: Structured loaders with clear APIs
- Maintainability: Easy to update parsing logic without touching client code
- Testability: Config loaders can be tested independently
Adding New Config Types
To add a new configuration type:
- Create a new
*Config.hpp file in common/include/RType/Config/
- Use
SimpleJsonParser for parsing
- Provide
load*() and optionally save*() functions
- Return structured data (maps, vectors, or custom structs)
- Document the config file format and location
Example:
inline std::vector<EnemyDef> loadEnemyConfigs(
const std::string& filepath = "config/common/enemies.json"
) {
}
}
File : SpriteMapConfig.hpp License: MIT Author : GitHub Copilot Date : 18/01/2026.