From API reference to a testable result
Using Callable: prerequisites, expected output, deferred calls and a freed target.
Check a new API with a small task
Example task: perform a calculation through Callable, then update a label later. If the Label is freed before the queue runs, the callback must not access the freed object. These are concrete outcomes that can be checked separately from the rest of the game.
1. Use the complete example
Open Callable.Call and save the article’s complete CallableSignalExamples.cs file in your C# project. It is a static helper class; do not attach it to an Entity. In an existing Entity script, for example inside _Ready, call:
ReckfellApi.Print(CallableSignalExamples.Twice(21));Build C# and run the document. The expected output is 42. Obtain that result before modifying the example. If the class is missing, check the saved file, namespace and build errors; if _Ready is not called, check script attachment and which document is running.
2. Read the contract before editing
Check the selected overload’s argument and return types. Twice converts its local argument to Variant, Call returns Variant and the result is read as int. CallDeferred has no result: it only queues a call. Substituting one method for the other changes behavior even with identical inputs.
SetLabelLater in the same file checks IsInstanceValid immediately before accessing the Label. A check only at queue time is insufficient: the object can be freed between those actions.
3. Check ordinary and boundary cases
| Check | Expected result |
|---|---|
| Twice(21) | 42 |
| SetLabelLater with a live Label | Text changes when the queue runs, not synchronously |
| Label freed before the queue runs | The handler does not change the freed object |
| Await the next ProcessFrame | Continuation after the next signal emission |
Signal.GetAwaiter explains waiting. Freeing the signal owner does not promise automatic await completion; it is a separate case, not proof of a successful operation.
Then integrate into your project
Change one part: an input value, handler or target object. Repeat ordinary and boundary checks after each change. Do not start by porting an entire project or rewriting a large class.
If results differ, retain the minimal document, complete participating script, action sequence, expected result, first error and engine version. Include object names and parents to reproduce paths. This is more useful than a screenshot of the final error alone.
For an unfamiliar signature, see reading the C# reference; for a broken project, see troubleshooting.