@neocompose/cli 0.77.1 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/dist/neo.mjs +3165 -1372
- package/dist/test-worker.mjs +1251 -677
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +1 -1
- package/skills/neocompose-cli/references/animation-and-world-authoring.md +24 -5
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/commands-and-sync.md +5 -2
- package/skills/neocompose-cli/references/declarations-and-construction.md +34 -1
- package/skills/neocompose-cli/references/neoscript.md +3 -8
- package/skills/neocompose-cli/references/values-identities-and-references.md +28 -2
package/package.json
CHANGED
|
@@ -38,10 +38,28 @@ NeoCellPattern neighbors = NeoCellPattern.Box(1, excluding: .Center);
|
|
|
38
38
|
NeoCellPattern custom = new(offsets: [new(-1, 0), new(2, 1)]);
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
`NeoCellPattern` is an ordinary stored class, and the presets are stored
|
|
42
|
+
static values. A field that owns its pattern can't default to a preset or any
|
|
43
|
+
other stored static, because the static already owns that row. `neo status`
|
|
44
|
+
and push refuse `= NeoCellPattern.EightNeighbors` there. Call `.Clone()` to
|
|
45
|
+
give each instance its own copy, or declare `Reference<NeoCellPattern>` to
|
|
46
|
+
share the preset or any stored pattern:
|
|
47
|
+
|
|
48
|
+
```neo
|
|
49
|
+
class Sprinkler : NeoObject {
|
|
50
|
+
public NeoCellPattern Reach = NeoCellPattern.EightNeighbors.Clone();
|
|
51
|
+
public Reference<NeoCellPattern> Splash = NeoCellPattern.Center;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
41
55
|
On a placed `NeoObject`, `this.Cell` returns its grid cell.
|
|
42
56
|
`this.GetObjects<Plant>(neighbors)` returns matching placed objects in the
|
|
43
57
|
same grid, filtered to `Plant` and subclasses. `this.GetTile(neighbors)`
|
|
44
|
-
returns the first tile found in pattern order, or null.
|
|
58
|
+
returns the first tile found in pattern order, or null.
|
|
59
|
+
`this.GetTiles(neighbors)` returns the tile at each occupied cell in pattern
|
|
60
|
+
order and skips empty cells. Each query takes an optional `offset` that shifts
|
|
61
|
+
the whole pattern, so `this.GetTiles(neighbors, new(0, 2))` queries around the
|
|
62
|
+
cell two rows up without building a translated pattern. These queries track
|
|
45
63
|
empty cells as well as hits, so a getter updates when a new neighbor appears.
|
|
46
64
|
Calling them on an unplaced object is an error.
|
|
47
65
|
|
|
@@ -51,10 +69,11 @@ Box, Cross, and Line include the origin by default. Use `excluding: .Center`
|
|
|
51
69
|
to omit it. Line's `length` is the number of steps beyond the origin, so
|
|
52
70
|
`Line(new(1, 0), 3)` contains four cells.
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
`
|
|
72
|
+
In C#, the generated `NeoCellPattern` implements `INeoCellPattern`, an
|
|
73
|
+
`IReadOnlyList<Vector2Int>` of offsets, and SDK grid helpers accept any
|
|
74
|
+
`INeoCellPattern`. Replace old boolean factory arguments with
|
|
75
|
+
`NeoCellPatternExcluding.None` or `.Center`. To retain Line's old default,
|
|
76
|
+
pass `excluding: NeoCellPatternExcluding.Center` explicitly.
|
|
58
77
|
|
|
59
78
|
## Tile placements
|
|
60
79
|
|
|
@@ -129,7 +129,7 @@ wrappers.
|
|
|
129
129
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
130
130
|
|
|
131
131
|
```html
|
|
132
|
-
<!-- reviewed-through-cli: 0.
|
|
132
|
+
<!-- reviewed-through-cli: 0.79.0 -->
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -35,7 +35,8 @@ names with readable ones. It keeps chosen names and rewrites references. Use
|
|
|
35
35
|
declaration file grouping already recorded by the workspace, while
|
|
36
36
|
declarations with no prior placement use the canonical per-declaration layout. Use `--force` only to discard local edits for the server
|
|
37
37
|
version. Normal pulls persist a transaction cursor and fetch only changed
|
|
38
|
-
records.
|
|
38
|
+
records. Dictionary string keys, including Unicode, round-trip through full and
|
|
39
|
+
incremental reads. If the remote head is unchanged, pull preserves the local source
|
|
39
40
|
without compiling it; use `neo status` to inspect local edits and diagnostics.
|
|
40
41
|
Pull ignores records whose hashes already match the saved server baseline,
|
|
41
42
|
including echoes of this checkout's last push, and advances its cursor without
|
|
@@ -86,7 +87,9 @@ does not prompt, upload, commit, or rewrite source.
|
|
|
86
87
|
Removing a class or collection declaration also deletes its hidden collection
|
|
87
88
|
entry members, including nested lists and dictionaries. Replacing a collection
|
|
88
89
|
with a scalar deletes its abandoned entries too. Entries used by surviving
|
|
89
|
-
declarations are retained.
|
|
90
|
+
declarations are retained. If a member is deleted locally before pulling remote
|
|
91
|
+
instance values, pull retains those values in the deletion plan; the next push
|
|
92
|
+
removes them with the member. Review these derived deletions in `neo status` or
|
|
90
93
|
`neo diff` before pushing.
|
|
91
94
|
|
|
92
95
|
Dry-run also compares the CLI's derived-edge extractor with the server version
|
|
@@ -91,7 +91,7 @@ Use context-aware typed annotations:
|
|
|
91
91
|
- `@visibility(.Hidden)` only on a class; absence means visible.
|
|
92
92
|
- Stateful settings use contextual enum cases, such as
|
|
93
93
|
`@settings(format: .Plain)` and `@settings(kind: .Unordered)`.
|
|
94
|
-
- `@settings(...)` before a `List` element or `Dictionary` value type
|
|
94
|
+
- `@settings(...)` before a `List` or `Set` element or `Dictionary` value type
|
|
95
95
|
configures the collection's entries: `List<@settings(format: .Plain) string>`,
|
|
96
96
|
`Dictionary<string, @settings(min: 0) int>`. Only the member that declares
|
|
97
97
|
the collection spells them; overrides share its entries.
|
|
@@ -271,6 +271,36 @@ A `Reference<T>` member satisfies an interface `T Foo { get; }` or
|
|
|
271
271
|
|
|
272
272
|
Constructor and function parameters use `Set<T>` for several selections.
|
|
273
273
|
|
|
274
|
+
### Set members
|
|
275
|
+
|
|
276
|
+
`Set<T>` is an insertion-ordered collection that can't hold duplicates. The
|
|
277
|
+
element picks the storage:
|
|
278
|
+
|
|
279
|
+
- An enum `Set<Trait>` is a multi-select Enum.
|
|
280
|
+
- `Set<Reference<T>>` is a multi-select lookup.
|
|
281
|
+
- `Set<NeoDialogueReference>` is a multi-select dialogue lookup.
|
|
282
|
+
- Any other element makes an owned Set whose entries are rows, like a List.
|
|
283
|
+
|
|
284
|
+
An owned Set holds `bool`, `int`, `float`, `decimal`,
|
|
285
|
+
`@settings(format: .Plain) string`, vectors, `Color`, sprites, audio clips,
|
|
286
|
+
or a class. Elements can't be nullable, collections, variants, delegates,
|
|
287
|
+
actions, or interfaces. A class entry is unique by row, a value entry by its
|
|
288
|
+
value. `@index` and `@column` work as on a List; `kind:` is an error, since a
|
|
289
|
+
Set is always insertion-ordered.
|
|
290
|
+
|
|
291
|
+
```neo
|
|
292
|
+
@index(member: Slug, kind: .Unique)
|
|
293
|
+
public Set<Quest> ActiveQuests = [];
|
|
294
|
+
public Set<int> LuckyNumbers = [3, 7];
|
|
295
|
+
public Set<Trait> Traits = [.Brave];
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
`selection:` is an error everywhere: `Set<T>` selects many and `T` selects
|
|
299
|
+
one. The language server's quick fix rewrites `@settings(selection: .Multi)`
|
|
300
|
+
to a `Set<…>` type. A default literal that repeats a value fails `push`, and a
|
|
301
|
+
`List<Trait>` stays an ordered List of enum values. Queries over a Set, such
|
|
302
|
+
as `Where` and `OrderBy`, return a Set; `ToSet()` turns a List into one.
|
|
303
|
+
|
|
274
304
|
Declare a multicast event as `NeoAction<…>`. Its value is an ordered listener
|
|
275
305
|
set, so give it a bracketed list of method groups — never a lambda, and never
|
|
276
306
|
a bare method group — and never mark it `required`: the rest state is the
|
|
@@ -535,6 +565,9 @@ Populated unordered member defaults, such as `@settings(kind: .Unordered)` with
|
|
|
535
565
|
`List<Entry> Entries = [new Entry()]`, are constructed by an initializer for
|
|
536
566
|
each instance. A declaration has no container value row to own unordered entries.
|
|
537
567
|
Nested unordered lists already have container rows and retain their stored values.
|
|
568
|
+
A field, collection entry, or dictionary value can't place a value that
|
|
569
|
+
something else already owns, such as `Bag = [Shared.Pattern]` or a constructor
|
|
570
|
+
parameter stored in an ordinary field. Call `Clone()` or use `Reference`.
|
|
538
571
|
|
|
539
572
|
A lookup's declared class must be assignable to the entry class of its
|
|
540
573
|
`@settings(collection: Owner.Member)` collection. A subclass may narrow the
|
|
@@ -143,8 +143,8 @@ static function may be named as `Read` or qualified as `Holder.Read`/`Other.Read
|
|
|
143
143
|
A qualified method group must name a static function. Method groups use the same
|
|
144
144
|
signature rule as in a body, and a mismatch is reported at the declaration.
|
|
145
145
|
A static field that names another static copies a value, as in
|
|
146
|
-
`public static int B = Holder.A
|
|
147
|
-
|
|
146
|
+
`public static int B = Holder.A;`. A class, List, Set, or Dictionary static
|
|
147
|
+
already owns its value, so call `Clone()` or use `Reference`. A static delegate cannot copy another Class's delegate field,
|
|
148
148
|
because its closure compiles in its own Class; wrap it as `() => Other.Call()`.
|
|
149
149
|
Collection type arguments in constructions, such as `new Box<List<int>>([1, 2])`,
|
|
150
150
|
work even when no field declares that collection type. Preparation includes the
|
|
@@ -356,9 +356,6 @@ count fails at runtime with `List.Repeat count must be non-negative; got
|
|
|
356
356
|
still known. The value is evaluated exactly once, then the count exactly once,
|
|
357
357
|
so side effects happen once regardless of `count`, and every entry is that one
|
|
358
358
|
value: for a reference-typed entry the same reference repeats `count` times.
|
|
359
|
-
Materializing the list charges `count` to the shared collection-entries
|
|
360
|
-
execution budget, so a runaway count fails with the existing budget error
|
|
361
|
-
before allocating.
|
|
362
359
|
|
|
363
360
|
## Conditional and logical operators
|
|
364
361
|
|
|
@@ -422,7 +419,6 @@ and `Select((key, value) => key)`. String-keyed dictionaries yield strings.
|
|
|
422
419
|
Use `break` for the nearest loop or switch and `continue` for the nearest
|
|
423
420
|
loop. A `continue` inside a switch nested in a loop continues the loop.
|
|
424
421
|
|
|
425
|
-
All nested loops and called NeoScript bodies share a 10,000-iteration budget.
|
|
426
422
|
A `while` loop checks its boolean condition before each iteration. A
|
|
427
423
|
`do / while` loop runs its body once before checking the condition. Both
|
|
428
424
|
require braces; the `do / while` condition ends with a semicolon.
|
|
@@ -437,8 +433,7 @@ do {
|
|
|
437
433
|
} while (this.HasWork());
|
|
438
434
|
```
|
|
439
435
|
|
|
440
|
-
`continue` checks the condition again in both loops.
|
|
441
|
-
against the shared iteration budget.
|
|
436
|
+
`continue` checks the condition again in both loops.
|
|
442
437
|
|
|
443
438
|
## Switch
|
|
444
439
|
|
|
@@ -21,7 +21,7 @@ Root root = new() {
|
|
|
21
21
|
@id("root-assets-member-id")
|
|
22
22
|
@storage(allowed: .Immutable)
|
|
23
23
|
Assets Assets = new() {
|
|
24
|
-
Outposts = [Assets.Capitol],
|
|
24
|
+
Outposts = [Assets.Capitol.Clone()],
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
```
|
|
@@ -44,6 +44,22 @@ class Assets {
|
|
|
44
44
|
|
|
45
45
|
A computed static getter is an alias; it creates neither a binding nor a row.
|
|
46
46
|
|
|
47
|
+
A static used in another initializer copies value kinds, including scalars and
|
|
48
|
+
delegates. Class, list, set, and dictionary values have exactly one owner.
|
|
49
|
+
Placing a value that something else already owns is refused: a static, a
|
|
50
|
+
static's field, a collection entry, a local placed elsewhere, or a constructor
|
|
51
|
+
parameter stored in an ordinary field. Status, push, and `neo test` report the
|
|
52
|
+
placement at its authored position. Call `Clone()` to own a copy, or use
|
|
53
|
+
`Reference`:
|
|
54
|
+
|
|
55
|
+
```neo
|
|
56
|
+
static Outpost Annex = Assets.Capitol.Clone();
|
|
57
|
+
static Reference<Outpost> Seat = Reference(Assets.Capitol);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Statics created together may refer to each other regardless of declaration
|
|
61
|
+
order; no preliminary push is needed.
|
|
62
|
+
|
|
47
63
|
Enum-keyed dictionaries accept contextual or qualified option keys in defaults
|
|
48
64
|
and stored values:
|
|
49
65
|
|
|
@@ -102,13 +118,18 @@ AudioSettings AUDIO_SETTINGS = new() { Main = SFX_FOLDER };
|
|
|
102
118
|
```
|
|
103
119
|
|
|
104
120
|
In constructor arguments and executable operands, a class local names its one
|
|
105
|
-
stored instance instead of constructing a copy
|
|
121
|
+
stored instance instead of constructing a copy. Its owning placement keeps it,
|
|
122
|
+
so a constructor that stores it needs a `Reference` field:
|
|
106
123
|
|
|
107
124
|
```neo
|
|
108
125
|
@id("86ac7c7d-8d3b-4642-9def-cdf32643bdc5")
|
|
109
126
|
DeliveryQuest HARD_AS_STONE = new();
|
|
110
127
|
// The core quest list owns HARD_AS_STONE.
|
|
111
128
|
WorkflowStep UNLOCK = new QuestUnlockStep(HARD_AS_STONE);
|
|
129
|
+
|
|
130
|
+
class QuestUnlockStep(DeliveryQuest quest) : WorkflowStep {
|
|
131
|
+
public Reference<DeliveryQuest> Quest = quest;
|
|
132
|
+
}
|
|
112
133
|
```
|
|
113
134
|
|
|
114
135
|
The referenced local must have exactly one owning placement. A nested target
|
|
@@ -312,6 +333,11 @@ different. The name must end with the binary's extension, because pull
|
|
|
312
333
|
rebuilds the file's path from it. With no template annotation, the CLI persists the complete built-in
|
|
313
334
|
Unity defaults for the file kind.
|
|
314
335
|
|
|
336
|
+
Template-backed Unity settings may contain sparse nested override values and leaf
|
|
337
|
+
paths such as `platformSettings.standalone.maxTextureSize` or
|
|
338
|
+
`spriteSettings.pivot.x`. Preserve these paths during synchronization so untouched
|
|
339
|
+
settings continue inheriting from the template.
|
|
340
|
+
|
|
315
341
|
A top-level `NeoImage` or `NeoAudioClip` declaration in any definition file
|
|
316
342
|
can stand in for an inline entry. The registry lists it by name
|
|
317
343
|
(`NeoAudioClip SwordHit = SWORD_HIT;`), and the declaration carries the `@id`,
|