Biến, Input và Bộ nhớ
Microbe Studio cho bạn bốn chỗ khác nhau để giữ một giá trị, và chúng khác nhau đúng một điều: giá trị sống bao lâu, và ai nhìn thấy nó. Chọn nhầm là nguyên nhân phổ biến nhất của "bộ đếm của tôi bị reset" và "hai instance của tôi giành nhau một giá trị".
Trang này vẽ bản đồ cả bốn.
Mục đích
Dùng trang này để quyết định, cho bất kỳ mẩu dữ liệu nào:
- Nó nên là biến hay mục bộ nhớ?
- Nó có cần sống qua lần chạy? Qua khởi động lại app? Instance khác có cần thấy nó?
- Người vận hành có nên gõ nó vào trước khi chạy?
Bốn ngôi nhà, nhìn nhanh
| Ngôi nhà | Sống trong | Ai thấy | Dùng điển hình |
|---|---|---|---|
Biến flow (scope: flow) | Một lần chạy | Chỉ lần chạy đó | Bộ đếm, trạng thái vòng lặp, kết quả OCR |
Biến Instance (scope: global) | Mãi mãi, qua khởi động lại | Mọi flow trên một instance | "Instance này đăng nhập tài khoản nào" |
| Runtime Memory | TTL theo từng mục, bạn chọn | Tùy scope bộ nhớ (dưới đây) | "Đừng đụng mục tiêu n ày thêm 15 phút" |
| Flow Input Parameter | Một lần chạy, cấp lúc khởi động | Lần chạy đó | "Chuyến này xử lý bao nhiêu mục" |
Biến flow
Biến flow được khai trong hộp thoại Variables của flow với đường dẫn (vars.gem_farmed_trip), kiểu, và giá trị mặc định tùy chọn.
Các kiểu
Các kiểu khai báo được:
string, number, boolean, point, rect, object, array, null
Mỗi kiểu trừ null có thêm biến thể nullable viết với ? cuối — number?, string?, v.v. Biến nullable được phép giữ null; biến không nullable thì không, và giá trị vi phạm khai báo sẽ từ chối khởi động lần chạy với TYPE_MISMATCH.
Khởi tạo thế nào
Ở đầu mỗi lần chạy, theo đúng thứ tự:
- Mọi biến khai báo được đặt
null. defaultValuecủa khai báo được áp nếu có.initialValuescủa flow được áp.- Mỗi giá trị được kiểm với kiểu khai báo.
- Bất kỳ giá trị nào vi phạm, lần chạy không khởi động.
Thứ tự này nghĩa là mặc định luôn thắng null, và initial value luôn thắng mặc định.
Đọc và ghi
Tham chiếu biến trong hầu hết ô chữ với một trong hai cú pháp — cả hai được chấp nhận và y hệt nhau:
{{gem_farmed_trip}}
${gem_farmed_trip}
Ghi biến bằng node Variable, chứa danh sách các dòng gán. Mỗi dòng có đích và thao tác:
| Thao tác | Hiệu ứng |
|---|---|
set | Định giá biểu thức và lưu kết quả |
clear | Trả biến về mặc định khai báo |
delete | Gỡ biến khỏi ngữ cảnh |
log | Ghi giá trị hiện tại vào log lần chạy (không đổi) |
Dòng set còn mang được expire after (ttlSeconds, tối đa một năm). Hết hạn thì giá trị hồi về mặc định của khai báo thay vì biến mất.
Cặp hai node hữu dụng nhất sản phẩm:
- Node Variable:
vars.items_done = {{items_done}} + 1 - Node If:
{{items_done}} >= {{max_per_trip}}
Cặp đó cho bạn "làm N lần, N cấp theo lần chạy" mà không cần node vòng lặp, và nó sống sót qua rẽ nhánh — điều một bộ đếm vòng lặp không làm được.
Biến Instance
Đặt scope: global trên khai báo — nhãn Instance trong UI — thay đổi hoàn toàn nơi lưu:
- Giá trị bền qua các lần chạy và qua khởi động lại app.
- Nó được chia sẻ bởi mọi flow chạy trên instance đó.
- Nó cách ly giữa các instance: instance A và B mỗi bên một bản.
Dùng cho sự thật về thiết bị, không phải về lần chạy. "Đăng nhập tài khoản nào", "instance này đã setup lần đầu chưa", "instance này ở server nào".
Vì sống qua khởi động lại, một biến Instance cũ kỹ sẽ âm thầm ảnh hưởng các lần chạy nhiều ngày sau. Cho chúng một đường reset chủ đích — một dòng clear trong flow setup — thay vì mặc định là khởi đầu sạch.
Flow Input Parameter
Đánh dấu khai báo là input và nó thành Flow Input Parameter: vẫn là biến thường bên trong flow, nhưng còn được đưa ra nhập liệu trước lần chạy.
- Người vận hành điền trên form Run Condition của Dashboard.
- Đánh dấu required chặn lần chạy nếu bỏ trống.
- Node Sub Flow gắn được biểu thức của cha vào input của con — truyền đối số thực thụ.
Đây là thứ biến flow thành hàm tái dùng:
Con khai thứ nó cần; cha cấp tại điểm gọi. Con không biết gì về bên gọi, nên cùng một con chạy được từ mục Queue, từ Lịch, hay từ ba cha khác nhau.
Runtime Memory
Biến trả lời "điều gì đúng ngay lúc này trong lần chạy này". Runtime Memory trả lời câu khác: "tôi đã xử lý thứ này chưa, và gần đây cỡ nào?"
Nó là kho key/value đa mục với TTL theo từng mục, được node Runtime Memory ghi và node Memory Match truy vấn.
Bốn scope bộ nhớ
Đây là phần đáng học cho chính xác:
| Scope | Sống qua kết thúc lần chạy | Sống qua khởi động lại app | Chia sẻ giữa instance |
|---|---|---|---|
run | Không | Không | Không |
session | Có | Không — một lần mở app | Không — riêng từng instance |
persist | Có | Có | Không — riêng từng instance |
shared | Có | Có | Có — scope liên-instance duy nhất |
runsống trên ngữ cảnh thực thi của lần chạy. Biến mất cùng lần chạy.sessionnghĩa là "lần mở app này". Mở mới bắt đầu rỗng.persistlưu SQLite, an toàn qua khởi động lại.sharedlà opt-in chủ đích duy nhất cho phối hợp liên-instance. Mọi scope khác đặt namespace mục theo instance, nên instance A không bao giờ đọc/đè bộ nhớ của instance B.
shared chia sẻ thật sựMười instance ghi cùng một khóa trong scope shared sẽ đè lên nhau. Chỉ dùng khi phối hợp liên-instance chính là mục đích — ví dụ danh sách "mục tiêu này có người nhận" toàn cục. Thứ gì theo thiết bị, dùng persist.
Khuôn mẫu chốt-chặn-cooldown
Cách dùng kinh điển của Runtime Memory: đừng xử lý lại thứ vừa xử lý gần đây.
Memory Match so ứng viên với mọi mục còn sống bằng biểu thức có thể tham chiếu mục đang xét là {{item.<trường>}}:
(abs({{current_x}} - {{item.x_coordinate}}) <= 1) && (abs({{current_y}} - {{item.y_coordinate}}) <= 1)
Đọc là "có mục đã nhớ nào trong vòng một ô quanh chỗ tôi đứng không?" — so khớp dung sai, không phải bằng tuyệt đối, đúng thứ dữ liệu màn hình thật cần.
Vì mục mang TTL 900 giây, chốt chặn tự hết hạn sau 15 phút. Không gì phải dọn.
Các thao tác bộ nhớ
| Thao tác | Làm gì | Cần key |
|---|---|---|
remember | Thêm mục (key trống tự sinh) | Không |
forget | Gỡ một mục theo key | Có |
clear | Dọn cả bộ nhớ | Không |
count | Ghi số mục còn sống vào biến | Không |
Chọn thế nào: bảng quyết định
| Bạn muốn… | Dùng |
|---|---|
| Đếm lượt trong một lần chạy | Biến flow |
| Truyền một con số trước khi chạy | Flow Input Parameter |
| Nhớ giả lập này dùng tài khoản nào | Biến Instance |
| Tránh ghé lại mục tiêu trong 15 phút | Runtime Memory, persist, TTL |
| Chỉ tránh ghé lại trong lần chạy này | Runtime Memory, run |
| Cho mọi instance né một danh sách chung | Runtime Memory, shared |
Best practices
- Khai báo mọi biến bạn dùng. Tham chiếu chưa khai hỏng lúc khởi động thay vì giữa chừng — đó là kiểu hỏng bạn muốn.
- Cho bộ đếm mặc định
0, không phảinull.null + 1không phải con số. - Dùng
number?cho mọi thứ OCR ghi. Lần đọc hỏng không sinh giá trị, và khai báo không-nullable sẽ từ chối nó. - Ưu tiên TTL hơn dọn tay. Mục tự hết hạn không thể rò rỉ.
- Đặt tên input theo quyết định nó điều khiển —
max_per_trip, không phảin. - Reset bộ đếm chuyến ở ranh giới tự nhiên, không phải đầu vòng lặp. Trong automation tham chiếu, bộ đếm reset khi flow quay về căn cứ — điểm "một chuyến" thực sự kết thúc.
Ghi chú hiệu năng
- Đọc biến và định giá biểu thức nằm trong bộ nhớ, gần như miễn phí. Đừng né biến vì lý do hiệu năng.
- Thao tác bộ nhớ
persistvàsharedchạm SQLite. Nhanh, nhưng là I/O — tránh đặtremembertrong vòng lặp trong siết chạy trăm lần mỗi giây. countquét các mục sống của bộ nhớ. Bộ nhớ lớn thì tự duy trì một biến đếm sẽ hơn.
Ghi chú bộ nhớ
- Mỗi session mang bản sao riêng của mọi biến flow. Một flow chạy trên 10 instance nghĩa là 10 bộ biến độc lập.
- Runtime Memory scope
rungiữ trên ngữ cảnh thực thi và giải phóng khi lần chạy kết thúc. - Scope
sessionlưu trong CSDL chung dưới token theo lần mở app; app thu hồi các hàng của lần mở trước lúc khởi động, nên nó không phình vô hạn. - Mục bộ nhớ hết hạn theo thời gian tuyệt đối, nên mục ghi TTL 900 giây vẫn hết hạn sau khởi động lại — thời hạn được lưu, không phải đếm ngược trong RAM.
Lỗi thường gặp
| Lỗi | Triệu chứng | Cách sửa |
|---|---|---|
| Bộ đếm khai không mặc định | Phép cộng chẳng ra gì | Mặc định 0 |
| Biến không-nullable gắn kết quả OCR | Lần chạy từ chối TYPE_MISMATCH | Khai number? / string? |
Dùng bộ nhớ shared cho trạng thái theo máy | Instance đè lên nhau | Dùng persist |
Mong session sống qua khởi động lại | Rỗng sau mở lại | Dùng persist |
| Reset bộ đếm chuyến ở đầu vòng | Không bao giờ chạm ngưỡng | Reset ở ranh giới chuyến |
| Coi biến Instance khởi đầu sạch | Giá trị mốc từ nhiều ngày trước | Clear tường minh trong setup |
Khắc phục sự cố
Bộ đếm của tôi mãi là 1.
Node Variable đang reset thay vì tăng. Kiểm biểu thức là {{x}} + 1 chứ không phải 1.
Lần chạy từ chối khởi động với TYPE_MISMATCH.
Một mặc định hoặc initial value lệch kiểu khai. Thường là đích OCR nullable bị khai non-nullable.
Memory Match không bao giờ khớp.
Kiểm scope trên cả hai node — remember scope run vô hình với match đọc persist. Xác nhận luôn tên trường trong biểu thức khớp trường bạn đã lưu.
Hai instance cứ né việc của nhau.
Chúng chia một bộ nhớ scope shared. Chuyển sang persist để cách ly theo thiết bị.
FAQ
{{name}} khác ${name} không?
Không. Cả hai được chấp nhận, hành xử y hệt. Chọn một và nhất quán.
Sub Flow đổi được biến của cha không? Con nhận input đã gắn làm biến cục bộ của nó. Truyền kết quả ngược bằng trạng thái kết thúc của con, hoặc một scope bộ nhớ chia sẻ.
Biến hết TTL thì thành gì?
Hồi về giá trị mặc định khai báo — không thành null trừ khi mặc định là vậy.
Biến Instance có đồng bộ giữa các máy tính? Không. Cục bộ với instance trên bản cài đó.
Trang liên quan
- Mô hình thực thi — ngữ cảnh các giá trị này sống trong
- Giải phẫu Flow — khai báo được lưu ở đâu
- Node Variable — node ghi chúng
- Node Runtime Memory — bên ghi bộ nhớ
- Node Memory Match — bên đọc bộ nhớ
- Node Sub Flow — truyền đối số