Brodgar client

Published code: the Java a .res carries

Not all of the client’s code is in this tree (doc/resource-code): a .res can carry its own Java — a code layer of classes plus a codeentry layer naming the entry point and, under type 2 or a use datum, a classpath of other resources to load it against ($use: lib/obst in the preprocessed source). CodeEntry.loader() chains a Resource.ResClassLoader per entry, whose parent is the client’s own loader. Every tooltip (ui/tt/*), the gilding window (ui/slot-info), the village and realm panels, most effect sprites and every instrument are code of this kind, and it is what a server widget gets whenever its type name contains / (Widget.gettype3).

Where a resource comes from, in what order the sources are asked and how a version decides between them is resource loading.

A local copy under src/haven/res/ wins over the served class only when its @haven.FromResource(name, version) matches the resource actually served; otherwise the loader warns and uses the fetched code. So adopting a class is version-pinned by construction and a server-side bump degrades to upstream behaviour rather than breaking. Resource’s own main has get-code (fetch the source and write it annotated) and find-updates (report copies whose version has moved on).

Served classes are compiled against upstream’s haven and resolved by name and descriptor, at first use, against this client’s classes: ui/slot-info’s Probability does new ILabel(text, Window.cf), and its getstatic haven/Window.cf : Lhaven/Text$Furnace; is answered by whatever haven.Window this jar holds — or by NoSuchFieldError, thrown out of the widget’s constructor the first time the player opens that window: not at compile time, not at start-up. So for a public or protected member of haven:

What the descriptor rule does not cover, no tool covers: a member kept intact whose behaviour changed.

The reshapes of upstream’s surface this client carries that no served code in the bundled jars or the cache reaches — debt to know about, not bugs: GameUI.FKeyBelt.beltkeys; UI.mousehover(Coord) returning boolean; the OptWnd panel constructors without their Panel argument.

See also