Skip to main content

Lint rules

Generated page

This page is generated from packages/eslint-plugin-reforged/docs, packages/eslint-plugin-reforged/src/rules/index.ts by docs:collect. Edit the source, not this page.

eslint-plugin-reforged is the lint layer of the Guards: type-aware rules that report the Warcraft III scripting pitfalls (desync, crash, leak) in the editor and in CI, before the map compiles. Its recommended config sets every rule below, and each diagnostic links to its rule's page here. Its README sets the plugin up, and Desync safety and guards says what the lint catches next to the type layer and the runtime Guards.

To silence a rule on one line, say why after --:

// eslint-disable-next-line reforged/<rule> -- <why the code is safe here>

Rules​

  • no-async-value-as-state: Reports a value that differs between clients (an @async Native or library member, or Lua's os.clock, os.time, os.date, os.difftime) that flows into game state: a call argument, a module-level variable or a table key. A warning in the recommended config; share the value through the sync System (SyncRequest) first, or use it only in a text or visual call.
  • no-dotted-asset-paths: Reports an asset path whose file name holds a dot before its extension (my_model_1.0.mdx), which the game does not read since 3.0.0. An error in the recommended config; the replacement is the file renamed with underscores (my_model_1_0.mdx).
  • no-game-state-in-local-branch: Reports a call that may change game state inside a branch that runs for the local player only: a Native or a Wrapper member that the plugin's allowlist does not list as visual, a creation, Filter/Condition, ForGroup/ForForce, and a random-number call. An error in the recommended config; keep the game-state change outside the branch, for every player, and only the visuals inside it.
  • no-handle-id-as-data: Reports a call to GetHandleId and a read of a Wrapper's id accessor whose value does not reach a text-display Native. A warning in the recommended config; key by the Handle or Wrapper itself instead.
  • no-handles-at-module-top-level: Reports a creation at module top level: a Wrapper's create* static (Unit.create, Effect.createAttachment) or a creation Native (CreateTimer, CreateUnit, AddSpecialEffect, Location, ...) that runs when the module loads. An error in the recommended config; create the object in an Init.onGlobals callback, or a later Init stage.
  • no-legacy-w3ts-names: Reports a w3ts 3.x name that reforged-ts renamed or removed: an import from w3ts, an imported export, a member or static access on a library class, and a new of a library class; and the w3ts use of a member that kept its name but not its signature. An error in the recommended config; the message gives the replacement and why the name changed. One-to-one renames are fixed automatically.
  • no-percent-in-display-strings: Reports a string literal or template with a lone % that reaches a text-display Native (DisplayTextToPlayer, BJDebugMsg, print, the frame text setters and their library members). A warning in the recommended config; the suggestion writes %%, which the game displays as %.
  • no-self-recursion: Reports a function that calls itself by name in its own body: a function declaration, a function expression, an arrow bound by const, or a method through this (or its class, for a static method). A warning in the recommended config; the replacement is a loop, or a depth bound the author has checked.
  • no-unordered-iteration: Reports the iteration that typescript-to-lua compiles to Lua's pairs, whose order differs between clients: for...in, Object.keys, Object.values, Object.entries, direct calls to pairs and next, and for...of over a LuaTable, LuaMap or LuaSet. A warning in the recommended config; the replacement is a SyncedMap or SyncedSet for a keyed collection, or for...of over an array.
  • no-unsafe-natives: Reports a call to a Native on the plugin's ban list: the ones that kill the thread, leak or desync (TriggerSleepAction, PolledWait, TriggerWaitForSound, DestroyEffectAfterTimeBJ, the BJ timer helpers, SelectGroupForPlayerBJ, SmartCameraPanBJ). An error in the recommended config; the message gives the reason and the replacement.
  • no-unused-handle-result: Reports an expression statement that discards a creation (Unit.create(...), CreateTimer(), AddSpecialEffect(...)) or a Filter(...)/Condition(...) boolexpr. An error in the recommended config; keep the reference and destroy the object when it is no longer needed.
  • prefer-handle-map: Reports new Map and new Set whose key type is a Wrapper (Map<Unit, number>, Set<Effect>), whether written or inferred. A warning in the recommended config; the suggestion changes the constructor to HandleMap/HandleSet.