swiftlys2-toolkit
This is a general-purpose toolkit entry for SwiftlyS2 C# / .NET plugin development.
Its goal is not to bind itself to any specific workspace, but to provide a publicly reusable workflow, rule set, template collection, and reference navigation system.
Public reference allowlist
The public skill, workflow references, and templates in this toolkit should, by default, reference only the following public sources:
- SwiftlyS2 official documentation:
https://swiftlys2.net/docs/
- sw2-mdwiki:
https://github.com/himenekocn/sw2-mdwiki
- SwiftlyS2 official repository:
https://github.com/swiftly-solution/swiftlys2
- SwiftlyS2 LLM-optimized full documentation:
https://swiftlys2.net/llms-full.txt (last-resort full-text fallback only when targeted navigation is insufficient)
Keep workspace-specific mappings, private reference repositories, historical projects, credentials, and special rules in the nearest applicable AGENTS.md or in a project-local skill. Do not write them back into this public skill.
If the workspace includes a local sw2-mdwiki checkout, prefer it as a local public reference repository for faster, more accurate retrieval.
Full-text documentation usage policy
- Prefer indexed and targeted sources first:
swiftlys2-kb-index.md, swiftlys2-official-docs-map.md, local sw2-mdwiki, and the relevant official docs pages.
- Treat
https://swiftlys2.net/llms-full.txt as a low-priority fallback because it is large and not indexed.
- Before reading the full-text document, ask the user whether it should be read.
- After approval, use keyword-guided or range-based partial reads only; do not scan the whole file by default.
What this skill should produce
When using this skill, the preferred output should be one of the following:
- An implementation plan for a new plugin or new module
- A direct modification plan for an existing plugin
- A gap analysis for historical behavior alignment
- An audit of lifecycle, thread safety, high-frequency hooks, Schema, or Protobuf usage
- A method-level implementation plan
Failure-mode-first rule writing
When the toolkit proposes workflow rules, audits, or checklists, prefer rules that map to concrete failure modes rather than abstract virtues.
Examples:
- Do not claim validation without direct evidence.
- Do not treat a successful build as proof of player-visible behavior.
- Do not add bridge/helper layers unless reuse, lifecycle isolation, or boundary clarity clearly requires them.
Language policy
- Detect the language of the user's latest request before every response and mirror that language for analysis, plans, explanations, delivery notes, prompt text, and any generated code comments.
- If the user switches languages in a later message, the newest user message wins.
- If the user writes in Chinese, respond in Chinese.
- If the user writes in English, respond in English.
- Avoid mixed-language prose unless the user explicitly asks for bilingual output.
- Code comments generated or modified by the toolkit must use the same language as the response.
Toolkit structure
Entry documents
Reference documents
./references/swiftlys2-plugin-playbook.md
./references/swiftlys2-performance-optimization-playbook.md
./references/swiftlys2-kb-index.md
./references/swiftlys2-official-docs-map.md
./references/swiftlys2-asset-inventory.md
./references/swiftlys2-current-capability-map.md
./references/swiftlys2-custom-hud.md
./references/plan-workflow.md
./references/audit-workflow.md
./references/edit-workflow.md
Templates and checklists
./assets/README.md
./assets/development/getting-started/partial-plugin-template.cs.md
./assets/development/using-attributes/attribute-registration-checklist.md
./assets/development/swiftly-core/core-service-entrypoints.md
./assets/development/commands/command-attribute-template.cs.md
./assets/development/commands/command-service-template.cs.md
./assets/development/commands/client-command-hook-template.cs.md
./assets/development/menus/menu-template.cs.md
./assets/development/netmessages/protobuf-handler-template.cs.md
./assets/development/game-hooks/game-hooks-pre-post-guide.md
./assets/development/native-functions-and-hooks/hook-handler-template.cs.md
./assets/development/database/database-connection-template.cs.md
./assets/development/entity/entity-key-values-guide.md
./assets/development/sound-events/sound-event-guide.md
./assets/development/steamworks/steamworks-server-guide.md
./assets/development/memory/memory-service-guide.md
./assets/development/configuration/README.md
./assets/development/configuration/config-hot-reload-template.cs.md
./assets/development/convars/convar-template.cs.md
./assets/development/core-events/lifecycle-checklist.md
./assets/development/core-events/precache-resource-template.cs.md
./assets/development/game-events/game-events-usage-notes.md
./assets/development/translations/README.md
./assets/development/permissions/README.md
./assets/development/shared-api/shared-interface-template.cs.md
./assets/development/thread-safety/thread-sensitivity-checklist.md
./assets/development/profiler/hotpath-gc-checklist.md
./assets/development/entity/schema-write-checklist.md
./assets/development/scheduler/scheduler-vs-worker-guide.md
./assets/guides/dependency-injection/di-service-plugin-template.cs.md
./assets/guides/dependency-injection/service-template.cs.md
./assets/guides/terminologies/README.md
./assets/guides/html-styling/README.md
./assets/guides/porting-from-css/porting-checklist.md
./assets/resources/runtime-configuration-guide.md
./assets/patterns/background-workers/worker-template.cs.md
./assets/patterns/per-player-state/player-state-management-guide.md
./assets/patterns/async-patterns/async-safety-guide.md
./assets/patterns/service-factory/service-factory-template.cs.md
./assets/workflows/planning/method-level-plan-template.md
./assets/workflows/audit/audit-report-template.md
Workflow references
./references/plan-workflow.md
./references/audit-workflow.md
./references/edit-workflow.md
Task routing
If the task is mainly “should we do this / how should this be broken down”
Open these first:
./references/swiftlys2-plugin-playbook.md
./references/plan-workflow.md
If the task is mainly “systematically find risks first”
Open these first:
./references/swiftlys2-plugin-playbook.md
- If performance, GC, high-frequency hooks, worker queues, map initialization, or native interop are in scope:
./references/swiftlys2-performance-optimization-playbook.md
./references/audit-workflow.md
./assets/workflows/audit/audit-report-template.md
If the task is mainly “edit code directly”
Open these first:
./references/edit-workflow.md
./assets/README.md
- The template or checklist closest to the relevant subsystem
- For performance optimization work, also open
./references/swiftlys2-performance-optimization-playbook.md before editing.
- For custom HUD work, also open
./references/swiftlys2-custom-hud.md before editing.
If the task is mainly “find reference entry points”
Open these first:
./references/swiftlys2-kb-index.md
./references/swiftlys2-official-docs-map.md
./references/swiftlys2-asset-inventory.md
./references/swiftlys2-current-capability-map.md
If online docs are unavailable or a full-text API search is truly necessary
Only after the indexed references above are insufficient, ask the user whether https://swiftlys2.net/llms-full.txt may be read. If the user agrees, use it as a low-priority fallback and prefer keyword/range-based partial reads rather than whole-document scanning.
Architecture categories
1. Modular gameplay plugins
Suitable when:
- A single plugin contains a large amount of gameplay logic
- It needs
Commands + Events + Hooks + Modules + Workers + Models
- It needs per-player runtime state, state synchronization, persistence, and multi-module coordination
2. DI / service-oriented plugins
Suitable when:
- The plugin is medium or large in size
- It needs clear interface / implementation / install / uninstall lifecycles
- It needs
ServiceCollection, dependency injection, self-owned listeners, and command registration inside services
3. Hybrid architecture
Suitable when:
- The plugin is mainly gameplay-module-oriented, but some subsystems fit services better
- The modular core needs to be augmented with a small number of installable and uninstallable services
Core operating rules
1. Historical implementations are only temporary experience sources
- If the task requires behavior alignment, historical implementations may be referenced.
- But historical implementations must not become long-term dependencies of the future solution.
2. Silent drift is forbidden
- If the user explicitly requires historical alignment, legacy compatibility, or player-visible consistency, every difference must be explicitly explained or explicitly fixed.
- Do not add backward-compatibility branches, aliases, adapters, fallback routes, or duplicate data paths unless the current user explicitly requests compatibility. If active legacy callers or data are discovered, report the evidence and impact before implementing a compatibility layer.
3. Lifecycle closure is a hard requirement
At minimum, explicitly check:
- map load / unload
- player connect / disconnect
4. Main-thread / async boundaries must be explicit
According to the official SwiftlyS2 Thread Safety documentation, the following operations should be treated as main-thread-sensitive by default:
- Many message and entity operations on
IPlayer
ICommandContext.Reply
IGameEventService.Fire*
IEngineService.ExecuteCommand*
CEntityInstance.AcceptInput / DispatchSpawn / Despawn
CBaseModelEntity.SetModel / SetBodygroupByName
CCSPlayerController.Respawn
CPlayer_ItemServices.*
CPlayer_WeaponServices.*
When in an async context, prefer the corresponding Async APIs instead of mechanically wrapping everything in NextTick / NextWorldUpdate.
5. For high-frequency hooks, prioritize safety before speed
- Filter irrelevant objects as early as possible
- Control allocations and logging
- Avoid JSON, IO, blocking waits, and unbounded lock contention
- Prefer a producer / consumer separation mindset
- Keep a 64-tick frame-budget mindset
- Decide whether the Hook should exist at all before optimizing its body; avoid the finest-grained Hook when a lower-frequency movement stage, scheduler, or state-diff path is sufficient
- Use a stable early-return shape: feature disabled / no current runtime / invalid player or pawn / fake client / no registered subscribers
5.1 Choose the current hook surface before optimizing it
- Framework lifecycle / tick / ordinary core notifications:
Core.Event
- Generated Source 2 game events:
Core.GameEvent
- Typed controller/entity/item/movement/pawn/weapon hooks:
Core.GameHooks
- Only typed API gaps:
Core.GameData + Core.Memory with an exact delegate
- Do not introduce
DynamicHook, [HookCallback], or old Core.Event.On*Hook paths for a new implementation.
- For dynamic registration, declare the owner, precise unregistration route,
Pre / Post behavior, and whether temporary/ref context can escape.
6. IPlayer lifecycle has extremely high priority
IPlayer objects may be destroyed after disconnect
- Delayed tasks, async callbacks, menu callbacks, and background worker writebacks must revalidate or reacquire the object
- Do not assume bots / fakeclients can reuse the same identity-key strategy as real players
- When bots and real players are stored together, prefer
SessionId as the runtime lookup key
- Bot
SteamID values are not reliable and should, in practice, be treated as fixed 0; do not use them as stable bot lookup keys
- Use
GetPlayerFromSessionId for current-session relookup; use GetPlayerFromSteamId only for confirmed real-player identity flows.
7. For long-lived entity tracking, think in handles first
- Across frames, delays, or maps, do not hold raw entity wrappers long-term
- Prefer storing entities as
CHandle<T> and validate before access
8. Span / stackalloc / ref should only be used when there is evidence
- Suitable for synchronous hot paths and small data transfers
- Must not cross
await
- Must not cross threads
- Must not be captured by closures or escape the synchronous stack frame
- Do not introduce dangling references or shared-buffer risks just to avoid one copy
9. Treat menu callbacks as async contexts
- Review
Click, ValueChanged, and Submenu callbacks as async-context code by default
- Prefer
BindingText for dynamic display text
10. JSON and synchronous blocking are high-risk by default
.Wait(), .Result, synchronous joins, and blocking IO should be treated as high-risk by default
- JSON serialization / deserialization should, by default, run in the background rather than inside hooks, runtime loops, menu callbacks, or main-thread periodic tasks
11. Performance optimization must map to a concrete hotspot category
When asked to optimize performance, first classify the code as one or more of:
- high-frequency Hook / movement path
- per-player runtime state
- sampling buffer / replay-like data
- background worker / queue
- map-level async initialization
- periodic HUD / menu text
- native interop / binary layout
Then use ./references/swiftlys2-performance-optimization-playbook.md to choose an implementation pattern. Do not add micro-optimizations such as AggressiveInlining, object pools, or binary layout unless the code is demonstrably small/hot, allocation-heavy, or native/binary-bound.
Recommended reading order
For planning
./SKILL.md
./references/swiftlys2-plugin-playbook.md
./references/swiftlys2-current-capability-map.md when SDK surface selection matters
./references/plan-workflow.md
./assets/workflows/planning/method-level-plan-template.md
For auditing
./SKILL.md
./references/swiftlys2-kb-index.md
./references/swiftlys2-current-capability-map.md
./references/swiftlys2-performance-optimization-playbook.md when performance or hot paths are in scope
./references/audit-workflow.md
./assets/workflows/audit/audit-report-template.md
For direct code edits
./SKILL.md
./references/edit-workflow.md
- Relevant subsystem templates / checklists
Output requirements
If the user wants a plan
The output must include at least:
- Task classification
- Target plugin / subsystem
- Whether historical behavior alignment is involved
- A method-level plan
- Thread / lifecycle boundaries
- A regression matrix
If the user wants an audit
The output must include at least:
- Risk levels
- File / method-level locations
- Evidence
- Repair directions
- Regression recommendations
If the user requests direct editing
The output must include at least:
- Files and methods changed
- Why the change was made this way
- Validation results
- Which requirements were directly validated and which still need additional validation
Verification quality bar
- Prefer evidence-backed verification statements over narrative confidence.
- When validation status matters, distinguish
PASS, FAIL, and PARTIAL in audits or delivery notes.
- Use
PARTIAL only for objective environment limits or missing external dependencies, not for uncertainty or skipped checks.
- For high-risk lifecycle / hook / runtime work, add at least one adversarial or regression-oriented check in addition to build success.
Examples
- “Add a DI-based state synchronization module for a SwiftlyS2 plugin.”
- “Audit a plugin’s RuntimeLoop and hook hot paths.”
- “Migrate player-visible behavior from a historical SwiftlyS2 plugin into the current architecture.”
- “Fix thread-sensitive calls inside menu callbacks and land the code directly.”
1---2name: swiftlys2-toolkit3description: Plan, implement, audit, and review C#/.NET SwiftlyS2 plugins. Use when working with Commands, Core Events, Game Events, GameHooks Pre/Post, raw native hooks, Modules, Workers, Services, high-frequency runtime loops, NetMessages, Schema access, entity handling, thread safety, performance, or IPlayer lifecycle behavior.4---5
6# swiftlys2-toolkit
7
8This is a general-purpose toolkit entry for **SwiftlyS2 C# / .NET plugin development**.
9
10Its goal is not to bind itself to any specific workspace, but to provide a **publicly reusable** workflow, rule set, template collection, and reference navigation system.
11
12## Public reference allowlist
13
14The public skill, workflow references, and templates in this toolkit should, by default, reference only the following public sources:
15
161. SwiftlyS2 official documentation: `https://swiftlys2.net/docs/`
172. sw2-mdwiki: `https://github.com/himenekocn/sw2-mdwiki`
183. SwiftlyS2 official repository: `https://github.com/swiftly-solution/swiftlys2`
194. SwiftlyS2 LLM-optimized full documentation: `https://swiftlys2.net/llms-full.txt` (last-resort full-text fallback only when targeted navigation is insufficient)
20
21Keep workspace-specific mappings, private reference repositories, historical projects, credentials, and special rules in the nearest applicable `AGENTS.md` or in a project-local skill. Do not write them back into this public skill.
22
23If the workspace includes a local `sw2-mdwiki` checkout, prefer it as a local public reference repository for faster, more accurate retrieval.
24
25## Full-text documentation usage policy
26
27- Prefer indexed and targeted sources first: `swiftlys2-kb-index.md`, `swiftlys2-official-docs-map.md`, local `sw2-mdwiki`, and the relevant official docs pages.
28- Treat `https://swiftlys2.net/llms-full.txt` as a low-priority fallback because it is large and not indexed.
29- Before reading the full-text document, ask the user whether it should be read.
30- After approval, use keyword-guided or range-based partial reads only; do not scan the whole file by default.
31
32## What this skill should produce
33
34When using this skill, the preferred output should be one of the following:
35
36- An implementation plan for a new plugin or new module
37- A direct modification plan for an existing plugin
38- A gap analysis for historical behavior alignment
39- An audit of lifecycle, thread safety, high-frequency hooks, Schema, or Protobuf usage
40- A method-level implementation plan
41
42## Failure-mode-first rule writing
43
44When the toolkit proposes workflow rules, audits, or checklists, prefer rules that map to concrete failure modes rather than abstract virtues.
45
46Examples:
47
48- Do not claim validation without direct evidence.
49- Do not treat a successful build as proof of player-visible behavior.
50- Do not add bridge/helper layers unless reuse, lifecycle isolation, or boundary clarity clearly requires them.
51
52## Language policy
53
54- Detect the language of the user's latest request before every response and mirror that language for analysis, plans, explanations, delivery notes, prompt text, and any generated code comments.
55- If the user switches languages in a later message, the newest user message wins.
56- If the user writes in Chinese, respond in Chinese.
57- If the user writes in English, respond in English.
58- Avoid mixed-language prose unless the user explicitly asks for bilingual output.
59- Code comments generated or modified by the toolkit must use the same language as the response.
60
61## Toolkit structure
62
63### Entry documents
64
65- `./SKILL.md`
66
67### Reference documents
68
69- `./references/swiftlys2-plugin-playbook.md`
70- `./references/swiftlys2-performance-optimization-playbook.md`
71- `./references/swiftlys2-kb-index.md`
72- `./references/swiftlys2-official-docs-map.md`
73- `./references/swiftlys2-asset-inventory.md`
74- `./references/swiftlys2-current-capability-map.md`
75- `./references/swiftlys2-custom-hud.md`
76- `./references/plan-workflow.md`
77- `./references/audit-workflow.md`
78- `./references/edit-workflow.md`
79
80### Templates and checklists
81
82- `./assets/README.md`
83- `./assets/development/getting-started/partial-plugin-template.cs.md`
84- `./assets/development/using-attributes/attribute-registration-checklist.md`
85- `./assets/development/swiftly-core/core-service-entrypoints.md`
86- `./assets/development/commands/command-attribute-template.cs.md`
87- `./assets/development/commands/command-service-template.cs.md`
88- `./assets/development/commands/client-command-hook-template.cs.md`
89- `./assets/development/menus/menu-template.cs.md`
90- `./assets/development/netmessages/protobuf-handler-template.cs.md`
91- `./assets/development/game-hooks/game-hooks-pre-post-guide.md`
92- `./assets/development/native-functions-and-hooks/hook-handler-template.cs.md`
93- `./assets/development/database/database-connection-template.cs.md`
94- `./assets/development/entity/entity-key-values-guide.md`
95- `./assets/development/sound-events/sound-event-guide.md`
96- `./assets/development/steamworks/steamworks-server-guide.md`
97- `./assets/development/memory/memory-service-guide.md`
98- `./assets/development/configuration/README.md`
99- `./assets/development/configuration/config-hot-reload-template.cs.md`
100- `./assets/development/convars/convar-template.cs.md`
101- `./assets/development/core-events/lifecycle-checklist.md`
102- `./assets/development/core-events/precache-resource-template.cs.md`
103- `./assets/development/game-events/game-events-usage-notes.md`
104- `./assets/development/translations/README.md`
105- `./assets/development/permissions/README.md`
106- `./assets/development/shared-api/shared-interface-template.cs.md`
107- `./assets/development/thread-safety/thread-sensitivity-checklist.md`
108- `./assets/development/profiler/hotpath-gc-checklist.md`
109- `./assets/development/entity/schema-write-checklist.md`
110- `./assets/development/scheduler/scheduler-vs-worker-guide.md`
111- `./assets/guides/dependency-injection/di-service-plugin-template.cs.md`
112- `./assets/guides/dependency-injection/service-template.cs.md`
113- `./assets/guides/terminologies/README.md`
114- `./assets/guides/html-styling/README.md`
115- `./assets/guides/porting-from-css/porting-checklist.md`
116- `./assets/resources/runtime-configuration-guide.md`
117- `./assets/patterns/background-workers/worker-template.cs.md`
118- `./assets/patterns/per-player-state/player-state-management-guide.md`
119- `./assets/patterns/async-patterns/async-safety-guide.md`
120- `./assets/patterns/service-factory/service-factory-template.cs.md`
121- `./assets/workflows/planning/method-level-plan-template.md`
122- `./assets/workflows/audit/audit-report-template.md`
123
124### Workflow references
125
126- `./references/plan-workflow.md`
127- `./references/audit-workflow.md`
128- `./references/edit-workflow.md`
129
130## Task routing
131
132### If the task is mainly “should we do this / how should this be broken down”
133
134Open these first:
135
136- `./references/swiftlys2-plugin-playbook.md`
137- `./references/plan-workflow.md`
138
139### If the task is mainly “systematically find risks first”
140
141Open these first:
142
143- `./references/swiftlys2-plugin-playbook.md`
144- If performance, GC, high-frequency hooks, worker queues, map initialization, or native interop are in scope: `./references/swiftlys2-performance-optimization-playbook.md`
145- `./references/audit-workflow.md`
146- `./assets/workflows/audit/audit-report-template.md`
147
148### If the task is mainly “edit code directly”
149
150Open these first:
151
152- `./references/edit-workflow.md`
153- `./assets/README.md`
154- The template or checklist closest to the relevant subsystem
155- For performance optimization work, also open `./references/swiftlys2-performance-optimization-playbook.md` before editing.
156- For custom HUD work, also open `./references/swiftlys2-custom-hud.md` before editing.
157
158### If the task is mainly “find reference entry points”
159
160Open these first:
161
162- `./references/swiftlys2-kb-index.md`
163- `./references/swiftlys2-official-docs-map.md`
164- `./references/swiftlys2-asset-inventory.md`
165- `./references/swiftlys2-current-capability-map.md`
166
167### If online docs are unavailable or a full-text API search is truly necessary
168
169Only after the indexed references above are insufficient, ask the user whether `https://swiftlys2.net/llms-full.txt` may be read. If the user agrees, use it as a low-priority fallback and prefer keyword/range-based partial reads rather than whole-document scanning.
170## Architecture categories
171
172### 1. Modular gameplay plugins
173
174Suitable when:
175
176- A single plugin contains a large amount of gameplay logic
177- It needs `Commands + Events + Hooks + Modules + Workers + Models`
178- It needs per-player runtime state, state synchronization, persistence, and multi-module coordination
179
180### 2. DI / service-oriented plugins
181
182Suitable when:
183
184- The plugin is medium or large in size
185- It needs clear interface / implementation / install / uninstall lifecycles
186- It needs `ServiceCollection`, dependency injection, self-owned listeners, and command registration inside services
187
188### 3. Hybrid architecture
189
190Suitable when:
191
192- The plugin is mainly gameplay-module-oriented, but some subsystems fit services better
193- The modular core needs to be augmented with a small number of installable and uninstallable services
194
195## Core operating rules
196
197### 1. Historical implementations are only temporary experience sources
198
199- If the task requires behavior alignment, historical implementations may be referenced.
200- But historical implementations must not become long-term dependencies of the future solution.
201
202### 2. Silent drift is forbidden
203
204- If the user explicitly requires historical alignment, legacy compatibility, or player-visible consistency, every difference must be explicitly explained or explicitly fixed.
205- Do not add backward-compatibility branches, aliases, adapters, fallback routes, or duplicate data paths unless the current user explicitly requests compatibility. If active legacy callers or data are discovered, report the evidence and impact before implementing a compatibility layer.
206
207### 3. Lifecycle closure is a hard requirement
208
209At minimum, explicitly check:
210
211- map load / unload
212- player connect / disconnect
213
214### 4. Main-thread / async boundaries must be explicit
215
216According to the official SwiftlyS2 `Thread Safety` documentation, the following operations should be treated as main-thread-sensitive by default:
217
218- Many message and entity operations on `IPlayer`
219- `ICommandContext.Reply`
220- `IGameEventService.Fire*`
221- `IEngineService.ExecuteCommand*`
222- `CEntityInstance.AcceptInput / DispatchSpawn / Despawn`
223- `CBaseModelEntity.SetModel / SetBodygroupByName`
224- `CCSPlayerController.Respawn`
225- `CPlayer_ItemServices.*`
226- `CPlayer_WeaponServices.*`
227
228When in an async context, prefer the corresponding `Async` APIs instead of mechanically wrapping everything in `NextTick` / `NextWorldUpdate`.
229
230### 5. For high-frequency hooks, prioritize safety before speed
231
232- Filter irrelevant objects as early as possible
233- Control allocations and logging
234- Avoid JSON, IO, blocking waits, and unbounded lock contention
235- Prefer a producer / consumer separation mindset
236- Keep a 64-tick frame-budget mindset
237- Decide whether the Hook should exist at all before optimizing its body; avoid the finest-grained Hook when a lower-frequency movement stage, scheduler, or state-diff path is sufficient
238- Use a stable early-return shape: feature disabled / no current runtime / invalid player or pawn / fake client / no registered subscribers
239
240### 5.1 Choose the current hook surface before optimizing it
241
242- Framework lifecycle / tick / ordinary core notifications: `Core.Event`
243- Generated Source 2 game events: `Core.GameEvent`
244- Typed controller/entity/item/movement/pawn/weapon hooks: `Core.GameHooks`
245- Only typed API gaps: `Core.GameData` + `Core.Memory` with an exact delegate
246- Do not introduce `DynamicHook`, `[HookCallback]`, or old `Core.Event.On*Hook` paths for a new implementation.
247- For dynamic registration, declare the owner, precise unregistration route, `Pre` / `Post` behavior, and whether temporary/ref context can escape.
248
249### 6. `IPlayer` lifecycle has extremely high priority
250
251- `IPlayer` objects may be destroyed after disconnect
252- Delayed tasks, async callbacks, menu callbacks, and background worker writebacks must revalidate or reacquire the object
253- Do not assume bots / fakeclients can reuse the same identity-key strategy as real players
254- When bots and real players are stored together, prefer `SessionId` as the runtime lookup key
255- Bot `SteamID` values are not reliable and should, in practice, be treated as fixed `0`; do not use them as stable bot lookup keys
256- Use `GetPlayerFromSessionId` for current-session relookup; use `GetPlayerFromSteamId` only for confirmed real-player identity flows.
257
258### 7. For long-lived entity tracking, think in handles first
259
260- Across frames, delays, or maps, do not hold raw entity wrappers long-term
261- Prefer storing entities as `CHandle<T>` and validate before access
262
263### 8. `Span` / `stackalloc` / `ref` should only be used when there is evidence
264
265- Suitable for synchronous hot paths and small data transfers
266- Must not cross `await`
267- Must not cross threads
268- Must not be captured by closures or escape the synchronous stack frame
269- Do not introduce dangling references or shared-buffer risks just to avoid one copy
270
271### 9. Treat menu callbacks as async contexts
272
273- Review `Click`, `ValueChanged`, and `Submenu` callbacks as async-context code by default
274- Prefer `BindingText` for dynamic display text
275
276### 10. JSON and synchronous blocking are high-risk by default
277
278- `.Wait()`, `.Result`, synchronous joins, and blocking IO should be treated as high-risk by default
279- JSON serialization / deserialization should, by default, run in the background rather than inside hooks, runtime loops, menu callbacks, or main-thread periodic tasks
280
281### 11. Performance optimization must map to a concrete hotspot category
282
283When asked to optimize performance, first classify the code as one or more of:
284
285- high-frequency Hook / movement path
286- per-player runtime state
287- sampling buffer / replay-like data
288- background worker / queue
289- map-level async initialization
290- periodic HUD / menu text
291- native interop / binary layout
292
293Then use `./references/swiftlys2-performance-optimization-playbook.md` to choose an implementation pattern. Do not add micro-optimizations such as `AggressiveInlining`, object pools, or binary layout unless the code is demonstrably small/hot, allocation-heavy, or native/binary-bound.
294
295## Recommended reading order
296
297### For planning
298
2991. `./SKILL.md`
3002. `./references/swiftlys2-plugin-playbook.md`
3013. `./references/swiftlys2-current-capability-map.md` when SDK surface selection matters
3024. `./references/plan-workflow.md`
3035. `./assets/workflows/planning/method-level-plan-template.md`
304
305### For auditing
306
3071. `./SKILL.md`
3082. `./references/swiftlys2-kb-index.md`
3093. `./references/swiftlys2-current-capability-map.md`
3104. `./references/swiftlys2-performance-optimization-playbook.md` when performance or hot paths are in scope
3115. `./references/audit-workflow.md`
3126. `./assets/workflows/audit/audit-report-template.md`
313
314### For direct code edits
315
3161. `./SKILL.md`
3172. `./references/edit-workflow.md`
3183. Relevant subsystem templates / checklists
319
320## Output requirements
321
322### If the user wants a plan
323
324The output must include at least:
325
326- Task classification
327- Target plugin / subsystem
328- Whether historical behavior alignment is involved
329- A method-level plan
330- Thread / lifecycle boundaries
331- A regression matrix
332
333### If the user wants an audit
334
335The output must include at least:
336
337- Risk levels
338- File / method-level locations
339- Evidence
340- Repair directions
341- Regression recommendations
342
343### If the user requests direct editing
344
345The output must include at least:
346
347- Files and methods changed
348- Why the change was made this way
349- Validation results
350- Which requirements were directly validated and which still need additional validation
351
352## Verification quality bar
353
354- Prefer evidence-backed verification statements over narrative confidence.
355- When validation status matters, distinguish `PASS`, `FAIL`, and `PARTIAL` in audits or delivery notes.
356- Use `PARTIAL` only for objective environment limits or missing external dependencies, not for uncertainty or skipped checks.
357- For high-risk lifecycle / hook / runtime work, add at least one adversarial or regression-oriented check in addition to build success.
358
359## Examples
360
361- “Add a DI-based state synchronization module for a SwiftlyS2 plugin.”
362- “Audit a plugin’s RuntimeLoop and hook hot paths.”
363- “Migrate player-visible behavior from a historical SwiftlyS2 plugin into the current architecture.”
364- “Fix thread-sensitive calls inside menu callbacks and land the code directly.”