You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
You are an expert in Web development, including JavaScript, TypeScript, CSS, React, Tailwind, Node.js, and Next.js. You excel at selecting and choosing the best tools, avoiding unnecessary duplication and complexity.
6
+
7
+
When making a suggestion, you break things down into discrete changes and suggest a small test after each stage to ensure things are on the right track.
8
+
9
+
Produce code to illustrate examples, or when directed to in the conversation. If you can answer without code, that is preferred, and you will be asked to elaborate if it is required. Prioritize code examples when dealing with complex logic, but use conceptual explanations for high-level architecture or design patterns.
10
+
11
+
Before writing or suggesting code, you conduct a deep-dive review of the existing code and describe how it works between <CODE_REVIEW> tags. Once you have completed the review, you produce a careful plan for the change in <PLANNING> tags. Pay attention to variable names and string literals—when reproducing code, make sure that these do not change unless necessary or directed. If naming something by convention, surround in double colons and in ::UPPERCASE::.
12
+
13
+
Finally, you produce correct outputs that provide the right balance between solving the immediate problem and remaining generic and flexible.
14
+
15
+
You always ask for clarification if anything is unclear or ambiguous. You stop to discuss trade-offs and implementation options if there are choices to make.
16
+
17
+
You are keenly aware of security, and make sure at every step that we don't do anything that could compromise data or introduce new vulnerabilities. Whenever there is a potential security risk (e.g., input handling, authentication management), you will do an additional review, showing your reasoning between <SECURITY_REVIEW> tags.
18
+
19
+
Additionally, consider performance implications, efficient error handling, and edge cases to ensure that the code is not only functional but also robust and optimized.
20
+
21
+
Everything produced must be operationally sound. We consider how to host, manage, monitor, and maintain our solutions. You consider operational concerns at every step and highlight them where they are relevant.
22
+
23
+
Finally, adjust your approach based on feedback, ensuring that your suggestions evolve with the project's needs.
Copy file name to clipboardExpand all lines: AGENTS.md
+29-16Lines changed: 29 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,6 +4,12 @@
4
4
5
5
A .NET library + WASM/Node packages for Balatro seed analysis. It predicts what items, jokers, tags, vouchers, etc. a given seed will produce using Balatro's PRNG system.
6
6
7
+
### Call it JAML
8
+
9
+
Filter documents are **JAML** (`.jaml`). In user-facing prose and comments, prefer **JAML** over “YAML” — *YAML Ain’t Motely’s Language.* (YamlDotNet is still the parser; that’s implementation.)
10
+
11
+
Optional top-level **`aesthetics`** (e.g. `- palindrome`) is parsed from the JAML document and merged in `MotelySearchOrchestrator.PrepareSearch` when it doesn’t conflict with the host’s seeds / keywords / random mode.
Both are **OUTPUT DIRECTORIES**. They are populated by `build-and-pack.ps1`.
20
26
27
+
### JAML JSON schema — no hand edits, no drift
28
+
29
+
`jaml.schema.json`, `jaml-schema.js`, and `jaml-schema.d.ts` are **generated from C#** by `Motely.CLI`:
30
+
31
+
```bash
32
+
dotnet run --project Motely.CLI/Motely.CLI.csproj -- --write-jaml-schema
33
+
```
34
+
35
+
`JamlSchemaGenerator` writes the same content to every mirror path (repo root, `public/`, `Motely.NodeAddon/`, `motely-wasm/`, `motely-node/`). `build-and-pack.ps1` runs this step after version bump so packs stay consistent. Do **not** edit those files manually: you will fork copies, break the npm pipeline, and fight the next generator run. New JAML surface area (e.g. `JamlAesthetic` values) belongs in **`Motely.CLI/JamlSchemaGenerator.cs`** and in the parser/enum in **`Motely`**, then regenerate.
@@ -81,37 +96,35 @@ Every PRNG stream's state is ultimately a `double`. `MotelySinglePrngStream(doub
81
96
82
97
### ref struct vs struct
83
98
84
-
Some stream types are `ref struct` (stack-only, cannot be stored on the heap). When you need to store a `ref struct` as a class field, decompose its fields into a storage struct (they're just doubles and strings), then reconstruct on demand. See `StreamCache` in `MotelyGameplayState.cs`.
99
+
Some stream types are `ref struct` (stack-only, cannot be stored on the heap). When you need to store a `ref struct` as a class field, decompose its fields into a storage struct (they're just doubles and strings), then reconstruct on demand.
85
100
86
101
Do NOT change `ref struct` to `struct` in core Motely files. Work around it.
87
102
88
-
### The Parked Filter Pattern
89
-
90
-
`MotelyGameplayState` uses the search pipeline as a **context factory**. It parks a filter on a background thread via semaphores, keeping a `MotelySingleSearchContext` alive on the stack indefinitely. This is the ONLY way to get a context for single-seed analysis.
91
-
92
-
**DO NOT touch the parked filter code** (`ParkedFilterDesc`, `ParkedFilter`, `CheckSeed`, the semaphore dance). It is correct.
103
+
### analyzeSeed Returns a Fixed Snapshot
93
104
94
-
**DO NOT touch the `Cmd<T>` delegate dispatch.** It is correct.
105
+
`MotelySeedAnalyzer.AnalyzeToDto()` pre-computes a fixed set of items for antes 1-8: boss, voucher, tags, draw order, shop queue, packs. This is NOT infinite — it's a snapshot. The shop queue list is finite and exhaustible.
95
106
96
107
### One Ante At A Time
97
108
98
109
The game state represents sequential gameplay. One ante at a time. When the ante changes, reset streams. Do NOT use `Dictionary<int, StreamType>` to cache per-ante.
99
110
100
-
### MotelyGameplayState IS the Single Seed Context
It's a stateful object that wraps `MotelySingleSearchContext` for one seed. You create it, call `NextShopItem(ante)` repeatedly, and it advances the PRNG. Infinite scroll. Don't pre-compute, don't batch, don't wrap the analyzer.
113
+
Infinite shop item streaming requires a stateful C# object that wraps `MotelySingleSearchContext` for one seed, advancing the shop PRNG on each call (e.g. `createSeedContext → nextShopItem(ante)`). This does NOT exist yet. Today, infinite shop streaming only works on the TypeScript Game path. Building this on the Motely/WASM side requires:
114
+
1. A new C# class (`MotelyGameplayState`) that holds live PRNG state
["seeds"]=StringArrayProperty("Known seed examples associated with this filter."),
155
+
["aesthetics"]=newJsonObject
156
+
{
157
+
["type"]="array",
158
+
["description"]=
159
+
"Optional seed-space constraints from JamlAesthetic (see definitions/JamlAesthetic). Merged in MotelySearchOrchestrator when compatible; conflicts with host seeds, keywords, or random mode.",
["must"]=ClauseArray("Required clauses. All listed clauses must match."),
157
164
["should"]=ClauseArray("Scored clauses. Matching clauses add score but do not gate the seed by themselves."),
158
165
["mustNot"]=ClauseArray("Rejected clauses. If any listed clause matches, the seed is rejected.")
159
166
},
160
167
["definitions"]=newJsonObject
161
168
{
162
-
["clause"]=BuildClauseDefinition()
169
+
["clause"]=BuildClauseDefinition(),
170
+
["JamlAesthetic"]=newJsonObject
171
+
{
172
+
["title"]="JamlAesthetic",
173
+
["description"]=
174
+
"Named constraint on which seeds participate in search. Motely: see JamlAesthetics for enumeration and Matches(); seed alphabet is MotelyCore.SeedDigits, max length MotelyCore.MaxSeedLength.",
"title": "JAML - Jimbo\u0027s Ante Markup Language",
7
7
"description": "Schema for Balatro seed filter configuration files (.jaml)",
8
8
"type": "object",
@@ -68,6 +68,13 @@ export const jamlSchema = {
68
68
},
69
69
"description": "Known seed examples associated with this filter."
70
70
},
71
+
"aesthetics": {
72
+
"type": "array",
73
+
"description": "Optional seed-space constraints from JamlAesthetic (see definitions/JamlAesthetic). Merged in MotelySearchOrchestrator when compatible; conflicts with host seeds, keywords, or random mode.",
74
+
"items": {
75
+
"$ref": "#/definitions/JamlAesthetic"
76
+
}
77
+
},
71
78
"defaults": {
72
79
"type": "object",
73
80
"description": "Default values applied to clauses when a clause does not specify its own values.",
"description": "Named constraint on which seeds participate in search. Motely: see JamlAesthetics for enumeration and Matches(); seed alphabet is MotelyCore.SeedDigits, max length MotelyCore.MaxSeedLength.",
"title": "JAML - Jimbo\u0027s Ante Markup Language",
6
6
"description": "Schema for Balatro seed filter configuration files (.jaml)",
7
7
"type": "object",
@@ -67,6 +67,13 @@
67
67
},
68
68
"description": "Known seed examples associated with this filter."
69
69
},
70
+
"aesthetics": {
71
+
"type": "array",
72
+
"description": "Optional seed-space constraints from JamlAesthetic (see definitions/JamlAesthetic). Merged in MotelySearchOrchestrator when compatible; conflicts with host seeds, keywords, or random mode.",
73
+
"items": {
74
+
"$ref": "#/definitions/JamlAesthetic"
75
+
}
76
+
},
70
77
"defaults": {
71
78
"type": "object",
72
79
"description": "Default values applied to clauses when a clause does not specify its own values.",
@@ -1699,6 +1706,14 @@
1699
1706
],
1700
1707
"additionalProperties": false,
1701
1708
"minProperties": 1
1709
+
},
1710
+
"JamlAesthetic": {
1711
+
"title": "JamlAesthetic",
1712
+
"description": "Named constraint on which seeds participate in search. Motely: see JamlAesthetics for enumeration and Matches(); seed alphabet is MotelyCore.SeedDigits, max length MotelyCore.MaxSeedLength.",
0 commit comments