All help topics · Link to this topic
Showing help on 'init_for_core'
OBJECT:init_for_core([CORE_VARIANT_SPEC])
This verb is called in the final stage of core extraction (see $wiz:make-core-database), which occurs after all non-core objects have been recycled, the remaining ones have been renumbered and moved to #-1. This verbcall then performs any final cleanups to establish the initial state of the object and is (pretty much) the last thing to happen to the object before the new core database is saved.
What exactly goes in an :init_for_core verb varies hugely. Some considerations:
(1) The :init_for_core verbs are invoked from the top down, i.e., a given object's :init_for_core call verb precedes that of any of its children. Thus, when a given object's init_for_core() runs, you can safely assume that its entire ancestor chain has already been initialized in this way, and likewise that NONE of the descendants have been initialized yet.
(2) For non-ancestral objects, all bets are off --- with a few exceptions, you should not assume that they will be in working order, i.e., only invoke verbs that you know aren't being changed, and don't mess with their properties. Or if you must, make sure whatever you do works in BOTH the case where the other object's init_for_core has already run AND the case where it has not.
(3) The object's own properties, where they contain references to other objects, will be GARBAGE; renumber() does not update object values within properties or lists. That's your job (i.e., you qua author of :init_for_core).
(4) The root object's :init_for_core will copy code from any verb whose name ends in "(core)" to the corresponding verbname obtained by dropping that suffix. So, for example, if you find yourself writing 'set_verb_code(this, "verbname", {...})', you should instead create a (non-executable) "verbname(core)" verb, so as to have the verbcode in a place where you can edit it in a more readable form. This means...
(4a) For non-root objects, it is very important that pass(@args) be called.
And yes the @args need to be there, too, since while the
CORE_VARIANT_SPEC argument is currently unspecified and ignored
by all existing init_for_core verbs, it is intended to mean
mean something someday.
(4b) A given object's init_for_core will be applied to every descendant.
Bracket the parts that only apply to the object itself with
if ($code_utils:verb_location() == this)
...
endif
(5) Oddly enough, init_for_core verbs by default become part of the core database. You can arrange for them to remove themselves, but in the cases where they're performing generic sorts of initializations that are likely to be applicable to other MOOs, it's best to leave them in place. This is for the sake of other MOO admins who may, after some amount of their own development, want to (re)extract their own cores. While they will most likely be modifying the various init_for_core verbs as needed, if they do NOT make such modifications then (ideally) a core extraction should produce the same core they started with.
Thus,
(5a) init_for_core should be IDEMPOTENT; i.e., running it a second time on the
same object should achieve the same result. So, e.g., rather than
player.current_message = {@player.current_message, {this, 0, 0}};
which will create a duplicate entry the second time around, do
player:set_current_message(this, 0, 0, 1);
(5b) init_for_core should not depend on any non-core verbs/properties.
In particular, if your init_for_core deletes a LambdaMOO-specific
verb/property and you don't arrange to delete the init_for_core as well,
then you should bracket that call (e.g., with `... ! E_PROPNF,E_VERBNF')
so that it will work elsewhere even after said verb/property is long gone.
(5c) if your init_for_core has a large amount of LambdaMOO-specific material,
consider splitting the verb into
(*) an :init_for_core that eliminates the LambdaMOO-specific material,
and
(*) an :init_for_core(core) that accomplishes the generic initialization
(and will be copied into place by $root_object:init_for_core so that
ONLY the generic stuff escapes to the outside world.).
You can arrange for BOTH verbs to be called as follows:
#foo:init_for_core
if (caller_perms().wizard)
pass(@args); // copies :init_for_core(core) to this
if ($code_utils:verb_location() == this)
// wipe LambdaMOO-specific properties/verbs from this object
...
// call init_for_core(core) code
this:init_for_core()
endif
endif
though again, this depends on the various parent verbs being idempotent
since in this case they will be invoked twice.