⚠️ Clean-Room / Educational

This project is educational and Open Source. No code is copied from other emulators. Implementation based solely on technical documentation and permitted tests.

Fix AttributeError: _framebuffer_copy_detailed_count

Date:2025-12-29 StepID:0367 State: VERIFIED

Summary

Fixed aAttributeErrorwhat happened during execution when the code tried to access the attribute_framebuffer_copy_detailed_countwhich was not initialized in the classViboy. The error occurred in the methodrun()when trying to verify the counter before initializing it. Added initialization of the counter using the patternhasattr()before using it, following the same convention as other similar counters in the code.

Hardware Concept

This fix is ​​not directly related to the Game Boy hardware, but rather to state management in the emulator. However, it is important to understand that diagnostic counters are useful tools for tracking behavior. of the emulator without affecting the performance of the main loop.

Lazy Attribute Initialization in Python

In Python, it is common to use the "lazy initialization" pattern for attributes that are only needed under certain conditions. This pattern consists of:

  1. Check if the attribute exists usinghasattr()
  2. Initialize it only if it does not exist
  3. Use it normally after verification

This pattern is useful when:

  • The attribute is only needed under certain conditions (e.g. when debug mode is activated)
  • You want to avoid initializing many attributes in the constructor if they are not going to be used
  • Need to maintain compatibility with code that may or may not initialize the attribute

Implementation

Identified Problem

During execution, the following error occurred:

AttributeError: 'Viboy' object has no attribute '_framebuffer_copy_detailed_count'
  File "/media/fabini/8CD1-4C30/ViboyColor/src/viboy.py", line 1018, in run
    if self._framebuffer_copy_detailed_count<= 5:

The code was trying to access the attribute_framebuffer_copy_detailed_countwithout first checking if it existed, causing aAttributeErrorwhen the attribute was not initialized.

Implemented Solution

Added counter initialization using patternhasattr()before using it, following the same convention than other similar counters in the code (such as_framebuffer_copy_verify_count).

Code Before (Incorrect)

#4. Check first 20 pixels after copying
first_20_after = [fb_data[i] & 0x03 for i in range(min(20, len(fb_data)))]

if self._framebuffer_copy_detailed_count<= 5:  # ❌ AttributeError si no existe
    logger.info(f"[Viboy-Framebuffer-Copy-Detailed] First 20 indices after copy: {first_20_after}")

Code After (Correct)

#4. Check first 20 pixels after copying
first_20_after = [fb_data[i] & 0x03 for i in range(min(20, len(fb_data)))]

# Initialize counter if it does not exist
if not hasattr(self, '_framebuffer_copy_detailed_count'):
    self._framebuffer_copy_detailed_count = 0

if self._framebuffer_copy_detailed_count<= 5:
    self._framebuffer_copy_detailed_count += 1
    logger.info(f"[Viboy-Framebuffer-Copy-Detailed] First 20 indices after copy: {first_20_after}")

Fixed Locations

Added initialization in two places where the counter is used:

  1. Line ~1018:Before checking the first 20 pixels after copying
  2. Line ~1065:Before counting indexes in the copy (redundant initialization for security)

Affected Files

  • src/viboy.py- Added initialization_framebuffer_copy_detailed_countin two places (lines ~1018-1020 and ~1065-1067)

Tests and Verification

A quick test was run to verify that the bug was fixed:

Command Executed

timeout 5 python3 main.py roms/tetris.gb 2>&1 | grep -E "(Error|AttributeError|_framebuffer_copy_detailed_count)"

Result

✅ The error ofAttributeError: 'Viboy' object has no attribute '_framebuffer_copy_detailed_count'it no longer appears.

The code now initializes the counter correctly before using it, following the same pattern as other diagnostic counters in the code.

Sources consulted

  • Python Documentation:hasattr()- Function to check if an object has an attribute
  • Python Best Practices: Lazy attribute initialization

Educational Integrity

What I Understand Now

  • Lazy initialization:It is a useful pattern for attributes that are only needed under certain conditions, avoiding initializing many attributes in the constructor
  • hasattr():Allows you to check if an object has an attribute before accessing it, avoiding AttributeError
  • Code consistency:It is important to follow the same pattern as other similar counters in the code to maintain consistency

What remains to be confirmed

  • Initialization in __init__:Consider whether it would be better to initialize all diagnostic counters in the constructor to avoid these types of errors

Hypotheses and Assumptions

Assumption:Lazy initialization is preferable for diagnostic counters that are only used in debug mode, since it avoids initializing many unnecessary attributes when debug mode is disabled. This assumption is supported by the fact that other similar counters in the code use the same pattern.

Next Steps

  • [ ] Consider initializing all diagnostic counters in the constructor to avoid similar errors
  • [ ] Verify that there are no other attributes that may have the same problem
  • [ ] Continue with rendering tests after correcting Step 0366