sorcery  Check-in [5de2e733a4]

Overview
Comment:add form builder prototype, update readme
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 5de2e733a4e846d047aab6ef8302f0b52dbb8e96e06f0bd4a8a3a2cf066afff9
User & Date: lexi on 2021-06-28 18:28:34
Other Links: manifest | tags
Context
2021-06-28
18:31
defuckulate markdown check-in: fa442a5d6a user: lexi tags: trunk
18:28
add form builder prototype, update readme check-in: 5de2e733a4 user: lexi tags: trunk
15:38
more work on kegs and liquid, add taps and troughs for tapping trees and obtaining sap, add tree lore, add infuser module system, various tweaks, fix up bugged itemclass logic, add scaffold for crafting extension mechanism check-in: 01f4ba8ddc user: lexi tags: trunk
Changes

Modified lib/ui.lua from [787cef01b1] to [70c6c0143a].

1
2
3
4


































5
6
7
8
9
10
11
local l = sorcery.lib
local dui = sorcery.data.ui

return {


































	tooltip = function(a)
		local color = a.color and a.color:readable()
		if color == nil then color = l.color(136,158,177) end
		local str = a.title
		if a.desc then
			str = str .. '\n' .. color:fmt(minetest.wrap_text(a.desc,60))
		end




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
local l = sorcery.lib
local dui = sorcery.data.ui

return {
	form = function()
		return {
			src = "";
			width = 8;
			pad = 0;
			curs = {x = 0, y = 0, maxh = 0};
			nl = function(self, h)
				h = h or 0
				self.curs.x = 0
				self.curs.y = math.max(h, self.curs.y + self.curs.maxh)
				self.curs.maxh = 0
			end;
			atttach = function(self, elt, x, y, w, h, ...)
				local content = ''
				if self.width - self.curs.x < w then self:nl() end
				for _, v in pairs{...} do
					content = content .. ';' .. minetest.formspec_escape(tostring(v))
				end
				self.src = self.src .. string.format('%s[%f,%f;%f,%f%s]', elt, x,y, w,h, content)
				if h > self.curs.maxh then self.curs.maxh = h end
			end;
			add = function(self, elt, w, h, ...)
				local ax, ay = self.curs.x, self.curs.y
				self:attach(elt, ax,ay, w,h, ...)
				self.curs.x = self.curs.x + w + self.pad
				if self.curs.x > self.width then self:nl() end
				return ax, ay
			end;
			render = function()
				return string.format("size[%f,%f]%s", self.width, self.curs.y + self.pad + self.curs.maxh, self.src)
			end;
		}
	end;

	tooltip = function(a)
		local color = a.color and a.color:readable()
		if color == nil then color = l.color(136,158,177) end
		local str = a.title
		if a.desc then
			str = str .. '\n' .. color:fmt(minetest.wrap_text(a.desc,60))
		end

Modified sorcery.md from [b729085cc9] to [2d498af290].

1
2
3


4
5
6
7
8
9
10
..
32
33
34
35
36
37
38
























39
40
41
42
43
44
45
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# sorcery

`sorcery` is a wide-ranging mod that adds many features, devices, powers, and mechanics to the minetest default game. it aims to add a distinctive cosmology, or world-system, to the game, based around mese, alchemy, spellcasting, and worship. it is intended to be pro-social, lore-flexible, and to interoperate well with other mods wherever possible.



# dependencies

## first-party
 * **default**
 * **stairs** for slabs, used in crafting recipes
 * **screwdriver** for several crafting recipes
................................................................................
## hopper
many `sorcery` devices support interactions with the hopper. devices that produce outputs after a period of time like the infuser will automatically inject their output into a hopper if one is placed below it, and if the device has multiple slots, they can usually be accessed by configuring a hopper to insert from the side or from above.

## others
* if `moreores` is in use, `sorcery` will use its silver rather than creating its own. mithril is not used by `sorcery`.
* `sorcery` will use `new_campfire`'s ash if it's available, otherwise creating its own.

























# lore
`sorcery` supplies a default system of lore (that is, the arbitrary objects that the basic principles of the setting operate over) but this can be augmented or replaced on a per-world basis. for instance, you can substitute your own gods for the Harvest Goddess, Blood God, change their names, and so on, or simply make your own additions to the pantheon. since lore overrides are stored outside the minetest tree, it can be updated without destroying your changes.

lore is stored separately from the rest of the game logic, in the 'data' directory of the `sorcery` mod. it is arranged in a hierarchy of thematically-organized tables. for instance, the table of gods can be found in `data/gods.lua`. ideally, lore tables should contain plain data, though they can also contain lambdas if necessary. lore files are evaluated in the second stage of the init process, after library code has been loaded but before any game logic has been instantiated. lore can thus depend on libraries where reasonable (though e.g. colors should be stored as 3-tuples rather than `sorcery.lib.color` objects, and images as texture strings, unless there is a very good reason to do otherwise).

lore files should never depend on functions in the `minetest` or `core` namespace! if you really need such functionality, gate it off with an if statement and be sure to return something useful in the event that the namespace isn't defined. *lore is just data:* as a general principle, non-minetest code should be able to evaluate and make use of the lore files, for instance to produce an HTML file tabulating the various potions and how to create them. lore should also not mutate the global environment: while there is currently nothing preventing it from doing so, steps will likely be taken in the future to give each lore module a clean environment to keep it from contaminating the global namespace. right now, all functions and variables declared in a lore file should be defined `local`. the only job of a lore file is to return a table.

................................................................................
this has the handy property that any changes made upstream to the Harvest Goddess will be respected if you update the mod, without overriding the changes made in lore-gods.lua.

or, if you want to extract a specific god from the default pantheon and include it with your own:

```
-- /srv/mt/geographica/sorcery/lore-gods.lua
local gods = ...
local mygods = dofile('pantheon.lua')
mygods.harvest = gods.harvest
mygods.harvest.name = 'Disastra bel-Malphegor'
return mygods
```

## compatibility tables
if you use a mod that neither supports `sorcery` nor is supported by it, the proper solution is of course to open a ticket in the former's bug tracker, but as a quick fix you can also tweak the `sorcery` compatibility tables with a `$world/sorcery/lore-compat.lua` file.
................................................................................
			value = 3;
			grindcost = 1;
		};
	};
})
```

note that we have to use deepmerge instead of naming the file `lore-compat-extra.lua` and returning a simple table because the init routine only performs a shallow merge, meaning that it would wipe out the entire provided version of `sorcery.data.compat.grindables`! no bueno.

## local tweaks
if you need to change `sorcery`'s behavior in a way that isn't possible through modifying the lore, you can create a file `$world/sorcery/finalize.lua` which will be run at the end of the init process and which will have access to all of the machinery created by the various modules of the mod. `worldbuilding.lua` is like `finalize.lua` but it is run before any lore is loaded. finally, `bootstrap.lua` will be run before anything else, including library code, is loaded, but after the core `sorcery` structure and its loading functions have been created.

in the unlikely event that the lore-loading process itself is incompatible with the changes you're trying to make, you can create a `loadlore.lua` file that will be run instead of the usual routine. you'll then be responsible for loading all of the game's lore; the default lore will not even be read! this will be most useful if you're loading or generating your own lore from an unusual source, such as somewhere on the network.

if you want to write a lore loader but include some of the default lore, you can use the loading function passed to `loadlore.lua`:


|
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
..
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# sorcery

`sorcery` is a wide-ranging mod that adds many features, devices, powers, and mechanics to the minetest default game. it aims to add a distinctive cosmology, or world-system, to the game, based around mese, alchemy, spellcasting, farming, gathering resources from nature, and worship. it is intended to be pro-social, lore-flexible, to lend itself well towards a vibrant in-game economy, and to interoperate well with other mods wherever possible.

sorcery is still alpha-quality. it is far from feature-complete, and many important spells have not been written yet.

# dependencies

## first-party
 * **default**
 * **stairs** for slabs, used in crafting recipes
 * **screwdriver** for several crafting recipes
................................................................................
## hopper
many `sorcery` devices support interactions with the hopper. devices that produce outputs after a period of time like the infuser will automatically inject their output into a hopper if one is placed below it, and if the device has multiple slots, they can usually be accessed by configuring a hopper to insert from the side or from above.

## others
* if `moreores` is in use, `sorcery` will use its silver rather than creating its own. mithril is not used by `sorcery`.
* `sorcery` will use `new_campfire`'s ash if it's available, otherwise creating its own.

# mechanics
sorcery adds many new mechanics to the game. among them:
 * extracts can be crafted using crushed excess seeds and alcohol
 * oils, greases, and other substances can be crafted by mixing together various ingredients, including extracts
 * magical elixirs can be made by infusing oils and the like into bottles of water at an **Infuser**, and can be drunk to gain temporary powers
 * liquids can be carried around in buckets, bottles, and glasses, depending on the liquid.
 * kegs can store large volumes of liquid, making for easy retrieval when you, say, need a specific extract or potion to brew an elixir
 * troughs can be used to gather liquid from nature. set out under the open sky, for instance, they will slowly collect rainwater (depending on the biome). they have twice the volume of buckets.
 * taps can be attached to trees to extract saps, syrups, and resins from under the bark; these can be caught by placing a trough below. you can then fill bottles from the trough, or simply pick the whole trough up and bring it home to deposit the liquid in a keg for later use.
 * wands, made at an **Wandworking Station** out of a wood, gems, bands, and cores, can be enchanted by soaking them in philters, special potions used for imbuing wood with ley-force (though i'm trying to come up with a better mechanism). these fire off powerful spells with a flick of the wrist, but will break when they run out of power (unless you recharge them…)
 * if you want to get into advanced arcanism, you can build an **Enchanter**. equipped with the proper wands, this powerful artifact can be used to imbue tools with useful supernatural properties, though what enchantments are available and how much ley-charge a tool can hold depend on what metal the tool is made of. but Enchanters can be used for more subtle purposes as well. with the right ingredients and a **Divination Wand**, you can conjure up recipes for delicacies or schematics for powerful magitech devices you never imagined were possible. **Melding Wands** can merge the mystic essences of items on an Enchanter to create something new, including some things that can't be made any other way, though the stars may need to be right (an **Astrolabe** can help you check) for certain recipes to work, and some may come down to plain old luck. **Division Wands** are very similar, but work the other way around.
 * you can also build a **Disassembly Kit**, which you can use with pen, ink, and paper to create schematics for any object you come across that you want to be able to craft yourself.
 * you can collect your assorted recipes into cookbooks, and you can build yourself a **Writing Stand** to insert, delete, re-order, or (if you have some Scissors handy) cut out parts of the book.
 * you can make a **Mill** for grinding up solid materials into powder or pulp. it makes flour from grain more efficiently than a mortar and pestle, can produce various metal powders of great utility, and can reduce books, paper, and punchcards down to a pulp, suitable for cleaning with **Erasure Fluid** and cooking back into clean paper. but you'll need some way to power it. a **Generator** will produce plenty of energy in a pinch, but it may be more rewarding to build yourself a real power grid, carrying current from place to place using cables (**Vidrium Cables** are sufficient for homes and studios, but industrial facilities may need **Iridium Cables** or the even more conductive **Conduit**). **Mese Blocks** always emit a small but constant amount of ley-current, but if you're near a strong leyline, building **Condenser**s to harvest its power will be much more efficient. (**Leyspark Wand**s are crucial tools for testing the source and affinity of the ambient leyscape.)
 * some new alloys can be made by sintering metal powders; others need to be melted down in a **Smelter**. these alloys have the most remarkable properties of any metal, and are especially valued by toolsmiths and enchanters, though they may be less broadly useful than the lesser metals.
 * if you need to travel quickly between two distant places, and you're wealthy enough to afford it, you can build yourself one of the most powerful and complex of magitech devices — the **Teleporter**. it's no mean feat: even the smallest teleporter requires a teleport pad with a reflector above it and a portal node connected to one or the other. the teleporter will then need to be connected to its destination with cables or conduits, and if where you're travelling is very far away, you'll have to build two separate ley nets and bridge them by using an **Attunement Wand** on a pair of **Raycasters** — or perhaps even **Farcasters**. the power required to operate all of these devices is not trivial, and while a Farcaster's signal can pierce through any substance and cross any distance to reach its destination, the farther away each is from the other, the more power each side will consume. and casters can't send current, they can only send signals, so you may need a sizable power plant on both sides of the portal.
 * if all you need to do is send small items, of course, a **Displacer** is much cheaper, and more flexible. if you're feeling particularly ambitious, you could use a Displacer net to connect your whole kingdom with instantaneous package service.
 * stop your foes in their tracks by flipping a switch to turn on your **Force Field Emitters**, generating an impenetrable barrier wherever they aim.
 * who needs elevators when you have **Gravitators**? float gently up a vast borehole, bring attackers crashing down to earth, or slow a fatal plunge to a soft and easy landing.
 * build graven **Idols** to your gods and set sacrifices to them upon an altar. if they're feeling generous, they might start sending you presents of their own, or consecrating your offerings. but beware: different gods have different tastes (and different powers), and get bored quickly with repetitive offerings.
 * to bend the ultimate arcane forces of the cosmos to your will, you'll need a **Rune Forge**. with a strong ley-current and a steady supply of **Phials** from an Infuser, a Rune Forge will crystallize thaumic impurities into Runes that can you can imbue into a gemstone **Amulet** with a **Rune Wrench**. each amulet can only be used once before it loses its charge, and it may be a long time before the same kind of rune happens to coalesce in your forge again, but the spells they unleash are unique and priceless boons — or weapons. teleport without a teleporter! purge your environs of all spellcraft no matter how fearsomely potent! surround yourself with a shimmering Disjunction Field that, for a short while, will snuff out any spell it touches and, rendering enemy mages utterly helpless and piercing otherwise impenetrable defenses! stride through solid stone like open air! carve huge tunnels deep into the rock with only a snap of your fingers! rain obliteration down upon a target of your choosing! send forth a titanic bolt of flame with the power to blast open mountainsides! tear the very life force straight from an enemy's body and use it to fortify your being! all this and more can be done with the power of rune magic.

there's more as well. i have yet to figure out how i want to go about introducing users to the lore, but for now there's some information on the wiki and some things you can glean from creative mode; otherwise you'll have to read the source code.

# lore
`sorcery` supplies a default system of lore (that is, the arbitrary objects that the basic principles of the setting operate over) but this can be augmented or replaced on a per-world basis. for instance, you can substitute your own gods for the Harvest Goddess, Blood God, change their names, and so on, or simply make your own additions to the pantheon. since lore overrides are stored outside the minetest tree, it can be updated without destroying your changes.

lore is stored separately from the rest of the game logic, in the 'data' directory of the `sorcery` mod. it is arranged in a hierarchy of thematically-organized tables. for instance, the table of gods can be found in `data/gods.lua`. ideally, lore tables should contain plain data, though they can also contain lambdas if necessary. lore files are evaluated in the second stage of the init process, after library code has been loaded but before any game logic has been instantiated. lore can thus depend on libraries where reasonable (though e.g. colors should be stored as 3-tuples rather than `sorcery.lib.color` objects, and images as texture strings, unless there is a very good reason to do otherwise).

lore files should never depend on functions in the `minetest` or `core` namespace! if you really need such functionality, gate it off with an if statement and be sure to return something useful in the event that the namespace isn't defined. *lore is just data:* as a general principle, non-minetest code should be able to evaluate and make use of the lore files, for instance to produce an HTML file tabulating the various potions and how to create them. lore should also not mutate the global environment: while there is currently nothing preventing it from doing so, steps will likely be taken in the future to give each lore module a clean environment to keep it from contaminating the global namespace. right now, all functions and variables declared in a lore file should be defined `local`. the only job of a lore file is to return a table.

................................................................................
this has the handy property that any changes made upstream to the Harvest Goddess will be respected if you update the mod, without overriding the changes made in lore-gods.lua.

or, if you want to extract a specific god from the default pantheon and include it with your own:

```
-- /srv/mt/geographica/sorcery/lore-gods.lua
local gods = ...
local mygods = dofile('my-pantheon.lua')
mygods.harvest = gods.harvest
mygods.harvest.name = 'Disastra bel-Malphegor'
return mygods
```

## compatibility tables
if you use a mod that neither supports `sorcery` nor is supported by it, the proper solution is of course to open a ticket in the former's bug tracker, but as a quick fix you can also tweak the `sorcery` compatibility tables with a `$world/sorcery/lore-compat.lua` file.
................................................................................
			value = 3;
			grindcost = 1;
		};
	};
})
```

note that we have to use deepmerge instead of naming the file `lore-compat-extra.lua` and returning a simple table because the init routine only performs a shallow merge over extras, meaning that it would wipe out the entire provided version of `sorcery.data.compat.grindables`! no bueno.

## local tweaks
if you need to change `sorcery`'s behavior in a way that isn't possible through modifying the lore, you can create a file `$world/sorcery/finalize.lua` which will be run at the end of the init process and which will have access to all of the machinery created by the various modules of the mod. `worldbuilding.lua` is like `finalize.lua` but it is run before any lore is loaded. finally, `bootstrap.lua` will be run before anything else, including library code, is loaded, but after the core `sorcery` structure and its loading functions have been created.

in the unlikely event that the lore-loading process itself is incompatible with the changes you're trying to make, you can create a `loadlore.lua` file that will be run instead of the usual routine. you'll then be responsible for loading all of the game's lore; the default lore will not even be read! this will be most useful if you're loading or generating your own lore from an unusual source, such as somewhere on the network.

if you want to write a lore loader but include some of the default lore, you can use the loading function passed to `loadlore.lua`: