@genocode/core 0.1.0 → 0.2.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.
@@ -0,0 +1,45 @@
1
+ import type { CheckResult } from "./checker.js";
2
+ import { type GeneInfo } from "./genes.js";
3
+ import { type Value } from "./values.js";
4
+ /** Gene values by full name. A gene that isn't listed has the value written in the program. */
5
+ export type GeneValues = ReadonlyMap<string, Value>;
6
+ /** A creature for breeding and morphing: its genes, and the values they have. */
7
+ export interface GeneSet {
8
+ genes: readonly GeneInfo[];
9
+ values?: GeneValues;
10
+ }
11
+ export interface GeneticsOptions {
12
+ /** A random number from 0 up to 1, such as `Math.random` or `mulberry32(seed)`. */
13
+ random: () => number;
14
+ /** Full names of genes to keep as they are. */
15
+ locked?: ReadonlySet<string>;
16
+ }
17
+ export interface MutateOptions extends GeneticsOptions {
18
+ /** How far genes move, from 0 to 1. */
19
+ strength: number;
20
+ /** The chance that each gene is changed. ½ unless the app lets the user choose. */
21
+ rate?: number;
22
+ }
23
+ /** Every gene's value: the one given, or the one written in the program. */
24
+ export declare function valuesOf(genes: readonly GeneInfo[], values?: GeneValues): Map<string, Value>;
25
+ /** A mutated copy of the gene values. */
26
+ export declare function mutate(genes: readonly GeneInfo[], values: GeneValues | undefined, options: MutateOptions): Map<string, Value>;
27
+ /** The gene values of a child of A and B. The child has A's program. */
28
+ export declare function breed(a: GeneSet, b: GeneSet, options: GeneticsOptions): Map<string, Value>;
29
+ /**
30
+ * The creature at `t` (0 to 1) between A and B: which program it has (A's before the halfway
31
+ * point, B's from it on) and its gene values. Values aren't limited to either range.
32
+ */
33
+ export declare function morph(a: GeneSet, b: GeneSet, t: number): {
34
+ from: "a" | "b";
35
+ values: Map<string, Value>;
36
+ };
37
+ /**
38
+ * The program's text with each gene's value written in, laid out by the formatter. Genes whose
39
+ * value hasn't changed keep the text they were written with. The automatic `seed` gene has no
40
+ * line to write into, so it isn't saved.
41
+ */
42
+ export declare function writeGenes(program: CheckResult, values: GeneValues): string;
43
+ /** A gene value written readably, and still within the gene's range. */
44
+ export declare function geneLiteral(g: GeneInfo, v: Value): string;
45
+ //# sourceMappingURL=genetics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genetics.d.ts","sourceRoot":"","sources":["../src/genetics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,OAAO,EAAY,KAAK,QAAQ,EAAe,MAAM,YAAY,CAAC;AAClE,OAAO,EAML,KAAK,KAAK,EAEX,MAAM,aAAa,CAAC;AAErB,+FAA+F;AAC/F,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAEpD,iFAAiF;AACjF,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC3B,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,mFAAmF;IACnF,MAAM,EAAE,MAAM,MAAM,CAAC;IACrB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,aAAc,SAAQ,eAAe;IACpD,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,EAAE,MAAM,CAAC,EAAE,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAE5F;AAID,yCAAyC;AACzC,wBAAgB,MAAM,CACpB,KAAK,EAAE,SAAS,QAAQ,EAAE,EAC1B,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,OAAO,EAAE,aAAa,GACrB,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAUpB;AAqED,wEAAwE;AACxE,wBAAgB,KAAK,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAY1F;AA4DD;;;GAGG;AACH,wBAAgB,KAAK,CACnB,CAAC,EAAE,OAAO,EACV,CAAC,EAAE,OAAO,EACV,CAAC,EAAE,MAAM,GACR;IAAE,IAAI,EAAE,GAAG,GAAG,GAAG,CAAC;IAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;CAAE,CAgBjD;AAsBD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAc3E;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,GAAG,MAAM,CAkBzD"}
@@ -0,0 +1,268 @@
1
+ // Mutating, breeding and morphing genes (docs/LANGUAGE.md section 19), and writing a creature's
2
+ // gene values back into its program, which is how a bred creature is saved.
3
+ import { hueDelta, mixHue, wrapHue } from "./colour.js";
4
+ import { formatText } from "./format.js";
5
+ import { inHueArc } from "./genes.js";
6
+ import { formatValue, isColour, isVec, valuesEqual, } from "./values.js";
7
+ /** Every gene's value: the one given, or the one written in the program. */
8
+ export function valuesOf(genes, values) {
9
+ return new Map(genes.map((g) => [g.fullName, values?.get(g.fullName) ?? g.value]));
10
+ }
11
+ // ---------- mutation (section 19.1) ----------
12
+ /** A mutated copy of the gene values. */
13
+ export function mutate(genes, values, options) {
14
+ const { random, strength } = options;
15
+ const rate = options.rate ?? 0.5;
16
+ const out = valuesOf(genes, values);
17
+ for (const g of genes) {
18
+ if (options.locked?.has(g.fullName))
19
+ continue;
20
+ if (random() >= rate)
21
+ continue;
22
+ out.set(g.fullName, mutateGene(g, out.get(g.fullName), strength, random));
23
+ }
24
+ return out;
25
+ }
26
+ function mutateGene(g, v, strength, random) {
27
+ if (isSeed(g))
28
+ return random() < strength ? Math.floor(random() * 2 ** 32) : v;
29
+ switch (g.kind) {
30
+ case "bool":
31
+ return random() < strength ? !v : v;
32
+ case "choice":
33
+ case "part": {
34
+ if (random() >= strength)
35
+ return v;
36
+ const others = g.options.filter((o) => !valuesEqual(o, v));
37
+ return others.length > 0 ? others[Math.floor(random() * others.length)] : v;
38
+ }
39
+ case "number":
40
+ return mutateNumber(v, g.min, g.max, g, strength, random);
41
+ case "vector": {
42
+ const [a, lo, hi] = [v, g.min, g.max];
43
+ const axis = (k) => mutateNumber(a[k], lo[k], hi[k], g, strength, random);
44
+ return { type: "vector", x: axis("x"), y: axis("y"), z: axis("z") };
45
+ }
46
+ case "colour": {
47
+ const [c, lo, hi] = [v, g.min, g.max];
48
+ const channel = (k) => mutateNumber(c[k], lo[k], hi[k], g, strength, random);
49
+ return {
50
+ type: "colour",
51
+ h: mutateHue(c.h, g.hue, strength, random),
52
+ s: channel("s"),
53
+ v: channel("v"),
54
+ a: channel("a"),
55
+ };
56
+ }
57
+ }
58
+ }
59
+ /** A uniformly random point in `v ± strength × (max − min)`, kept within min..max. */
60
+ function mutateNumber(v, min, max, g, strength, random) {
61
+ if (min === max)
62
+ return v;
63
+ if (g.log) {
64
+ const r = strength * (Math.log(max) - Math.log(min));
65
+ const l = Math.log(v);
66
+ const lo = Math.max(Math.log(min), l - r);
67
+ const hi = Math.min(Math.log(max), l + r);
68
+ return clamp(Math.exp(lo + random() * (hi - lo)), min, max);
69
+ }
70
+ const r = strength * (max - min);
71
+ const lo = Math.max(min, v - r);
72
+ const hi = Math.min(max, v + r);
73
+ return snap(lo + random() * (hi - lo), min, max, g.step);
74
+ }
75
+ /** Hue: the window `h ± strength × arc` taken round the circle, limited to the arc unless it's whole. */
76
+ function mutateHue(h, arc, strength, random) {
77
+ const r = strength * arc.length;
78
+ if (arc.whole)
79
+ return wrapHue(h + (random() * 2 - 1) * r);
80
+ const at = wrapHue(h - arc.start);
81
+ const lo = Math.max(0, at - r);
82
+ const hi = Math.min(arc.length, at + r);
83
+ return wrapHue(arc.start + lo + random() * (hi - lo));
84
+ }
85
+ // ---------- breeding (section 19.2) ----------
86
+ /** The gene values of a child of A and B. The child has A's program. */
87
+ export function breed(a, b, options) {
88
+ const { random } = options;
89
+ const av = valuesOf(a.genes, a.values);
90
+ const bv = valuesOf(b.genes, b.values);
91
+ const bGenes = new Map(b.genes.map((g) => [g.fullName, g]));
92
+ const out = new Map(av);
93
+ for (const g of a.genes) {
94
+ const match = bGenes.get(g.fullName);
95
+ if (options.locked?.has(g.fullName) || match === undefined || match.kind !== g.kind)
96
+ continue;
97
+ out.set(g.fullName, breedGene(g, av.get(g.fullName), bv.get(g.fullName), random));
98
+ }
99
+ return out;
100
+ }
101
+ function breedGene(g, x, y, random) {
102
+ if (isSeed(g) || g.kind === "bool")
103
+ return random() < 0.5 ? x : y;
104
+ if (g.kind === "choice" || g.kind === "part") {
105
+ const pick = random() < 0.5 ? x : y;
106
+ // B's choice only counts if it's one of A's options.
107
+ return g.options.some((o) => valuesEqual(o, pick)) ? pick : x;
108
+ }
109
+ if (g.kind === "number") {
110
+ return breedNumber(x, y, g.min, g.max, g, random);
111
+ }
112
+ if (g.kind === "vector" && isVec(x) && isVec(y)) {
113
+ const [lo, hi] = [g.min, g.max];
114
+ const axis = (k) => breedNumber(x[k], y[k], lo[k], hi[k], g, random);
115
+ return { type: "vector", x: axis("x"), y: axis("y"), z: axis("z") };
116
+ }
117
+ if (g.kind === "colour" && isColour(x) && isColour(y)) {
118
+ const [lo, hi] = [g.min, g.max];
119
+ const channel = (k) => breedNumber(x[k], y[k], lo[k], hi[k], g, random);
120
+ return {
121
+ type: "colour",
122
+ h: breedHue(x.h, y.h, g.hue, random),
123
+ s: channel("s"),
124
+ v: channel("v"),
125
+ a: channel("a"),
126
+ };
127
+ }
128
+ return x;
129
+ }
130
+ /** Half the time a random point between the two, otherwise one or the other; kept within A's range. */
131
+ function breedNumber(x, y, min, max, g, random) {
132
+ let v;
133
+ if (random() < 0.5) {
134
+ const t = random();
135
+ v =
136
+ g.log && x > 0 && y > 0
137
+ ? Math.exp(Math.log(x) + t * (Math.log(y) - Math.log(x)))
138
+ : x + t * (y - x);
139
+ }
140
+ else {
141
+ v = random() < 0.5 ? x : y;
142
+ }
143
+ return snap(v, min, max, g.step);
144
+ }
145
+ function breedHue(x, y, arc, random) {
146
+ const h = random() < 0.5 ? mixHue(x, y, random()) : random() < 0.5 ? x : y;
147
+ return clampHue(h, arc);
148
+ }
149
+ // ---------- morphing (section 19.3) ----------
150
+ /**
151
+ * The creature at `t` (0 to 1) between A and B: which program it has (A's before the halfway
152
+ * point, B's from it on) and its gene values. Values aren't limited to either range.
153
+ */
154
+ export function morph(a, b, t) {
155
+ const from = t < 0.5 ? "a" : "b";
156
+ const own = from === "a" ? a : b;
157
+ const other = from === "a" ? b : a;
158
+ const av = valuesOf(a.genes, a.values);
159
+ const bv = valuesOf(b.genes, b.values);
160
+ const otherGenes = new Map(other.genes.map((g) => [g.fullName, g]));
161
+ const out = valuesOf(own.genes, own.values);
162
+ for (const g of own.genes) {
163
+ const match = otherGenes.get(g.fullName);
164
+ if (match === undefined || match.kind !== g.kind)
165
+ continue;
166
+ const x = av.get(g.fullName);
167
+ const y = bv.get(g.fullName);
168
+ out.set(g.fullName, morphGene(g, x, y, t));
169
+ }
170
+ return { from, values: out };
171
+ }
172
+ function morphGene(g, x, y, t) {
173
+ const num = (p, q) => g.log && p > 0 && q > 0 ? p * (q / p) ** t : p + (q - p) * t;
174
+ if (typeof x === "number" && typeof y === "number" && !isSeed(g))
175
+ return num(x, y);
176
+ if (isVec(x) && isVec(y))
177
+ return { type: "vector", x: num(x.x, y.x), y: num(x.y, y.y), z: num(x.z, y.z) };
178
+ if (isColour(x) && isColour(y)) {
179
+ return {
180
+ type: "colour",
181
+ h: mixHue(x.h, y.h, t),
182
+ s: x.s + (y.s - x.s) * t,
183
+ v: x.v + (y.v - x.v) * t,
184
+ a: x.a + (y.a - x.a) * t,
185
+ };
186
+ }
187
+ return t < 0.5 ? x : y;
188
+ }
189
+ // ---------- writing genes into the program ----------
190
+ /**
191
+ * The program's text with each gene's value written in, laid out by the formatter. Genes whose
192
+ * value hasn't changed keep the text they were written with. The automatic `seed` gene has no
193
+ * line to write into, so it isn't saved.
194
+ */
195
+ export function writeGenes(program, values) {
196
+ const edits = [];
197
+ for (const g of program.genes) {
198
+ const v = values.get(g.fullName);
199
+ if (g.decl === undefined || v === undefined || valuesEqual(v, g.value))
200
+ continue;
201
+ const span = g.decl.value.span;
202
+ edits.push({ start: span.start, end: span.end, text: geneLiteral(g, v) });
203
+ }
204
+ if (edits.length === 0)
205
+ return program.text;
206
+ let text = program.text;
207
+ for (const e of edits.sort((p, q) => q.start - p.start)) {
208
+ text = text.slice(0, e.start) + e.text + text.slice(e.end);
209
+ }
210
+ return formatText(text).text ?? text;
211
+ }
212
+ /** A gene value written readably, and still within the gene's range. */
213
+ export function geneLiteral(g, v) {
214
+ if (g.kind === "number" && typeof v === "number") {
215
+ return numberLiteral(v, g.min, g.max, g.step);
216
+ }
217
+ if (g.kind === "vector" && isVec(v)) {
218
+ const [lo, hi] = [g.min, g.max];
219
+ const axis = (k) => numberLiteral(v[k], lo[k], hi[k], undefined);
220
+ return `(${axis("x")}, ${axis("y")}, ${axis("z")})`;
221
+ }
222
+ if (g.kind === "colour" && isColour(v)) {
223
+ const [lo, hi] = [g.min, g.max];
224
+ let h = Number(clampHue(v.h, g.hue).toFixed(1));
225
+ if (!inHueArc(h, g.hue))
226
+ h = clampHue(v.h, g.hue);
227
+ const ch = (k) => short(clamp(Number(v[k].toFixed(2)), lo[k], hi[k]));
228
+ const alpha = ch("a");
229
+ return `hsv(${short(h)}, ${ch("s")}, ${ch("v")}${alpha === "1" ? "" : `, ${alpha}`})`;
230
+ }
231
+ return formatValue(v);
232
+ }
233
+ function numberLiteral(v, min, max, step) {
234
+ if (step !== undefined)
235
+ return short(snap(v, min, max, step));
236
+ return short(clamp(Number(v.toPrecision(4)), min, max));
237
+ }
238
+ /** A number without floating-point noise, such as `0.3` rather than `0.30000000000000004`. */
239
+ function short(n) {
240
+ const s = String(Number(n.toPrecision(12)));
241
+ return s === "-0" ? "0" : s;
242
+ }
243
+ // ---------- helpers ----------
244
+ function isSeed(g) {
245
+ return g.fullName === "seed" && g.decl === undefined;
246
+ }
247
+ function clamp(x, lo, hi) {
248
+ return x < lo ? lo : x > hi ? hi : x;
249
+ }
250
+ /** Clamps into min..max, and onto the nearest whole step within it if the gene has one. */
251
+ function snap(v, min, max, step) {
252
+ v = clamp(v, min, max);
253
+ if (step === undefined)
254
+ return v;
255
+ let k = Math.round((v - min) / step);
256
+ if (min + k * step > max + 1e-9)
257
+ k--;
258
+ return min + k * step;
259
+ }
260
+ /** The hue itself if it's on the arc, otherwise the nearer end of the arc. */
261
+ function clampHue(h, arc) {
262
+ h = wrapHue(h);
263
+ if (inHueArc(h, arc))
264
+ return h;
265
+ const end = wrapHue(arc.start + arc.length);
266
+ return Math.abs(hueDelta(h, arc.start)) <= Math.abs(hueDelta(h, end)) ? arc.start : end;
267
+ }
268
+ //# sourceMappingURL=genetics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genetics.js","sourceRoot":"","sources":["../src/genetics.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,6 +7,8 @@ export { check, type CheckResult } from "./checker.js";
7
7
  export { format, formatText, type FormatResult } from "./format.js";
8
8
  export { build, buildBackground, DEFAULT_LIMITS, type BackgroundResult, type BuildOptions, type BuildResult, type Inputs, type LaidShape, type Limits, type MusicInputs, } from "./interpreter.js";
9
9
  export type { GeneInfo, GeneKind, GeneSection, HueArc } from "./genes.js";
10
+ export { breed, geneLiteral, morph, mutate, valuesOf, writeGenes, type GeneSet, type GeneticsOptions, type GeneValues, type MutateOptions, } from "./genetics.js";
11
+ export { mulberry32 } from "./noise.js";
10
12
  export { BUILTIN_CONSTANTS, BUILTIN_FUNCTIONS, isBuiltinName, type BuiltinFunction, } from "./builtins.js";
11
13
  export { hsv, rgb, hexColour, toRgb, mixColour, sampleGradient, NAMED_COLOURS } from "./colour.js";
12
14
  export { formatValue, typeOf, SHAPES, PATTERN_KINDS } from "./values.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,6CAA6C;AAC7C,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,mBAAmB,UAAU,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,KAAK,EACL,eAAe,EACf,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzE,YAAY,EACV,MAAM,EACN,QAAQ,EACR,OAAO,EACP,eAAe,EACf,SAAS,EACT,QAAQ,EACR,KAAK,EACL,GAAG,GACJ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,OAAO,EACP,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,IAAI,GACV,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,6CAA6C;AAC7C,eAAO,MAAM,cAAc,WAAW,CAAC;AAEvC,mBAAmB,UAAU,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,KAAK,EACL,eAAe,EACf,cAAc,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,MAAM,EACX,KAAK,WAAW,GACjB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EACL,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,QAAQ,EACR,UAAU,EACV,KAAK,OAAO,EACZ,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,KAAK,eAAe,GACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACzE,YAAY,EACV,MAAM,EACN,QAAQ,EACR,OAAO,EACP,eAAe,EACf,SAAS,EACT,QAAQ,EACR,KAAK,EACL,GAAG,GACJ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,gBAAgB,EAChB,OAAO,EACP,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,IAAI,GACV,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // The GenoCode language: lexer, parser, checker, formatter and interpreter
2
- // (docs/LANGUAGE.md). Genetics is added in roadmap phase 3.
2
+ // (docs/LANGUAGE.md), and genetics: mutating, breeding and morphing genes.
3
3
  /** The file extension for GenoCode files. */
4
4
  export const FILE_EXTENSION = ".genie";
5
5
  export { lex, KEYWORDS } from "./lexer.js";
@@ -7,6 +7,8 @@ export { parse } from "./parser.js";
7
7
  export { check } from "./checker.js";
8
8
  export { format, formatText } from "./format.js";
9
9
  export { build, buildBackground, DEFAULT_LIMITS, } from "./interpreter.js";
10
+ export { breed, geneLiteral, morph, mutate, valuesOf, writeGenes, } from "./genetics.js";
11
+ export { mulberry32 } from "./noise.js";
10
12
  export { BUILTIN_CONSTANTS, BUILTIN_FUNCTIONS, isBuiltinName, } from "./builtins.js";
11
13
  export { hsv, rgb, hexColour, toRgb, mixColour, sampleGradient, NAMED_COLOURS } from "./colour.js";
12
14
  export { formatValue, typeOf, SHAPES, PATTERN_KINDS } from "./values.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,4DAA4D;AAE5D,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AAGvC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAA8C,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAoB,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,KAAK,EACL,eAAe,EACf,cAAc,GAQf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWzE,OAAO,EACL,gBAAgB,EAChB,OAAO,GAKR,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,2EAA2E;AAE3E,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,QAAQ,CAAC;AAGvC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAA8C,MAAM,YAAY,CAAC;AACvF,OAAO,EAAE,KAAK,EAAoB,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,KAAK,EAAoB,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAqB,MAAM,aAAa,CAAC;AACpE,OAAO,EACL,KAAK,EACL,eAAe,EACf,cAAc,GAQf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,QAAQ,EACR,UAAU,GAKX,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAWzE,OAAO,EACL,gBAAgB,EAChB,OAAO,GAKR,MAAM,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@genocode/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "The GenoCode language: parser, checker, formatter, interpreter and genetics.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -912,6 +912,16 @@ A morph through several creatures (a loop) is a chain of these morphs between ne
912
912
  and B share a program, a morph is smooth all the way; when their programs differ, the creature
913
913
  changes shape at the halfway point.
914
914
 
915
+ ### 19.4 Saving
916
+
917
+ A creature that has been mutated, bred or morphed is saved as an ordinary creature file: its
918
+ program, with each gene's new value written into the gene's line. Nothing else in the program
919
+ changes, except that the file is laid out by the formatter, and a gene whose value hasn't changed
920
+ keeps the text it was written with. The new values are written readably: stepped numbers exactly,
921
+ other numbers to four significant figures, colours as `hsv(…)`, and choices by name, always within
922
+ the gene's range. The automatic `seed` gene has no line of its own, so it isn't saved yet: a saved
923
+ creature that uses `random` starts again from seed 0.
924
+
915
925
  ## 20. Building a creature
916
926
 
917
927
  1. **Checking.** The file is read and checked: syntax, names, gene rules, function rules, and types
@@ -0,0 +1,79 @@
1
+ creature Flowerball
2
+ // A ball of beads in rings, which opens out into a flat disc, crowned by five curling petals.
3
+ // Inspired by Flowerball, a DancerDNA creature.
4
+
5
+ gene open = 0.63 in 0..1 // 0 lays the beads flat in a disc; 1 rounds them into a ball and fills out the petals
6
+ gene gloss = 0.64 in 0..1 // how strong the highlights are
7
+ gene focus = 0.21 in 0..1 // how tight the highlights are
8
+ gene lift = 14.5 in -20..20 // how far from the beads the petals grow, as the creature opens
9
+
10
+ shine gloss
11
+ sharpness focus
12
+ beads
13
+ forward lift * open
14
+ pitch 90
15
+ repeat 5 {
16
+ petal
17
+ yaw 72
18
+ }
19
+
20
+ // Eight rings of beads around the heading. Ring 0 is the middle and has no beads.
21
+ part beads {
22
+ gene radius = 1 in 1..15 // the ball's radius, when it's fully open
23
+ gene bead = 0.92 in 0.1..1 // the size of each bead
24
+ gene inner = hsv(127, 0.45, 0.3) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
25
+ gene second = hsv(41, 0.95, 0.73) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
26
+ gene third = hsv(333, 0.96, 0.21) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
27
+ gene outer = hsv(59, 0.8, 0.95) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
28
+
29
+ let skin = gradient(inner, second, third, outer)
30
+ shape ball
31
+ repeat 8 as r {
32
+ let a = 180 * r / 8
33
+ colour skin(r / 8)
34
+ // Flat, ring r is r from the middle. As a ball, it's a circle of latitude.
35
+ let spread = mix(r, sin(a) * radius, open)
36
+ let height = open * cos(a) * radius
37
+ let circle = tau * r
38
+ repeat floor(circle) as s {
39
+ let t = 360 * s / circle
40
+ branch {
41
+ move (spread * cos(t), spread * sin(t), height)
42
+ lay { grow bead }
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ // A curling chain of stretched beads, fattest in the middle.
49
+ part petal {
50
+ gene curl = -0.86 in -2.5..2.5 // how far the petal curls, and which way
51
+ gene tip = hsv(285, 0.66, 0.3) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
52
+ gene edge = hsv(2, 0.43, 0.96) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
53
+ gene flank = hsv(90, 0.93, 0.61) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
54
+ gene heart = hsv(131, 0.56, 0.49) in hsv(0, 0.4, 0)..hsv(360, 1, 1)
55
+
56
+ let skin = gradient(tip, edge, flank, heart)
57
+ branch {
58
+ forward 2.5
59
+ pitch -36
60
+ yaw -45
61
+ roll -30
62
+ shape ball
63
+ for i from 1 to 29 {
64
+ let swell = bump(i / 30)
65
+ colour skin(swell)
66
+ yaw 6
67
+ branch {
68
+ forward 0.1
69
+ pitch 90 * swell * curl
70
+ lay { grow (open, open, open * 6 * (swell + 1)) }
71
+ }
72
+ move (0.4 * open, 0, 0)
73
+ }
74
+ }
75
+ }
76
+
77
+ background {
78
+ fill gradient(hsv(250, 0.5, 0.12), hsv(200, 0.45, 0.4))
79
+ }
@@ -0,0 +1,102 @@
1
+ creature StarBurstShell
2
+ // A spiraling geometric shell composed of bead spikes that unfurls into a sprawling celestial star.
3
+ // Fixed color gene ranges and reserved keyword variables.
4
+
5
+ gene unfurl = 0.45 in 0..1 // 0 packs the spikes into a tight spiral shell; 1 explodes them into a star
6
+ gene gloss = 0.75 in 0..1 // intensity of the metallic shell sheen
7
+ gene focus = 0.40 in 0..1 // sharpness of the light reflections
8
+ gene heightOffset = 8.0 in -15..15 // vertical expansion amplitude as it opens
9
+
10
+ shine gloss
11
+ sharpness focus
12
+
13
+ // Wrap the top-level part call in a branch to protect downstream rendering
14
+ branch {
15
+ shellSpikes
16
+ }
17
+
18
+ forward heightOffset * unfurl
19
+ pitch 90
20
+
21
+ // Generate 6 primary crown spikes circling the top axis
22
+ repeat 6 {
23
+ branch {
24
+ crownSpike
25
+ }
26
+ yaw 60
27
+ }
28
+
29
+ // The core body structure: 10 concentric, winding layers of beads
30
+ part shellSpikes {
31
+ gene maxRadius = 12 in 5..20
32
+ gene baseBeadSize = 0.75 in 0.2..1.5
33
+
34
+ // Galactic neon palette gradient with mandatory range specifications
35
+ gene coreColor = hsv(240, 0.85, 0.2) in hsv(0, 0, 0)..hsv(360, 1, 1) // Deep space blue
36
+ gene midColor1 = hsv(300, 0.90, 0.5) in hsv(0, 0, 0)..hsv(360, 1, 1) // Cosmic magenta
37
+ gene midColor2 = hsv(340, 0.95, 0.8) in hsv(0, 0, 0)..hsv(360, 1, 1) // Electric pink
38
+ gene outerColor = hsv(15, 0.80, 0.95) in hsv(0, 0, 0)..hsv(360, 1, 1) // Nebula orange
39
+
40
+ let skin = gradient(coreColor, midColor1, midColor2, outerColor)
41
+ shape ball
42
+
43
+ repeat 10 as layer {
44
+ let latAngle = 180 * layer / 10
45
+ colour skin(layer / 10)
46
+
47
+ // As unfurl approaches 1, structural layout transitions from flat spirals to a wide-latitude sphere
48
+ let distance = mix(layer, sin(latAngle) * maxRadius, unfurl)
49
+ let verticalZ = unfurl * cos(latAngle) * maxRadius
50
+ let stepCount = tau * layer
51
+
52
+ repeat floor(stepCount) as s {
53
+ let lonAngle = 360 * s / stepCount
54
+
55
+ branch {
56
+ // Positional placement using standard trigonometric displacement
57
+ move (distance * cos(lonAngle), distance * sin(lonAngle), verticalZ)
58
+ lay { grow baseBeadSize }
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ // A twisting, needle-sharp spike branch that reacts heavily to the unfurl gene
65
+ part crownSpike {
66
+ gene twistFactor = 1.25 in -3..3 // how sharply the crown arms curve outward
67
+
68
+ // Crown color parameters with mandatory range specifications
69
+ gene rootColor = hsv(160, 0.70, 0.6) in hsv(0, 0, 0)..hsv(360, 1, 1) // Turquoise heart
70
+ gene bodyColor = hsv(200, 0.80, 0.8) in hsv(0, 0, 0)..hsv(360, 1, 1) // Cyan mid-section
71
+ gene flareColor = hsv(280, 0.85, 0.7) in hsv(0, 0, 0)..hsv(360, 1, 1) // Violet edge
72
+ gene apexColor = hsv(0, 0.0, 1.0) in hsv(0, 0, 0)..hsv(360, 1, 1) // Pure white tips
73
+
74
+ let skin = gradient(rootColor, bodyColor, flareColor, apexColor)
75
+
76
+ branch {
77
+ forward 3.0
78
+ pitch -25
79
+ yaw 15
80
+ roll 45
81
+ shape ball
82
+
83
+ // Iteratively chain 25 progressively scaling segments to build a fine tip
84
+ for segment from 1 to 25 {
85
+ let taper = bump(segment / 26) // custom envelope tracking
86
+ colour skin(taper)
87
+
88
+ yaw 8
89
+ branch {
90
+ forward 0.15
91
+ pitch 45 * taper * twistFactor
92
+ // Drastically changes length/width profile when unrolled
93
+ lay { grow (unfurl, unfurl, unfurl * 4 * (taper + 0.5)) }
94
+ }
95
+ move (0.35 * unfurl, 0, 0)
96
+ }
97
+ }
98
+ }
99
+
100
+ background {
101
+ fill gradient(hsv(275, 0.6, 0.08), hsv(220, 0.5, 0.25))
102
+ }
@@ -0,0 +1,102 @@
1
+ creature StarBurstShell
2
+ // A spiraling geometric shell composed of bead spikes that unfurls into a sprawling celestial star.
3
+ // Fixed color gene ranges and reserved keyword variables.
4
+
5
+ gene unfurl = 0.2016 in 0..1 // 0 packs the spikes into a tight spiral shell; 1 explodes them into a star
6
+ gene gloss = 0.5104 in 0..1 // intensity of the metallic shell sheen
7
+ gene focus = 0.3599 in 0..1 // sharpness of the light reflections
8
+ gene heightOffset = 9.545 in -15..15 // vertical expansion amplitude as it opens
9
+
10
+ shine gloss
11
+ sharpness focus
12
+
13
+ // Wrap the top-level part call in a branch to protect downstream rendering
14
+ branch {
15
+ shellSpikes
16
+ }
17
+
18
+ forward heightOffset * unfurl
19
+ pitch 90
20
+
21
+ // Generate 6 primary crown spikes circling the top axis
22
+ repeat 6 {
23
+ branch {
24
+ crownSpike
25
+ }
26
+ yaw 60
27
+ }
28
+
29
+ // The core body structure: 10 concentric, winding layers of beads
30
+ part shellSpikes {
31
+ gene maxRadius = 10.95 in 5..20
32
+ gene baseBeadSize = 0.6653 in 0.2..1.5
33
+
34
+ // Galactic neon palette gradient with mandatory range specifications
35
+ gene coreColor = hsv(240, 0.85, 0.2) in hsv(0, 0, 0)..hsv(360, 1, 1) // Deep space blue
36
+ gene midColor1 = hsv(300, 0.87, 0.49) in hsv(0, 0, 0)..hsv(360, 1, 1) // Cosmic magenta
37
+ gene midColor2 = hsv(35.9, 0.81, 0.71) in hsv(0, 0, 0)..hsv(360, 1, 1) // Electric pink
38
+ gene outerColor = hsv(38.8, 0.79, 0.75) in hsv(0, 0, 0)..hsv(360, 1, 1) // Nebula orange
39
+
40
+ let skin = gradient(coreColor, midColor1, midColor2, outerColor)
41
+ shape ball
42
+
43
+ repeat 10 as layer {
44
+ let latAngle = 180 * layer / 10
45
+ colour skin(layer / 10)
46
+
47
+ // As unfurl approaches 1, structural layout transitions from flat spirals to a wide-latitude sphere
48
+ let distance = mix(layer, sin(latAngle) * maxRadius, unfurl)
49
+ let verticalZ = unfurl * cos(latAngle) * maxRadius
50
+ let stepCount = tau * layer
51
+
52
+ repeat floor(stepCount) as s {
53
+ let lonAngle = 360 * s / stepCount
54
+
55
+ branch {
56
+ // Positional placement using standard trigonometric displacement
57
+ move (distance * cos(lonAngle), distance * sin(lonAngle), verticalZ)
58
+ lay { grow baseBeadSize }
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ // A twisting, needle-sharp spike branch that reacts heavily to the unfurl gene
65
+ part crownSpike {
66
+ gene twistFactor = 1.161 in -3..3 // how sharply the crown arms curve outward
67
+
68
+ // Crown color parameters with mandatory range specifications
69
+ gene rootColor = hsv(184.3, 0.71, 0.68) in hsv(0, 0, 0)..hsv(360, 1, 1) // Turquoise heart
70
+ gene bodyColor = hsv(184.8, 0.8, 0.76) in hsv(0, 0, 0)..hsv(360, 1, 1) // Cyan mid-section
71
+ gene flareColor = hsv(253.4, 0.74, 0.7) in hsv(0, 0, 0)..hsv(360, 1, 1) // Violet edge
72
+ gene apexColor = hsv(0, 0.03, 1) in hsv(0, 0, 0)..hsv(360, 1, 1) // Pure white tips
73
+
74
+ let skin = gradient(rootColor, bodyColor, flareColor, apexColor)
75
+
76
+ branch {
77
+ forward 3.0
78
+ pitch -25
79
+ yaw 15
80
+ roll 45
81
+ shape ball
82
+
83
+ // Iteratively chain 25 progressively scaling segments to build a fine tip
84
+ for segment from 1 to 25 {
85
+ let taper = bump(segment / 26) // custom envelope tracking
86
+ colour skin(taper)
87
+
88
+ yaw 8
89
+ branch {
90
+ forward 0.15
91
+ pitch 45 * taper * twistFactor
92
+ // Drastically changes length/width profile when unrolled
93
+ lay { grow (unfurl, unfurl, unfurl * 4 * (taper + 0.5)) }
94
+ }
95
+ move (0.35 * unfurl, 0, 0)
96
+ }
97
+ }
98
+ }
99
+
100
+ background {
101
+ fill gradient(hsv(275, 0.6, 0.08), hsv(220, 0.5, 0.25))
102
+ }