Chương 2: Bước Đầu Debug
Lý Minh mở mắt vì đói.
Cơn đói đủ mạnh để đánh thức giữa giấc ngủ sâu. Nhưng trước khi tìm thứ bỏ vào mồm, có việc quan trọng hơn.
Anh ta nhắm mắt. Mở.
Debug interface sáng ở góc dưới bên trái — đầy hơn hôm qua. Ở cuối danh sách, hai dòng mới:
> Input mode: AVAILABLE
> [?] for help
Ready for input.
Tôn lão tổ đã ở ngoài sân, nâng tách trà trên ghế tre. Thấy Lý Minh bước ra, lão gật đầu.
"Minh Nhi dậy rồi. Cháo trong nồi, tự mà múc."
Lý Minh múc cháo — vẫn loãng như hôm qua. Ngồi bậc cửa, vừa ăn vừa để mắt đến người đàn ông vác cuốc đi ngang.
Anh ta tập trung ánh nhìn. Debug interface phản hồi — chờ lệnh. Anh ta nghĩ đến [?].
> [scan] — Quét thực thể trong tầm nhìn
> [detail] — Chi tiết một thực thể
> [config] — Cấu hình
Ba lệnh. Feature-gated — nhiều lệnh hơn mở khi có quyền cao hơn.
Anh ta chọn [scan], nhắm vào người đàn ông vác cuốc.
> Thôn dân #0198 | 34 tuổi
> Linh lực: 0.11/∞ | Thể chất: 56/100
> Hiệu suất hấp thu: 0.00012 ĐV/giây | Linh căn: Không có
Hiệu suất 0.00012 đơn vị mỗi giây. Không có linh căn — vẫn hấp thu một chút từ môi trường, nhưng vô nghĩa.
Điều khiến anh ta chú ý nhất: dấu /∞. Hôm qua nó xuất hiện ở mọi thực thể — giờ dùng [scan] có chủ đích, anh ta xác nhận: tất cả đều hiển thị /∞ cho dung lượng tối đa.
Infinity. Không giới hạn? Hay hệ thống hiển thị mặc định khi max value quá lớn?
Anh ta chọn [detail], nhắm vào chính mình.
> SELF: Lý Minh (#163847) | 16 tuổi
> Linh lực: 0.00/∞ | Thể chất: 12/100
> Linh căn: Ngũ Hành Phế Linh Căn
> Hiệu suất hấp thu: 0.00000 ĐV/giây
> Kinh mạch: Tắc nghẽn 73%
Dòng 0.00000 đập vào mắt. Hiệu suất bằng không. Kinh mạch tắc nghẽn bảy mươi ba phần trăm.
Đây không phải build xấu. Đây là nhân vật bị lỗi tạo hình.
Nhưng Lý Minh không tuyệt vọng — anh ta tò mò. Hiệu suất bằng zero không phải vấn đề. Vấn đề là dấu /∞ lặp lại ở mọi sinh vật: hệ thống giới hạn linh lực ở con số nào?
Buổi trưa, Lý Minh ngồi dưới gốc cây sung đầu làng.
Cả buổi sáng, anh ta quét mọi thứ trong phạm vi. Tất cả hiển thị /∞. Infinity là rule, không phải ngoại lệ.
Khi anh ta suy nghĩ sâu hơn — muốn thấy cấu trúc bên trong — debug interface dao động. Rồi hiện ra:
> Data type (linh lực): INT32 | Signed: Yes
> Max: 2,147,483,647 | Min: -2,147,483,648
> Overflow behavior: UNKNOWN
Lý Minh đọc. Đọc lại. Đọc lần thứ ba.
Không cử động được trong năm giây.
Con số 2.147.483.647 không phải ngẫu nhiên. Không phải quy luật tu luyện. Không phải huyền bí.
2^31 − 1. Giới hạn trên của signed 32-bit integer.
Mọi lập trình viên đều biết con số này — giới hạn timestamp Unix, FAT32, độ dài chuỗi. Và ở đây — nó giới hạn lượng linh lực tích lũy trong một chu kỳ hấp thu.
Giải thích /∞ ở mọi thực thể: Infinity không phải "vô hạn" — là hiển thị mặc định khi max value quá lớn để hiển thị. Mọi thôn dân gần bằng zero — người mạnh nhất làng mới đi được 0.000000005% quãng đường.
Nhưng điều quan trọng nhất nằm ở dòng cuối.
Overflow behavior: UNKNOWN
UNKNOWN — hệ thống chưa xử lý khi giá trị vượt giới hạn.
Trong lập trình, UNKNOWN không có nghĩa an toàn. Nghĩa là "chưa ai test." Edge case mà hệ thống bỏ ngỏ. Và khi hệ thống dùng integer có dấu, maxValue, mà không xử lý overflow —
Integer overflow. 2.147.483.647 cộng một đơn vị thành −2.147.483.648. Từ dương cực đại nhảy sang âm cực đại.
Trong game, nó giết nhân vật. Trong server, nó crash database.
Ở đây — nếu mình đẩy linh lực vượt giới hạn...
Anh ta đứng dậy, bước qua bước lại dưới gốc cây.
Bug không tự nhiên mất. Nếu mày nhìn thấy bug, nó sẽ ở đó cho đến khi mày fix, hoặc nó fix mày.
Buổi chiều, anh ta thử một cách khác.
Tư duy lập trình viên: debug interface là tool, tool nào cũng có edge case. Injection.
> [detail] --self --override=1 --depth=max
> Warning: Deep scan may expose restricted data.
> Continue? [y/n]
Thành công thêm dữ liệu. Thất bại thêm anomaly entry. Đã có warning từ hôm qua.
> [y]
> Deep Scan — RESTRICTED
> Giới hạn hấp thu chu kỳ: 2,147,483,647
> [!] Overflow: UNKNOWN | Underflow: UNKNOWN
Con số nằm ở đây — trong thân thể anh ta. Giới hạn áp dụng cho mỗi chu kỳ. Vì INT32 là INT32 — dù lưu con mèo hay đại năng —
Mọi sinh vật trong thế giới này đều bị giới hạn bởi 2^31 − 1.
Đây không phải bug nhỏ. Đây là kiến trúc.
Thiên Đạo đã chọn INT32 cho linh lực. Hai tỷ đơn vị — dù mỗi giây hấp thu một đơn vị, cũng hơn sáu mươi tám năm. Hệ thống tin rằng không ai chạm được giới hạn.
Nhưng giới hạn vẫn ở đó. Và bug vẫn ở đó.
Làm sao mình vượt? Không thể hấp thu linh lực — Phế Linh Căn chặn trước khi bắt đầu. Bug trong bug: lỗi tạo hình chặn mình trước khi kịp exploit.
Anh ta cười khẽ — tiếng ngắn, khô, không thành tiếng.
Hoàng hôn nhuộm đỏ rặng núi. Lý Minh nằm trên giường tre.
Ngày đầu tiên ở thế giới mới, anh ta chết. Ngày thứ hai, anh ta học cách đọc.
Con số 2.147.483.647 không rời khỏi đầu. Bởi vì mọi lập trình viên đều biết: khi hệ thống dùng integer có dấu, có giới hạn, không xử lý overflow —
Bug không phải khả năng. Bug là tất yếu.
Vấn đề duy nhất: ai trigger nó, và khi nào.
Debug interface nhấp nháy ở góc tầm nhìn, mờ trong bóng tối. Màn hình chờ vẫn mở.
Nhưng bây giờ, người ngồi trước nó đã biết nên gõ gì.