feat: Introduce mock ROM mode for testing without actual ROM files
- Added a new feature to the `z3ed` AI agent allowing testing in mock ROM mode, which creates a minimal valid ROM structure with embedded labels but no actual game data. - Updated the `agent_test_suite.sh` script to default to mock ROM mode for easier testing. - Introduced `--mock-rom` command line flag to enable mock ROM mode in various agent commands. - Enhanced documentation to cover the usage and benefits of mock ROM mode for CI/CD and development testing. - Implemented necessary changes in the codebase to support mock ROM initialization and label management.
This commit is contained in:
@@ -97,6 +97,7 @@ set(YAZE_AGENT_SOURCES
|
||||
cli/service/resources/resource_context_builder.cc
|
||||
cli/handlers/overworld_inspect.cc
|
||||
cli/handlers/message.cc
|
||||
cli/handlers/mock_rom.cc
|
||||
cli/flags.cc
|
||||
cli/service/rom/rom_sandbox_manager.cc
|
||||
)
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
#include "absl/flags/flag.h"
|
||||
|
||||
ABSL_FLAG(std::string, rom, "", "Path to the ROM file");
|
||||
ABSL_FLAG(bool, mock_rom, false,
|
||||
"Use mock ROM mode for testing without requiring an actual ROM file. "
|
||||
"Loads all Zelda3 embedded labels but no actual ROM data.");
|
||||
|
||||
// AI Service Configuration Flags
|
||||
ABSL_FLAG(std::string, ai_provider, "auto",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "cli/handlers/agent/commands.h"
|
||||
#include "app/rom.h"
|
||||
#include "app/core/project.h"
|
||||
#include "cli/handlers/mock_rom.h"
|
||||
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
@@ -16,6 +17,7 @@
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
ABSL_DECLARE_FLAG(std::string, rom);
|
||||
ABSL_DECLARE_FLAG(bool, mock_rom);
|
||||
|
||||
namespace yaze {
|
||||
namespace cli {
|
||||
@@ -28,10 +30,23 @@ absl::Status LoadRomForAgent(Rom& rom) {
|
||||
return ::absl::OkStatus();
|
||||
}
|
||||
|
||||
// Check if mock ROM mode is enabled
|
||||
bool use_mock = ::absl::GetFlag(FLAGS_mock_rom);
|
||||
if (use_mock) {
|
||||
// Initialize mock ROM with embedded labels
|
||||
auto status = InitializeMockRom(rom);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
std::cout << "✅ Mock ROM initialized with embedded Zelda3 labels\n";
|
||||
return ::absl::OkStatus();
|
||||
}
|
||||
|
||||
// Otherwise load from file
|
||||
std::string rom_path = ::absl::GetFlag(FLAGS_rom);
|
||||
if (rom_path.empty()) {
|
||||
return ::absl::InvalidArgumentError(
|
||||
"No ROM loaded. Pass --rom=<path> to z3ed agent test-conversation.");
|
||||
"No ROM loaded. Pass --rom=<path> or use --mock-rom for testing.");
|
||||
}
|
||||
|
||||
auto status = rom.LoadFromFile(rom_path);
|
||||
|
||||
@@ -23,12 +23,14 @@
|
||||
#include "app/zelda3/dungeon/room.h"
|
||||
#include "app/zelda3/overworld/overworld.h"
|
||||
#include "cli/handlers/message.h"
|
||||
#include "cli/handlers/mock_rom.h"
|
||||
#include "cli/handlers/overworld_inspect.h"
|
||||
#include "cli/service/resources/resource_context_builder.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "util/macro.h"
|
||||
|
||||
ABSL_DECLARE_FLAG(std::string, rom);
|
||||
ABSL_DECLARE_FLAG(bool, mock_rom);
|
||||
|
||||
namespace yaze {
|
||||
namespace cli {
|
||||
@@ -37,10 +39,22 @@ namespace agent {
|
||||
namespace {
|
||||
|
||||
absl::StatusOr<Rom> LoadRomFromFlag() {
|
||||
// Check if mock ROM mode is enabled
|
||||
bool use_mock = absl::GetFlag(FLAGS_mock_rom);
|
||||
if (use_mock) {
|
||||
Rom rom;
|
||||
auto status = InitializeMockRom(rom);
|
||||
if (!status.ok()) {
|
||||
return status;
|
||||
}
|
||||
return rom;
|
||||
}
|
||||
|
||||
// Otherwise load from file
|
||||
std::string rom_path = absl::GetFlag(FLAGS_rom);
|
||||
if (rom_path.empty()) {
|
||||
return absl::FailedPreconditionError(
|
||||
"No ROM loaded. Use --rom=<path> to specify ROM file.");
|
||||
"No ROM loaded. Use --rom=<path> or --mock-rom for testing.");
|
||||
}
|
||||
|
||||
Rom rom;
|
||||
|
||||
87
src/cli/handlers/mock_rom.cc
Normal file
87
src/cli/handlers/mock_rom.cc
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "cli/handlers/mock_rom.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "absl/flags/declare.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "app/core/project.h"
|
||||
#include "app/zelda3/zelda3_labels.h"
|
||||
|
||||
ABSL_DECLARE_FLAG(bool, mock_rom);
|
||||
|
||||
namespace yaze {
|
||||
namespace cli {
|
||||
|
||||
absl::Status InitializeMockRom(Rom& rom) {
|
||||
// Create a minimal but valid SNES ROM header
|
||||
// Zelda3 is a 1MB ROM (0x100000 bytes) in LoROM mapping
|
||||
constexpr size_t kMockRomSize = 0x100000; // 1MB
|
||||
std::vector<uint8_t> mock_data(kMockRomSize, 0x00);
|
||||
|
||||
// SNES header is at 0x7FC0 for LoROM
|
||||
constexpr size_t kHeaderOffset = 0x7FC0;
|
||||
|
||||
// Set ROM title (21 bytes at 0x7FC0)
|
||||
const char* title = "YAZE MOCK ROM TEST "; // 21 chars including spaces
|
||||
for (size_t i = 0; i < 21; ++i) {
|
||||
mock_data[kHeaderOffset + i] = title[i];
|
||||
}
|
||||
|
||||
// ROM makeup byte (0x7FD5): $20 = LoROM, no special chips
|
||||
mock_data[kHeaderOffset + 0x15] = 0x20;
|
||||
|
||||
// ROM type (0x7FD6): $00 = ROM only
|
||||
mock_data[kHeaderOffset + 0x16] = 0x00;
|
||||
|
||||
// ROM size (0x7FD7): $09 = 1MB (2^9 KB = 512 KB = 1MB with header)
|
||||
mock_data[kHeaderOffset + 0x17] = 0x09;
|
||||
|
||||
// SRAM size (0x7FD8): $03 = 8KB (Zelda3 standard)
|
||||
mock_data[kHeaderOffset + 0x18] = 0x03;
|
||||
|
||||
// Country code (0x7FD9): $01 = USA
|
||||
mock_data[kHeaderOffset + 0x19] = 0x01;
|
||||
|
||||
// Developer ID (0x7FDA): $33 = Extended header (Zelda3)
|
||||
mock_data[kHeaderOffset + 0x1A] = 0x33;
|
||||
|
||||
// Version number (0x7FDB): $00 = 1.0
|
||||
mock_data[kHeaderOffset + 0x1B] = 0x00;
|
||||
|
||||
// Checksum complement (0x7FDC-0x7FDD): We'll leave as 0x0000 for mock
|
||||
// Checksum (0x7FDE-0x7FDF): We'll leave as 0x0000 for mock
|
||||
|
||||
// Load the mock data into the ROM
|
||||
auto load_status = rom.LoadFromData(mock_data);
|
||||
if (!load_status.ok()) {
|
||||
return absl::InternalError(
|
||||
absl::StrFormat("Failed to initialize mock ROM: %s",
|
||||
load_status.message()));
|
||||
}
|
||||
|
||||
// Initialize embedded labels so queries work without actual ROM data
|
||||
core::YazeProject project;
|
||||
auto labels_status = project.InitializeEmbeddedLabels();
|
||||
if (!labels_status.ok()) {
|
||||
return absl::InternalError(
|
||||
absl::StrFormat("Failed to initialize embedded labels: %s",
|
||||
labels_status.message()));
|
||||
}
|
||||
|
||||
// Attach labels to ROM's resource label manager
|
||||
if (rom.resource_label()) {
|
||||
rom.resource_label()->labels_ = project.resource_labels;
|
||||
rom.resource_label()->labels_loaded_ = true;
|
||||
}
|
||||
|
||||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
bool ShouldUseMockRom() {
|
||||
return absl::GetFlag(FLAGS_mock_rom);
|
||||
}
|
||||
|
||||
} // namespace cli
|
||||
} // namespace yaze
|
||||
|
||||
35
src/cli/handlers/mock_rom.h
Normal file
35
src/cli/handlers/mock_rom.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef YAZE_CLI_HANDLERS_MOCK_ROM_H
|
||||
#define YAZE_CLI_HANDLERS_MOCK_ROM_H
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "app/rom.h"
|
||||
|
||||
namespace yaze {
|
||||
namespace cli {
|
||||
|
||||
/**
|
||||
* @brief Initialize a mock ROM for testing without requiring an actual ROM file
|
||||
*
|
||||
* This creates a minimal but valid ROM structure populated with:
|
||||
* - All Zelda3 embedded labels (rooms, sprites, entrances, items, etc.)
|
||||
* - Minimal header data to satisfy ROM validation
|
||||
* - Empty but properly sized data sections
|
||||
*
|
||||
* Purpose: Allow AI agent testing and CI/CD without committing ROM files
|
||||
*
|
||||
* @param rom ROM object to initialize as mock
|
||||
* @return absl::OkStatus() on success, error status on failure
|
||||
*/
|
||||
absl::Status InitializeMockRom(Rom& rom);
|
||||
|
||||
/**
|
||||
* @brief Check if mock ROM mode should be used based on flags
|
||||
* @return true if --mock-rom flag is set
|
||||
*/
|
||||
bool ShouldUseMockRom();
|
||||
|
||||
} // namespace cli
|
||||
} // namespace yaze
|
||||
|
||||
#endif // YAZE_CLI_HANDLERS_MOCK_ROM_H
|
||||
|
||||
Reference in New Issue
Block a user