Add OpenTelemetry metrics and traces instrumentation#2927
Open
Add OpenTelemetry metrics and traces instrumentation#2927
Conversation
Step 1 of world loading refactoring plan - baseline checksums. New files: - src/engine/db/world_checksum.h/cpp: CRC32-based checksum calculation for zones, rooms, mobs, objects, and triggers Features: - Calculates individual checksums per entity type using XOR aggregation - Combined checksum for detecting any world data changes - Detailed per-object checksums saved to file for diff analysis - CLI flag -C to disable checksum calculation Integration: - Checksums calculated at end of GameLoader::BootWorld() - Results logged to syslog and saved to checksums_detailed.txt CMake additions: - FULL_WORLD_PATH option for specifying full world data location - Automatic setup of small/full data directories in build dir Baseline checksums: Small World (lib): Combined: 4E6499FF Full World: Combined: BB58755C Detailed checksums saved in checksums_small.txt and checksums_full.txt for future comparison after refactoring. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Introduces an interface-based abstraction layer for world data loading: - IWorldDataSource interface with LoadZones/Triggers/Rooms/Mobs/Objects - LegacyWorldDataSource wraps existing BootIndex() calls - GameLoader::BootWorld() now accepts optional data source parameter - Excludes zone_rn from room checksums (runtime-calculated value) - Fixes compiler warnings (unused variable, strncpy truncation) Checksums verified identical before/after refactoring: - Small world: B6DA5931 - Full world: 82CF7A3E Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add optional SQLite support via HAVE_SQLITE CMake flag - Create SqliteWorldDataSource skeleton class (load methods not yet implemented) - Add Save methods to IWorldDataSource interface for OLC - Implement Save methods in LegacyWorldDataSource (delegates to *_save_to_disk) - Add trigedit_save_to_disk function for trigger saving - Fix compiler warnings in utils.cpp (array bounds, strncpy truncation) - Add Claude Code workflow rules to CLAUDE.md Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add complete implementation for loading world data from SQLite database: - Zones with commands (M,O,G,E,P,D,R,T,V,Q,F) and typeA/typeB groups - Triggers with script parsing into cmdlist - Rooms with flags, exits, triggers, and extra descriptions - Mobs with flags, skills, triggers, and all attributes - Objects with extra/wear/no/anti flags, applies, triggers, extra descriptions Schema matches mud-docs/world_schema.sql specification. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- GetText now returns std::string with UTF-8 to KOI8-R conversion - Add SafeStoi/SafeStol helper functions for safe string-to-number conversion - Fix all const char* usages to std::string - Fix to_room to store vnum (not rnum) - RosolveWorldDoorToRoomVnumsToRnums will convert later - Fix top_of_mobt to be last valid index (not count) for compatibility with CreateBlankMobsDungeon Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove -S command line option for SQLite database path - Move chdir() before config loading so paths are relative to data dir - Fix configuration.xml path to be relative (misc/ instead of lib/misc/) - Auto-detect world.db in data directory: if exists use SQLite, else legacy Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add direction_map to convert direction strings (north/east/etc) to numbers - Fix DOOR command arg2 to use direction_map instead of SafeStoi - Add load_prob (arg4) loading for GIVE_OBJ commands Zones checksums now match between legacy and SQLite loaders. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Set NPC flag before set_level() to avoid clamping mob levels to 34 (kLvlImplementator limit for non-NPCs) - Fix long_descr/description column swap (columns 8 and 9) - Set max_hit to 0 (flag for dice-based HP calculation) - Add trigger existence validation with warnings for missing triggers - Use ORDER BY rowid for predictable trigger loading order - Skip non-existent triggers instead of adding invalid references Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tests/utils.encoding.cpp with unit tests for utf8_to_koi function covering ASCII, Cyrillic, NO-BREAK SPACE, and box drawing characters - Fix NO-BREAK SPACE (U+00A0) conversion: UTF-8 0xC2 0xA0 -> KOI8-R 0x9A - Add lib symlink creation in CMake for running server from build directory Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add sex field to SQL query and loading code - Fix set_level vs set_minimum_remorts bug (was reading level column but calling wrong setter) - Update column indices for max_in_world after sex addition Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- SQLite loader now calculates zone_rn incrementally by vnum (matching Legacy) - Add extra_flags, anti_flags, no_flags, affect_flags to object checksum - Add extra_descriptions to object checksum Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…lags - Add kTrap to obj_type_map for proper type loading - Handle NULL max_in_world by returning -1 (matching Legacy behavior) - Add affect flag category handling for object weapons Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
… loader - Add kElementWeapon, kMissile, kWorm, kCraftMaterial2 to obj_type_map - Add missing extra flags (kSwimming, kFlying, kThrowing, plane 1 flags) - Apply colorLOW to short_description and PNames (match Legacy loader) - Apply colorCAP to description (match Legacy loader) - Add utils_string.h include for colorLOW/colorCAP - Update CLAUDE.md with SQLite world conversion documentation - Add patch-based editing guidance to CLAUDE.md Objects match: 99.7% (13 remaining differences) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Clear runtime flags (kTransformed, kTicktimer) after loading objects - Set max_in_world to -1 for objects with kZonedacay or kRepopDecay flags This ensures SQLite loader produces identical object prototypes to Legacy. All 5192 objects now match (100% checksum match). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use normalized trigger_type_bindings table with JOIN query - Compute trigger_type bitmask from type_chars (a-z = bits 0-25, A-Z = bits 26-51) - Add TrimRight for script lines to remove trailing whitespace - Add indent_trigger call to normalize script indentation - Include dg_olc.h for indent_trigger function All world checksums now match between Legacy and SQLite loaders. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Read obj_type_id, sector_id, attach_type_id, direction_id directly - Read location_id, skill_id, arg_wear_pos_id, arg_direction_id directly - Remove unused text-to-enum conversion maps - Use static_cast for direct integer-to-enum conversion - Matches normalized schema in mud-docs All checksums verified to match between Legacy and SQLite loaders. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added tools/: - convert_to_yaml.py: Legacy world to SQLite/YAML converter - world_schema.sql: SQLite database schema - sqlite-world-schema.md: Schema documentation - compare_world_checksums.sh: Test script for verifying checksums Updated .gitignore to exclude build directories. Removed generated checksum files (now in test builds). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 'enabled' column to SQLite schema for zones, rooms, mobs, objects, triggers to support index file filtering - Update converter to read index files and mark non-indexed entities as disabled (enabled=0) - Update SQLite loader to filter on enabled=1, matching Legacy behavior - Add minimum_remorts column to objects table - Add detailed checksum comparison infrastructure: - SaveDetailedBuffers() saves serialization buffers per entity - LoadBaselineChecksums() loads baseline for comparison - CompareWithBaseline() reports mismatches with field-level detail - Update compare_world_checksums.sh with --rebuild and --reconvert flags - Fix room exit serialization to use vnum instead of rnum Checksum verification: Small world shows 100% match between Legacy and SQLite loaders (zones, rooms, mobs, objects, triggers all identical). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When built with HAVE_SQLITE support but world.db file is not found, exit with error instead of silently falling back to legacy loader. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Restored KOI8-R encoding (was corrupted in 0c9ca3c) - Added includes for world_checksum, legacy/sqlite data sources - Renamed world_loader to game_loader - Refactored BootWorld to use IWorldDataSource abstraction - Added checksum calculation and baseline comparison at boot - Added no_world_checksum flag to disable checksums Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- setup_test_dirs.sh: Creates test directories for Legacy/SQLite comparison - run_load_tests.sh: Runs performance tests and compares checksums - Add test/ and magic.mgc to .gitignore Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The Trigger constructor expects rnum (runtime array index) as the first parameter, not vnum (persistent database ID). Passing vnum caused out-of-bounds array access in GET_TRIG_VNUM macro when the vnum was larger than the trig_index array size, resulting in segfaults during zone reset on larger worlds. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Filter files by pattern ^\d+\.<ext>$ to ignore backup files like 16.old.obj
- Fix armor parsing for negative values (use lstrip('-').isdigit())
- Use \r\n for joining multi-line aliases and case names (Legacy fread_string
converts \n to \r\n)
- Remove .strip() calls that were removing control characters like \x1d
- Keep trailing spaces in aliases to match Legacy behavior
This significantly reduces checksum differences:
- MOB: 1354 → 1
- OBJ: still has differences (to be investigated)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Schema changes: - Replace UNIQUE constraint on entity_triggers with trigger_order column - Allows duplicate triggers (same trigger attached multiple times) Converter changes: - Add trigger_order field for proper trigger ordering - Fix plane 2 offset in parse_ascii_flags (43 → 60) - Each plane has 30 bits, not varying sizes Loader changes: - Add explicit flag maps for affect, anti, no flags - Replace ITEM_BY_NAME with direct map lookups - More reliable flag loading without silent failures Progress (small world after reconvert): Zones: 100.0% (0 diff) Rooms: 99.9% (3 diff - missing kNoItem plane 2 flag) Mobs: 100.0% (0 diff) Objects: 100.0% (0 diff) Triggers: 100.0% (0 diff) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes: - Add --skip-encoding option - Check for UTF-8 BOM and Cyrillic in source files - Increase default dump count to 10 - Add buffer comparison for all entity types (rooms, triggers, zones) - Show field-by-field diff using | separator - Use temp files to avoid binary file issues with diff Progress (small world): Zones: 100.0% (0 diff) Rooms: 99.9% (3 diff - missing kNoItem plane 2 flag) Mobs: 100.0% (0 diff) Objects: 100.0% (0 diff) Triggers: 100.0% (0 diff) Progress (full world): Zones: 44.6% (354 diff) Rooms: 99.0% (435 diff) Mobs: 100.0% (0 diff) Objects: 99.5% (95 diff) Triggers: 97.8% (367 diff) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Converter: - Add load_prob parsing for E (EQUIP_MOB) command Loader: - Add arg4 (load_prob) reading for EQUIP_MOB commands - Add arg4 (load_prob) reading for PUT_OBJ commands Progress (full world): Zones: 78.7% (136 diff - zone.group not loaded yet) Rooms: 99.0% (435 diff - kNoItem flag) Mobs: 100.0% (0 diff) ✓ Objects: 99.5% (95 diff) Triggers: 97.8% (367 diff) Progress (small world): Zones: 100.0% ✓ Rooms: 99.9% (3 diff - kNoItem flag) Mobs: 100.0% ✓ Objects: 100.0% ✓ Triggers: 100.0% ✓ Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Converter: - Add UNUSED entries (indices 43-59) to ROOM_FLAGS array - Plane 2 flags (kNoItem, kDominationArena) now at correct indices 60-61 - Fixes room flags like kNoItem not being parsed from 'a2' format Tests: - Add test_convert_to_yaml.py with unit tests for parse_ascii_flags - Test plane 0, 1, 2 flags parsing - Test actual room 101 flags from small world - Verify ROOM_FLAGS array structure Progress (small world): Zones: 100.0% ✓ Rooms: 100.0% ✓ Mobs: 100.0% ✓ Objects: 100.0% ✓ Triggers: 100.0% ✓ Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Read zone_group from database instead of hardcoding to 1 - Apply same 0->1 conversion as Legacy loader - Add under_construction column to schema and converter - Parse 'test' flag in zone files for under_construction - Small world: 100% match on all categories - Full world: Zones 93.1%, Rooms 99.3%, Mobs 100%, Objects 99.5%, Triggers 97.8% Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply same weight correction as Legacy for kLiquidContainer and kFountain objects: if weight < val1, set weight = val1 + 5. Progress on full world: - Objects: 99.5% (90 diff, was 95) - Small world: 100% match Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace per-call iconv_open/iconv_close in koi8r_to_utf8 with a static iconv_t handle opened once. KOI8-R and UTF-8 are stateless encodings so the descriptor has no shared mutable state between calls. Combined with the existing ASCII fast-path this eliminates the iconv overhead at 25Hz. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setup_logs() creates log/ in the working directory before chdir(), but CSteppedProfiler and do_loadstat opened profiler.log with a hardcoded relative "log/" prefix which broke after chdir() into the data dir. Use runtime_config.log_dir() (absolute path set in setup_logs()) instead. Remove the now-unused LOAD_LOG_FOLDER macro. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move NowTs() from static in otel_provider.cpp to observability::NowTs() in otel_helpers.h/cpp with date+time format (YYYY-MM-DD HH:MM:SS.mmm). Apply to all printf/puts in comm.cpp and config.cpp startup path so every line printed to stdout during boot has a consistent timestamp prefix. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Step names (e.g. "Зоны", "Мобы") are KOI8-R strings that were going into OTEL metrics attributes and span names without conversion, causing "invalid UTF-8" protobuf errors. Apply koi8r_to_utf8 to step.name() in both the metrics attribute and the StartSpan call. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The function was declared in the header but defined in otel_helpers.cpp. In non-OTEL builds the function was not visible to config.cpp because of include-chain issues. Move the definition inline into the header to guarantee availability in all build configurations. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
otel_helpers.h has a complex include chain that caused NowTs to be invisible in non-OTEL builds of config.cpp. Move NowTs to a new minimal header utils/timestamp.h with no project dependencies. Update config.cpp, comm.cpp, otel_provider.cpp to include it directly. otel_helpers.h re-exports utils::NowTs via using declaration. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The shared header approach ran into mysterious include-chain problems in non-OTEL CI builds. Define NowTs as a local anonymous namespace function in config.cpp to guarantee availability without any external dependencies. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The anonymous namespace with NowTs was accidentally placed inside the #ifdef WITH_OTEL block, making it unavailable in non-OTEL builds. Move it outside the guard so it is always compiled. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AddEvent() and SetAttribute(string) in both OtelSpan and observability::Span were passing raw KOI8-R strings directly to protobuf. Apply koi8r_to_utf8 to span names, event names, and string attribute values in otel_traces.cpp and OtelSpan::AddEvent in otel_trace_sender.cpp. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AddEvent was passing raw KOI8-R span event names directly to protobuf, causing wire_format_lite invalid UTF-8 errors. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- magic_utils.cpp: convert spell_name and caster_class before SetAttribute - item_creation.cpp: convert recipe_name and skill before SetAttribute - otel_helpers.cpp: convert secondary_name in DualSpan::StartSpan (low-level API) - otel_provider.cpp: call absl::InitializeLog() at OTEL init to suppress "All log messages before absl::InitializeLog()" warning Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ция) Add ToUtf8Attrs() helper inside OtelMetrics that converts all string attribute values from KOI8-R to UTF-8. Applied to all attribute-accepting overloads of RecordCounter/RecordHistogram/RecordGauge. Callers now never need to manually call koi8r_to_utf8 - the wrapper handles encoding at the single point of entry into the OTEL metrics API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
otel_log_sender.cpp:
- Use native SetTraceId/SetSpanId/SetTraceFlags on log records instead of
manual hex extraction; this properly populates OTLP proto fields
- Keep trace_id string attribute for Loki derivedFields (Loki->Tempo link)
- Remove GetCurrentTraceContext() helper, use GetCurrentSpanContext() directly
datasources.yml:
- Fix tracesToLogs query: remove backslash-escaping inside single-quoted YAML
that caused Grafana to silently ignore the entire tracesToLogs block
- Simplified query to: {service_name=~".+"} | trace_id = "${__trace.traceId}"
- Extend time window to +-5m for better log coverage
tempo-config.yaml:
- Add metrics_generator with service-graphs and span-metrics processors
- Remote-write generated metrics to Prometheus for Service Map in Grafana
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
remote_write belongs inside storage, not directly under metrics_generator. Fixes Tempo startup failure with "field remote_write not found in type generator.Config". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add histogram buckets tuned for game timing (1ms - 2.5s) - Add custom dimensions: step, spell_name, trigger_type - Enable target_info metric for better service identification Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without uid: prometheus, Grafana auto-generates a random UID and the references datasourceUid: prometheus in Tempo's serviceMap and tracesToMetrics sections fail with "Datasource prometheus was not found". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
trace_id is indexed as a Loki label (not structured metadata), so the
correct filter is {trace_id="..."} label selector, not pipe filter
| trace_id = "...". The pipe filter was silently ignored, showing all
logs without filtering by trace ID.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without otlp_config, Loki promoted ALL log attributes to labels including trace_id and span_id (high cardinality - unique per request). This is production-unsafe. Fix: - Only service.name and service.namespace become Loki index labels - All other resource/log/scope attributes go to structured metadata - Grafana query reverted to pipe filter: | trace_id = "..." which works correctly against structured metadata in Loki 3.x Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix all gauge queries: use rate(_gauge_sum) / rate(_gauge_count) - Replace non-existent metrics (combat_round_duration, craft_*, auction_sale/revenue) with actual metrics from Prometheus - Add heartbeat_step_duration panel to operational and performance dashboards - Add heartbeat_missed_pulses panel to performance dashboard - Create METRICS.md with accurate Prometheus metric names and PromQL examples - Simplify README.md to reflect actual state - Delete outdated OTEL_INSTRUMENTATION.md, PERFORMANCE_IMPACT.md, DEPLOYMENT_GUIDE.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New metrics: - combat.active.count gauge in perform_violence() (fight.cpp) - player.deaths.total counter with death_type=pvp/pve/other (fight_stuff.cpp) - spell.cast.duration now includes spell_id/caster_class attrs (magic_utils.cpp) Docs: - Restored PERFORMANCE_IMPACT.md with corrected analysis (removed non-existent systems) - METRICS.md: added combat.active.count, player.deaths.total, expanded auction section - business-logic-dashboard: restored auction/craft panels (appear after first event), added player deaths panel Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
foldersFromFilesStructure: true in dashboards.yml means subdirectory name becomes the Grafana folder name automatically. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove DEBUG logging block from heartbeat.cpp (debug_counter % 250) - Remove stale -S <database> flag from comm.cpp help text (auto-detect was already implemented in an earlier commit) - Remove world-loading tools already superseded by master: convert_to_yaml.py, world_schema.sql, compare_world_checksums.sh, setup_test_dirs.sh, test_convert_to_yaml.py Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
OtelMetrics (via ToUtf8Attrs) and OtelTraceSender already perform KOI8-R→UTF-8 conversion internally. Callers must pass raw KOI8-R strings — conversion is the responsibility of the observability layer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ator() OtelMetrics methods are already no-ops without WITH_OTEL (empty body with (void) casts), so the #ifdef guard in operator() was redundant and obscured the control flow. Extract metric reporting into a private record_otel_metrics() method with clear semantics, keeping operator() focused on timing and tracing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Manager ownership OtelMetrics methods are already no-ops without WITH_OTEL, so #ifdef guards in ZoneReset::Reset() and HandleZoneCmdQ() are unnecessary. LogManager: replace raw leaked pointer with unique_ptr. Its declaration position (second in GlobalObjectsStorage) already ensures it is destroyed after all game objects and before OutputThread, per C++ reverse-init order. The "intentionally leaked" comment was incorrect. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
m_combat_root_span, m_combat_baggage_scope, m_combat_id were declared but never used — planned instrumentation that was not implemented. Also remove the forward declarations and unused includes (otel_helpers.h, trace_sender.h) from char_data.cpp that were added for this dead code. DualSpan cannot provide value in our stack: Loki log correlation works with a single trace_id, so parallel span trees give no observability benefit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Neither is used anywhere in gameplay code. DualSpan provided no value in our stack: Loki correlates logs with a single trace_id, so parallel span trees are invisible in practice. Also remove unused includes (trace_manager.h, noop_trace_sender.h, otel_trace_sender.h, baggage headers) from otel_helpers.cpp. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- otel_metrics.cpp: move (void) casts to #else blocks (not after #endif) - otel_provider: remove GetTracer/GetMeter/GetLogger from public interface; callers now use OTel global provider API directly - otel_trace_sender.h, otel_log_sender.h: remove redundant #ifdef WITH_OTEL wrappers (files are OTel-internal, only included by OTel implementation files) - dg_olc.cpp: remove dead void trigedit_save_to_disk(int zone_rnum) overload - dg_scripts.cpp: extract trigger_type_name() helper, remove dead attrs map - mobact.cpp: restore from master, add clean OTel instrumentation without extra blank lines or koi8r_to_utf8 at call site - game_limits.cpp: extract record_level_remort_distribution() helper - item_creation.cpp: remove misplaced span/metric from kMakeStaff early-exit block; remove unnecessary includes - char_data.h: remove two spurious blank lines Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
world-load-refactoring(PR World load refactoring #2891) changesInstrumented systems
Test plan
-DWITH_OTEL=ONand verify compilation-DWITH_OTEL=OFF) and verify no regressions./tests/tests🤖 Generated with Claude Code