···11+# underevaluate
22+* hermes' gambling <ne,qqqeeaqq>
33+* find other things
44+# in general
55+* make checklist of hexic features
66+- [x] patchworks
77+- [x] murmur
88+- [x] greater reveal
99+- [ ] mediaweave
1010+* find other neat things to do
1111+1212+---
1313+old todo list:
1414+115# before next release
216* `ktwznkmp` making Noetic Gateway always go to a demiplane's center
317* `ktwznkmp` special demiplane iota handling
+237-205
build.gradle.kts
···66import kotlin.io.path.exists
77import kotlin.io.path.readText
88import groovy.json.JsonOutput
99+import `java.nio`.file.Files;
1010+import kotlin.io.path.deleteIfExists
9111012plugins {
1113 id("fabric-loom") version "1.13-SNAPSHOT"
···1618 id("org.eu.net.pool.mc-plugin") version "0.1.1"
1719}
18201919-try {
2020- tasks.named("downloadRenderDoc") {
2121- setProperty("output", file("$buildDir/renderdoc_1.37.tar.gz"))
2222- }
2121+allprojects {
2222+ try {
2323+ tasks.named("downloadRenderDoc") {
2424+ setProperty("output", file("$buildDir/renderdoc_1.37.tar.gz"))
2525+ }
23262424- tasks.named("extractRenderDoc") {
2525- enabled = false
2626- }
2727+ tasks.named("extractRenderDoc") {
2828+ enabled = false
2929+ }
27302828- val erd by tasks.register<Sync>("myExtractRenderDoc") {
2929- dependsOn("downloadRenderDoc")
3030- from(tarTree(resources.gzip("$buildDir/renderdoc_1.37.tar.gz")))
3131- into("$buildDir/renderdoc")
3131+ val erd by tasks.register<Sync>("myExtractRenderDoc") {
3232+ dependsOn("downloadRenderDoc")
3333+ from(tarTree(resources.gzip("$buildDir/renderdoc_1.37.tar.gz")))
3434+ into("$buildDir/renderdoc")
3535+ }
3636+3737+ tasks.named("runClientRenderDoc") {
3838+ dependsOn(erd)
3939+ }
4040+ } catch (ignored: UnknownTaskException) {}
4141+}
4242+4343+val release: Boolean = !System.getenv("release").isNullOrEmpty()
4444+allprojects {
4545+ val p = P(project)
4646+ val modid: String by project.properties
4747+ ext.set("p", p)
4848+ version = project.property("mod_version") as String
4949+ if (!release) version = "${version}+${p.commit_id.take(7)}"
5050+ group = rootProject.property("maven_group") as String
5151+ println("configuring $modid ($project) v$version @ $group")
5252+ plugins.withId("java") {
5353+ base {
5454+ archivesName.set(modid)
5555+ }
5656+ java {
5757+ toolchain.languageVersion = JavaLanguageVersion.of(17)
5858+ withSourcesJar()
5959+ }
6060+6161+ tasks.named<Jar>("jar").configure {
6262+ from("LICENSE") {
6363+ rename { "LICENSE_$modid" }
6464+ }
6565+ duplicatesStrategy = DuplicatesStrategy.WARN
6666+ }
3267 }
33683434- tasks.named("runClientRenderDoc") {
3535- dependsOn(erd)
6969+ plugins.withId("scala") {
7070+ scala {
7171+ scalaVersion = "3.7.1"
7272+ }
3673 }
3737-} catch (ignored: UnknownTaskException) {}
38743939-loom.runs["client"].programArgs += listOf("--username", "Player", "--uuid", "bd346dd5-ac1c-427d-87e8-73bdd4bf3e13")
7575+ plugins.withId("fabric-loom") {
7676+ loom {
7777+ splitEnvironmentSourceSets()
7878+ runs["client"].programArgs += listOf("--username", "Player", "--uuid", "9e1b34e3-8031-4623-8918-eb7914ab564b")
40794141-//tasks.withType<RenderDocR>()
8080+ mods {
8181+ register(modid) {
8282+ sourceSet("main")
8383+ sourceSet("client")
8484+ }
8585+ }
42864343-val release: Boolean = !System.getenv("release").isNullOrEmpty()
4444-val p = P(project)
4545-project.ext.set("p", p)
4646-version = project.property("mod_version") as String
4747-val py_version: String by project.properties
4848-val wheelPath = file("dist/hexdoc_hexic-$version.$py_version-py3-none-any.whl")
4949-if (!release) version = "$version+${p.commit_id.take(7)}"
5050-group = project.property("maven_group") as String
8787+ mixin.useLegacyMixinAp = false
8888+ }
51895252-base {
5353- archivesName.set(project.property("archives_base_name") as String)
5454-}
9090+ fabricApi {
9191+ configureTests {
9292+ modId = modid
9393+ eula = true
9494+ }
9595+ }
55965656-val targetJavaVersion = 17
5757-java {
5858- toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
5959- // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
6060- // if it is present.
6161- // If you remove this line, sources will not be generated.
6262- withSourcesJar()
6363-}
9797+ dependencies {
9898+ modLocalRuntime("maven.modrinth:ears:1.4.7+fabric-1.20")
9999+ }
641006565-scala {
6666- scalaVersion = "3.7.1"
6767-}
101101+ if (project != rootProject) {
102102+ tasks.named("runClient") {
103103+ doFirst {
104104+ val rootOptions = rootProject.file("run/options.txt").toPath()
105105+ val options = file("run/options.txt").toPath()
106106+ options.deleteIfExists()
107107+ Files.createSymbolicLink(options, rootOptions)
108108+ }
109109+ }
110110+ }
681116969-loom {
7070- splitEnvironmentSourceSets()
112112+ tasks.processResources {
113113+ val bookRoot = destinationDir.resolve("assets/hexcasting/patchouli_books/thehexbook")
114114+ val langRoot = destinationDir.resolve("assets/$modid/lang")
711157272- mods {
7373- register("hexic") {
7474- sourceSet("main")
7575- sourceSet("client")
116116+ doLast {
117117+ bookRoot.list()?.forEach { lang ->
118118+ val langFile = langRoot.resolve("$lang.json")
119119+ if (langFile.exists()) {
120120+ val entries = JsonSlurper().parseText(langFile.readText()) as MutableMap<String, String>
121121+ var n = 0
122122+ for (bookFile in bookRoot.resolve(lang).walkTopDown()) {
123123+ if (bookFile.isFile) {
124124+ val json = JsonSlurper().parseText(bookFile.readText())
125125+ if (json !is Map<*, *>) continue
126126+ json as MutableMap<Any, Any>
127127+ val name = json["name"]
128128+ if (name is String) {
129129+ entries["text.$modid.book.${n}"] = name
130130+ json["name"] = "text.$modid.book.${n}"
131131+ n++
132132+ }
133133+ val pages = json["pages"]
134134+ if (pages !is MutableList<*>) continue
135135+ pages as MutableList<Any>
136136+ for (i in pages.indices) {
137137+ val page = pages[i]
138138+ if (page is String) {
139139+ entries["text.$modid.book.${n}"] = page
140140+ pages[i] = "text.$modid.book.${n}"
141141+ n++
142142+ } else if (page is MutableMap<*, *>) {
143143+ page as MutableMap<Any, Any>
144144+ for (key in listOf("text", "title", "header")) {
145145+ val text = page[key]
146146+ if (text != null && text is String) {
147147+ entries["text.$modid.book.${n}"] = text
148148+ page[key] = "text.$modid.book.${n}"
149149+ n++
150150+ }
151151+ }
152152+ }
153153+ }
154154+ bookFile.writeText(JsonOutput.toJson(json))
155155+ }
156156+ }
157157+ langFile.writeText(JsonOutput.toJson(entries))
158158+ }
159159+ }
160160+ }
76161 }
77162 }
7878-7979- mixin.useLegacyMixinAp = false
163163+ println("configured $project: release=$release, configured version: $version ($group)")
80164}
165165+val p: P by ext
166166+val py_version: String by project.properties
167167+val wheelPath = file("dist/hexdoc_hexic-$version.$py_version-py3-none-any.whl")
8116882169fabricApi {
83170 configureDataGeneration {
···97184// into("$buildDir/hexxy4")
98185//}
99186100100-repositories {
101101- fun exactRepo(url: String, vararg groups: String, recursive: Boolean = true) {
102102- exclusiveContent {
103103- forRepository {
104104- maven(url)
105105- }
106106- filter {
107107- for (group in groups) {
108108- if (recursive) {
109109- includeGroupAndSubgroups(group)
110110- } else {
111111- includeGroup(group)
187187+allprojects {
188188+ repositories {
189189+ fun exactRepo(url: String, vararg groups: String, recursive: Boolean = true) {
190190+ exclusiveContent {
191191+ forRepository {
192192+ maven(url)
193193+ }
194194+ filter {
195195+ for (group in groups) {
196196+ if (recursive) {
197197+ includeGroupAndSubgroups(group)
198198+ } else {
199199+ includeGroup(group)
200200+ }
112201 }
113202 }
114203 }
115204 }
116116- }
117205118118- mavenCentral()
119119- exactRepo("https://api.modrinth.com/maven",
120120- "maven.modrinth")
121121- exactRepo("https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/",
122122- "com.eliotlash.mclib",
123123- "software.bernie.geckolib")
124124- exactRepo("https://jitpack.io/",
125125- "com.github.Chocohead",
126126- "com.github.LlamaLad7",
127127- "com.github.Virtuoel",
128128- "com.github.mattidragon")
129129- exactRepo("https://maven.blamejared.com/",
130130- "at.petra-k",
131131- "com.samsthenerd.inline",
132132- "gay.object",
133133- "miyucomics.hexpose",
134134- "net.darkhax.openloader",
135135- "vazkii.patchouli")
136136- exactRepo("https://maven.hexxy.media/",
137137- "io.github.tropheusj",
138138- "ram.talia")
139139- exactRepo("https://maven.jamieswhiteshirt.com/libs-release/",
140140- "com.jamieswhiteshirt")
141141- exactRepo("https://maven.kosmx.dev/",
142142- "dev.kosmx")
143143- exactRepo("https://maven.ladysnake.org/releases/",
144144- "dev.onyxstudios")
145145- exactRepo("https://maven.pool.net.eu.org/",
146146- "dev.kineticcat.hexportation",
147147- "miyucomics.hexcellular",
148148- "miyucomics.hexical",
149149- "miyucomics.overevaluate",
150150- "org.eu.net.pool",
151151- "poollovernathan")
152152- exactRepo("https://maven.shedaniel.me/",
153153- "dev.architectury",
154154- "me.shedaniel")
155155- exactRepo("https://maven.terraformersmc.com/",
156156- "com.terraformersmc",
157157- "dev.emi")
158158- exactRepo("https://repo.sleeping.town/",
159159- "com.unascribed")
160160- exactRepo("https://masa.dy.fi/maven/",
161161- "carpet")
162162- exactRepo("https://maven.nucleoid.xyz/",
163163- "xyz.nucleoid")
206206+ mavenCentral()
207207+ exactRepo("https://api.modrinth.com/maven",
208208+ "maven.modrinth")
209209+ exactRepo("https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/",
210210+ "com.eliotlash.mclib",
211211+ "software.bernie.geckolib")
212212+ exactRepo("https://jitpack.io/",
213213+ "com.github.Chocohead",
214214+ "com.github.LlamaLad7",
215215+ "com.github.Virtuoel",
216216+ "com.github.mattidragon")
217217+ exactRepo("https://maven.blamejared.com/",
218218+ "at.petra-k",
219219+ "com.samsthenerd.inline",
220220+ "gay.object",
221221+ "miyucomics.hexpose",
222222+ "net.darkhax.openloader",
223223+ "vazkii.patchouli")
224224+ exactRepo("https://maven.hexxy.media/",
225225+ "io.github.tropheusj",
226226+ "ram.talia")
227227+ exactRepo("https://maven.jamieswhiteshirt.com/libs-release/",
228228+ "com.jamieswhiteshirt")
229229+ exactRepo("https://maven.kosmx.dev/",
230230+ "dev.kosmx")
231231+ exactRepo("https://maven.ladysnake.org/releases/",
232232+ "dev.onyxstudios")
233233+ exactRepo("https://pool.net.eu.org/",
234234+ "dev.kineticcat.hexportation",
235235+ "miyucomics.hexcellular",
236236+ "miyucomics.hexical",
237237+ "miyucomics.overevaluate",
238238+ "org.eu.net.pool",
239239+ "poollovernathan")
240240+ exactRepo("https://maven.shedaniel.me/",
241241+ "dev.architectury",
242242+ "me.shedaniel")
243243+ exactRepo("https://maven.terraformersmc.com/",
244244+ "com.terraformersmc",
245245+ "dev.emi")
246246+ exactRepo("https://repo.sleeping.town/",
247247+ "com.unascribed")
248248+ exactRepo("https://masa.dy.fi/maven/",
249249+ "carpet")
250250+ exactRepo("https://maven.nucleoid.xyz/",
251251+ "xyz.nucleoid")
252252+ }
164253}
165254166255fun download(url: String, name: String = file(url).name): Download {
···260349261350 val minecraft_version = "1.20.1"
262351 modDepends(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:0.5.0")!!)!!)
263263- modDepends(modImplementation("net.fabricmc.fabric-api:fabric-api:${project.property("fabric_version")}")!!)
264264- modDepends(include(modImplementation("poollovernathan.fabric:mod-tools:1.1.5+1.20.1")!!)!!)
265265- include(api("org.scala-lang:scala3-library_3:3.7.1")!!)
266266- include(api("org.scala-lang:scala-library:2.13.6")!!)
267267- modDepends(modImplementation("at.petra-k.hexcasting:hexcasting-fabric-$minecraft_version:0.11.2-pre-751")!!)
268268- modImplementation("at.petra-k.paucal:paucal-fabric-$minecraft_version:0.6.0-pre-118")
352352+ implementation(project(":util", "namedElements"))
353353+ modImplementation("io.github.tropheusj:serialization-hooks:0.4.99999")
354354+ modImplementation("poollovernathan.fabric:mod-tools:1.1.5+1.20.1")
355355+ modImplementation("at.petra-k.hexcasting:hexcasting-fabric-$minecraft_version:0.11.3")
269356 modImplementation("com.samsthenerd.inline:inline-fabric:$minecraft_version-1.0.1")
270357 modDepends(include(implementation("com.github.Chocohead:Fabric-ASM:v2.3")!!)!!)
271358 modCompileOnly("dev.kineticcat.hexportation:hexportation-fabric-1.20.1-fabric-fabric:0.0.3")
272359 modCompileOnly("carpet:fabric-carpet:1.20-1.+")
360360+ modLocalRuntime("maven.modrinth:lithium:mc1.20.1-0.11.4-fabric")
273361// modRuntimeOnly("carpet:fabric-carpet:1.20-1.+")
274362 compat("gay.object.ioticblocks:ioticblocks-fabric:1.0.2+1.20.1")
275275- modImplementation("io.github.tropheusj:serialization-hooks:0.4.99999")
276363 modImplementation(files("./libs/oneironaut-fabric-1.20.1-0.5.0-476cee2.jar"))
277364 compat("maven.modrinth:hexcassettes:1.1.4")
278365 modLocalRuntime("maven.modrinth:trinkets:3.7.2")
···290377 include(modApi("xyz.nucleoid:fantasy:0.4.11+1.20-rc1")!!)
291378// modImplementation("miyucomics:hexpose:1.0.0")
292379// modImplementation(files("hexical-2.0.0.jar"))
293293- val cardinal_version = "5.2.3"
294294- modApi("dev.onyxstudios.cardinal-components-api:cardinal-components-base:$cardinal_version")
295295- modDepends(modApi("dev.onyxstudios.cardinal-components-api:cardinal-components-block:$cardinal_version")!!)
296296- modDepends(modApi("dev.onyxstudios.cardinal-components-api:cardinal-components-entity:$cardinal_version")!!)
297297- modDepends(modApi("dev.onyxstudios.cardinal-components-api:cardinal-components-item:$cardinal_version")!!)
298298- modDepends(modApi("dev.onyxstudios.cardinal-components-api:cardinal-components-level:$cardinal_version")!!)
299299- modDepends(modApi("dev.onyxstudios.cardinal-components-api:cardinal-components-world:$cardinal_version")!!)
300300- modRuntimeOnly("dev.onyxstudios.cardinal-components-api:cardinal-components-api:$cardinal_version")
301380 include(implementation("net.bytebuddy:byte-buddy:1.17.7")!!)
302381 include(implementation("net.bytebuddy:byte-buddy-agent:1.17.7")!!)
303382···356435 }
357436 }
358437359359- entrypoint("org.eu.net.pool.hexic.Hexic\$package::init")
360360- entrypoint("org.eu.net.pool.hexic.client.HexicClient\$package::init", Environment.Client)
361361- entrypoint("fabric-datagen", "org.eu.net.pool.hexic.client.HexicClient\$package::datagen")
362362- entrypoint("mm:early_risers", "org.eu.net.pool.hexic.EarlyRiser\$package::warCrimes")
438438+ conflicts("valkyrienskies", "*") // need to figure out how to create dimensions without causing a crash
439439+440440+ entrypoint("org.eu.net.pool.hexic.main\$package::init")
441441+ entrypoint("org.eu.net.pool.hexic.client.main\$package::init", Environment.Client)
442442+ entrypoint("fabric-datagen", "org.eu.net.pool.hexic.client.main\$package::datagen")
443443+ entrypoint("mm:early_risers", "org.eu.net.pool.hexic.early_riser\$package::warCrimes")
363444 entrypoint("cardinal-components", "org.eu.net.pool.hexic.ComponentInit")
364445 mixins("hexic.mixins.json")
365446 mixins("hexic.client.mixins.json", Environment.Client)
···375456 dependsOn(cloth)
376457 dependsOn(*downloadedBags.values.toTypedArray())
377458 val itemsRoot = destinationDir.resolve("assets/hexic/textures/item")
378378- val langRoot = destinationDir.resolve("assets/hexic/lang")
379379- val bookRoot = destinationDir.resolve("assets/hexcasting/patchouli_books/thehexbook")
380459 doLast {
381460 for ((name, color) in colors) {
382461 exec {
···441520 }
442521 }
443522444444- doLast {
445445- for (lang in bookRoot.list()) {
446446- val langFile = langRoot.resolve("$lang.json")
447447- if (langFile.exists()) {
448448- val entries = JsonSlurper().parseText(langFile.readText()) as MutableMap<String, String>
449449- var n = 0
450450- for (bookFile in bookRoot.resolve(lang).walkTopDown()) {
451451- if (bookFile.isFile) {
452452- val json = JsonSlurper().parseText(bookFile.readText())
453453- if (json !is Map<*, *>) continue
454454- json as MutableMap<Any, Any>
455455- val name = json["name"]
456456- if (name is String) {
457457- entries["text.hexic.book.${n}"] = name
458458- json["name"] = "text.hexic.book.${n}"
459459- n++
460460- }
461461- val pages = json["pages"]
462462- if (pages !is MutableList<*>) continue
463463- pages as MutableList<Any>
464464- for (i in pages.indices) {
465465- val page = pages[i]
466466- if (page is String) {
467467- entries["text.hexic.book.${n}"] = page
468468- pages[i] = "text.hexic.book.${n}"
469469- n++
470470- } else if (page is MutableMap<*, *>) {
471471- page as MutableMap<Any, Any>
472472- for (key in listOf("text", "title", "header")) {
473473- val text = page[key]
474474- if (text != null && text is String) {
475475- entries["text.hexic.book.${n}"] = text
476476- page[key] = "text.hexic.book.${n}"
477477- n++
478478- }
479479- }
480480- }
481481- }
482482- bookFile.writeText(JsonOutput.toJson(json))
483483- }
484484- }
485485- langFile.writeText(JsonOutput.toJson(entries))
486486- }
487487- }
488488- }
489489-490523 eachFile {
491524 if (name.endsWith(".ase")) {
492525 exec {
···502535 }
503536}
504537505505-tasks.withType<AbstractArchiveTask> {
506506- isPreserveFileTimestamps = false
507507- isReproducibleFileOrder = true
508508-}
509509-510510-tasks.withType<JavaCompile>().configureEach {
511511- // ensure that the encoding is set to UTF-8, no matter what the system default is
512512- // this fixes some edge cases with special characters not displaying correctly
513513- // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
514514- // If Javadoc is generated, this must be specified in that task too.
515515- options.encoding = "UTF-8"
516516- options.release.set(targetJavaVersion)
517517-}
538538+allprojects {
539539+ tasks.withType<AbstractArchiveTask> {
540540+ isPreserveFileTimestamps = false
541541+ isReproducibleFileOrder = true
542542+ }
518543519519-tasks.withType<ScalaCompile>().configureEach {
520520- scalaCompileOptions.additionalParameters.addAll(listOf("-explain-cyclic", "-Ydebug-cyclic", "-experimental", "-feature", "-Ycc-debug"))
521521-}
544544+ tasks.withType<JavaCompile>().configureEach {
545545+ // ensure that the encoding is set to UTF-8, no matter what the system default is
546546+ // this fixes some edge cases with special characters not displaying correctly
547547+ // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
548548+ // If Javadoc is generated, this must be specified in that task too.
549549+ options.encoding = "UTF-8"
550550+ options.release.set(17)
551551+ }
522552523523-tasks.jar {
524524- from("LICENSE") {
525525- rename { "${it}_${project.base.archivesName}" }
553553+ tasks.withType<ScalaCompile>().configureEach {
554554+ scalaCompileOptions.additionalParameters.addAll(listOf("-explain-cyclic", "-Ydebug-cyclic", "-experimental", "-feature", "-Ycc-debug"))
526555 }
527527- duplicatesStrategy = DuplicatesStrategy.WARN
528556}
529557530558val wheelFiles by lazy {
···705733}
706734707735// configure the maven publication
708708-publishing {
709709- publications {
710710- create<MavenPublication>("mavenJava") {
711711- artifactId = project.property("archives_base_name") as String
712712- from(components["java"])
713713- }
714714- }
736736+allprojects {
737737+ afterEvaluate {
738738+ publishing {
739739+ publications {
740740+ create<MavenPublication>("mavenJava") {
741741+ artifactId = project.property("modid") as String
742742+ from(components["java"])
743743+ }
744744+ }
715745716716- // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
717717- repositories {
718718- // Add repositories to publish to here.
719719- // Notice: This block does NOT have the same function as the block in the top level.
720720- // The repositories here will be used for publishing your artifact, not for
721721- // retrieving dependencies.
746746+ // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
747747+ repositories {
748748+ maven("https://pool.net.eu.org/") {
749749+ name = "poolMaven"
750750+ credentials(PasswordCredentials::class.java)
751751+ }
752752+ }
753753+ }
722754 }
723755}
+2-2
gradle.properties
···88loader_version=0.16.14
99scala_loader_version=0.3.1.11
1010# Mod Properties
1111-mod_version=1.4.7-pre.1
1111+modid=hexic
1212+mod_version=2.0.0-alpha.01
1213py_version=1.0
1314maven_group=org.eu.net.pool
1414-archives_base_name=hexic
1515# Dependencies
1616# check this on https://modmuss50.me/fabric.html
1717fabric_version=0.92.6+1.20.1
···11+{
22+ "hexcasting.action.hexxytounge:murmur": "Murmur Reflection",
33+ "book.hexxytounge.page.murmur": "Finds the region of my mind known as the 'chat box' and adds its contents to the stack. If it cannot be found, adds Null instead."
44+}
···77 "Thus, I've devised a new pattern of my own. It's similar to $(l:hexcasting:patterns/basics#hexcasting:print)$(action)Reveal/$, but the message is lodged well within my mind, and I forget it instantly if I replace it with something else. It can also take a list of messages, for convenience.",
88 {
99 "type": "hexcasting:pattern",
1010- "anchor": "hexic:reveal",
1111- "op_id": "hexic:reveal",
1010+ "anchor": "hexxytounge:reveal",
1111+ "op_id": "hexxytounge:reveal",
1212 "input": "[iota] | iota",
1313 "output": "",
1414- "text": "Takes a list of iotas (or a single non-iota, which is treated as a list with one element) and displays them permanently to the caster. Displayed iotas survive all methods that would clear a normal Reveal, and can only be cleared by another casting of Greater Reveal."
1414+ "text": "Takes a list of iotas (or a single non-iota, which is treated as a list with one element) and embeds them in my mind persistently. Displayed iotas survive all methods that would clear a normal Reveal, and can only be cleared by another casting of Greater Reveal or my untimely demise."
1515 },
1616 "$(o)To be a Hexcaster is to glimpse a truth that might best be hidden./$"
1717 ]
···77 "Maps are an efficient structure holding pairings of some iota to some other iota. While this is perfectly possible using merely list operations, dedicated map iotas use some arcane substance called a '$(thing)Hash/$'. While this doesn't reduce the $(o)operations/$ required to access a map, it desperately reduces the load on Nature, nearing O(1) for most access.",
88 {
99 "type": "hexcasting:pattern",
1010- "op_id": "hexic:empty_map",
1111- "anchor": "hexic:empty_map",
1010+ "op_id": "phlib:empty_map",
1111+ "anchor": "phlib:empty_map",
1212 "input": "",
1313 "output": "map<⊥, ⊥>",
1414 "text": "Creates a new empty map for my usage."
···66 "pages": [
77 "I've discovered a way to create a new type of iota — an abhorrence against Nature of my own doing. This pattern weaves a 'sheath' of _media out of some iota, letting me customize several attributes of the new iota. Though this can make my spells more expressive, this ability is not to be taken lightly — I cannot imagine the mischief others would do with these 'patchwork' iotas.",
88 "To assemble a patchwork iota, I must provide four source iotas:$(br)$(li)The 'userdata' iota, passed to my overload _Hexes.$(li)The 'display' iota, visible to my eyes.$(li)A color for the iota, as an RGB vector in the 0-1 range.$(li)A pointer to an $(thing)overload map./$",
99- "Such an 'overload map' is merely a regular $(l:addon/hexic/maps)$(thing)Map/$ iota (mapping patterns to the _Hexes they should be replaced with), but stored within a $(l:properties)$(thing)Property/$. I assume that Nature's reason for boxing like this is to save space: it's likely I'll have many patched iotas all using the same overloads. This also gives me the convenience of updating every instance with merely $(l:properties#hexcellular:set_property)$(action)Schrödinger's Gambit/$, rather than finding and updating them all by hand.",
99+ "Such an 'overload map' is merely a regular $(l:addon/phlib/maps)$(thing)Map/$ iota (mapping patterns to the _Hexes they should be replaced with), but stored within a $(l:properties)$(thing)Property/$. I assume that Nature's reason for boxing like this is to save space: it's likely I'll have many patched iotas all using the same overloads. This also gives me the convenience of updating every instance with merely $(l:properties#hexcellular:set_property)$(action)Schrödinger's Gambit/$, rather than finding and updating them all by hand.",
1010 {
1111 "type": "hexcasting:pattern",
1212- "anchor": "hexic:metatable",
1313- "op_id": "hexic:metatable",
1212+ "anchor": "iotaworks:metatable",
1313+ "op_id": "iotaworks:metatable",
1414 "input": "iota, iota, vec, property",
1515 "output": "patchwork",
1616 "text": "$(br)Constructs a Patchwork iota from the userdata (iota stored inside), display iota (visible to my eyes), color, and an overload map."
···2828 {
2929 "type": "patchouli:text",
3030 "flag": "mod:hexdoc",
3131- "text": "These $(thing)overload maps/$ resemble a technique I've seen before — the concept of redefining patterns on a fundamental level resembles the moon cultists' (little time to explain) $(l:https://www.lua.org/pil/13.html)metatables/$, which allow associating a table with another table to redefine its operations. When my 'metamethods' are invoked, the userdata iota is pushed to the top of the stack. All other information about the patchwork disintegrates: I'll need to recreate it from scratch (maybe I should use a 'constructor' macro?) if I want to return a new iota of the same type."
3131+ "text": "These $(thing)overload maps/$ resemble a technique I've heard of before — the concept of redefining patterns on a fundamental level resembles the moon cultists' (little time to explain) $(l:https://www.lua.org/pil/13.html)metatables/$, which allow associating a table with another table to redefine its operations. When my 'metamethods' are invoked, the userdata iota is pushed to the top of the stack. All other information about the patchwork disintegrates: I'll need to recreate it from scratch (maybe I should use a 'constructor' macro?) if I want to return a new iota of the same type."
3232 },
3333 {
3434 "type": "patchouli:text",