Last time we had Runelang: A Bind Rune Generator. This time, let’s make ‘summoning circles’. Basically, we want to make a circle with stars and other circles inscribed and around the borders with various ‘mystic’ text in the mix. Something like this:
generate_summoning_circle
- random chance of boder
- random chance of one or more inscribed stars
- random chance of recurring on the border (calling
generate_summoning_circle
again) - random chance of recurring in the middle
Generate Bind Rune
Codewise, I only have one (relatively complicated) function this time:
function generate_summoning_circle(depth, options) {
let LANGUAGES = ["GREEK_UPPER", "ASTROLOGICAL", "RUNIC"]
options ||= {}
depth ||= 0
block("group {")
let border_text_chance = options["border_text_chance"] || 0.5
let star_chance = depth == 0 ? 1.0 : options["star_chance"] || 0.5
let second_star_chance = depth == 0 ? 1.0 : options["second_star_chance"] || 0.5
let border_recur_chance = options["border_recur_chance"] || 0.5 ** depth
let inner_recur_chance = options["inner_recur_chance"] || 0.5 ** depth
let inner_text_chance = options["inner_text_chance"] || 0.5 // if not inner recur
// Border
if (random_float() < border_text_chance) {
line(`doubleTextCircle(${choose(...LANGUAGES)})`)
} else {
line("double(0.1) circle")
}
// Stars
if (random_float() < star_chance) {
let points = [5, 7, 11, 13][random_int(0, 3)]
line(`star(${points})`)
if (random_float() < second_star_chance) {
let points = [5, 7, 11, 13][random_int(0, 3)]
line(`invert star(${points})`)
}
}
// Outer circles
if (random_float() < border_recur_chance) {
let points = [5, 7, 11, 13][random_int(0, 3)]
if (depth <= random_int(1, 3)) {
block("radial(scale: 1/4) [")
for (let i = 0; i < points; i++) {
generate_summoning_circle(depth + 1)
}
end_block("]")
}
}
// Inscribed circles
if (random_float() < inner_recur_chance) {
block("scale(0.5) {")
generate_summoning_circle(depth + 1)
end_block("}")
} else if (random_float() < inner_text_chance) {
line(`text(chooseOne(${choose(...LANGUAGES)}))`)
}
end_block("}")
}
Most of it’s in the comments and configuration variables, but the idea for each part is random_float() < ***_chance
, randomly choosing which features to draw. And then in ‘outer circles’ and ‘inscribed circles’, you have the recursive calls to generate_summoning_circle
. You do have to be careful with those chances. If they’re too high, you’ll recur an awfully long way down and end up bringing your browser to a screaming halt. But until then, it’s all good. :D
Demo
Demo time!