From 3059cf29943fe7b34ec0579aa7eaaa23c075a6dc Mon Sep 17 00:00:00 2001 From: Frotty Date: Sat, 29 Aug 2026 22:15:08 +0200 Subject: [PATCH] Update Wurst agent language guidance --- src/main/kotlin/file/SetupApp.kt | 2 +- templates/AGENTS.md | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/file/SetupApp.kt b/src/main/kotlin/file/SetupApp.kt index 618ebbf..f604632 100644 --- a/src/main/kotlin/file/SetupApp.kt +++ b/src/main/kotlin/file/SetupApp.kt @@ -33,7 +33,7 @@ object SetupApp { private data class WurstProcessResult(val exitCode: Int, val output: List) - internal const val AGENTS_TEMPLATE_VERSION = "2026-08-08" + internal const val AGENTS_TEMPLATE_VERSION = "2026-08-29" private const val AGENTS_TEMPLATE_MARKER_PREFIX = "" private const val AGENTS_TEMPLATE_SOURCE_HINT = "WurstScript Warcraft III map project notes" diff --git a/templates/AGENTS.md b/templates/AGENTS.md index 0fc22a9..72a9ef8 100644 --- a/templates/AGENTS.md +++ b/templates/AGENTS.md @@ -1,4 +1,4 @@ - + # AGENTS.md - WurstScript Map Project Notes WurstScript Warcraft III map project notes for editing `.wurst` code, dependencies, generated objects, tests, or map build logic. @@ -42,7 +42,19 @@ Read `scriptMode` before adding or removing `execute()` or timer chunking. Do no ## High-Risk Wurst Semantics -- Closures capture locals by value. Assigning inside a callback does not update the captured outer local. Keep creation and follow-up handlers in the same closure, store shared mutable state on an owning class, or use `reference(value)` and destroy it when finished. +- Prefer null-safe access (`?.`) when a missing receiver means no-op: the receiver is evaluated once and call arguments only when non-null. Keep an explicit check for null handling, primitive-valued results, or assignments. Example: `findTarget()?.damage(50.)`. +- Closures capture locals by value; callback assignments do not update the outer local. Inside a closure, `it` is that closure object, so use it for self-cancellation or cleanup instead of a temporary or `reference` used only to reach it: + + ```wurst + doPeriodically(0.25) -> + if isFinished() + destroy it + return + ``` + + `it` is not shared state; use an owning class or `reference(value)` for shared mutation, and destroy the reference when finished. +- Use `public readonly` for API fields callers may read but only the declaring class, module, or package may update, e.g. `public readonly int charges`. Unlike `constant`/`let`, the owner may update it repeatedly; visibility and write access are independent (`private readonly` hides reads). + - Wurst class lifetime remains explicit for Lua output. Objects created with `new`, stored closures/listeners, references, and owned collections usually need `destroy`; owners should clear stale references after destruction and must avoid double-destroy. - WC3 `int` is signed 32-bit and overflows silently. Promote before multiplication (`worth.toReal() * count`), never after an integer expression has already overflowed. - Lambdas require a known target type. Lambdas used as `code` cannot accept parameters or capture locals.