Skip to content

fix: TextBoxComponent crashes with the text in the examples #3938

Closed

Description

@erickzanardo

What happened?

While accessing the text examples at https://examples.flame-engine.org, the page crashes.

What do you expect?

Examples to be rendered fine.

How can we reproduce this?

Just access the Text example in the examples and the page will freeze

What steps should take to fix this?

No response

Do have an example of where the bug occurs?

import 'dart:async';

import 'package:flame/components.dart';
import 'package:flame/game.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(GameWidget.controlled(gameFactory: MyGame.new));
}

class MyGame extends FlameGame {
  @override
  FutureOr<void> onLoad() async {
    await super.onLoad();

    const text =
        '"This is our world now. The world of the electron and the switch; '
        'the beauty of the baud. We exist without nationality, skin color, '
        'or religious bias. You wage wars, murder, cheat, lie to us and '
        "try to make us believe it's for our own good, yet we're the "
        'criminals. Yes, I am a criminal. My crime is that of curiosity."';

    add(TextBoxComponent(text: text, position: Vector2.all(100)));
  }
}

Relevant log output

No log output, the page just freezes.

Execute in a terminal and put output into the code block below

Output of: flutter doctor -v

Affected platforms

Web

Other information

Tested on MacOS, android and web, and it seems to only break on web.

Are you interested in working on a PR for this?

  • I want to work on this

Activity

  1. self-assigned this
    on Jul 1, 2026
  2. erickzanardo commented on Jul 1, 2026

    @erickzanardo
    MemberAuthor

    After a bit of debugging, I tracked down the freezing to this method in the text_box_component.dart file:

      void _updateBoundsWithTextPainter(double availableWidth) {
        final textPaint = textRenderer as TextPaint;
        final textPainter = textPaint.toTextPainter(text);
        textPainter.layout(maxWidth: availableWidth);
    
        // Extract lines from the laid out text using line boundaries
        final lineMetricsList = textPainter.computeLineMetrics();
        var lineHeight = 0.0;
        var offset = 0;
    
        while (offset < text.length) { // CODE NEVER LEAVES THIS WHILE
          final range = textPainter.getLineBoundary(TextPosition(offset: offset));
          var lineText = text.substring(range.start, range.end);
    
          // Don't include the trailing newline character in the line text
          if (lineText.endsWith('\n')) {
            lineText = lineText.substring(0, lineText.length - 1);
          }
    
          lines.add(lineText);
    
          // Update max width based on actual line width
          final actualLineMetrics = textRenderer.getLineMetrics(lineText);
          _updateMaxWidth(actualLineMetrics.width);
    
          // Move to the next line
          offset = range.end;
          if (offset < text.length && text[offset] == '\n') {
            offset++; // Skip the newline character
          }
        }
    
        // Get line height from the metrics
        if (lineMetricsList.isNotEmpty) {
          lineHeight = lineMetricsList.first.height;
        }
    
        _lineHeight = lineHeight;
        _totalLines = lines.length;
      }

    I also discovered that it is not only that text that causes the issue, this also does: AAA AA AAA A A A.

    I am confidente that the issue is because of the classic JS number rouding issues, but I am still debugging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions