@genocode/core 0.1.1 → 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.
- package/dist/genetics.d.ts +45 -0
- package/dist/genetics.d.ts.map +1 -0
- package/dist/genetics.js +268 -0
- package/dist/genetics.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/reference/LANGUAGE.md +10 -0
- package/reference/creatures/StarBurstShell.genie +102 -0
- package/reference/creatures/StarBurstShell9.genie +102 -0
|
@@ -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"}
|
package/dist/genetics.js
ADDED
|
@@ -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";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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)
|
|
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,
|
|
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
package/reference/LANGUAGE.md
CHANGED
|
@@ -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,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
|
+
}
|