Certainly – If you have existing heightfields you want to match against, create as so:
HFPointer original = < ... >
HFPointer myNewHF = GetNewHF(original->getContext());
getContext() will return the PacketContext that defines the worldspace location, dimensions, etc, which can be used to create heightfields with. You cannot get a context in the constructor since the device hasn’t yet been assigned to a world and so it has no defined sizes.
The other answers to your questions depend a fair bit on what you want to do… for example, you can easily add a HFPointer member to your class that will hold your custom data outside of any activate calls… and If you just want to store them in the TMD file you can load and save it in your Device’s Load() and Save() function by simply calling the packet’s Load() and Save() functions and providing it the stream you’re using. (If you need to load/save externally from disk, check out the HFieldIO.h file for the built-in I/O formats WM can use)
Your device will receive notice on the notifyWorldChange() function when the world size or extents change, but in general a better place to do any real work or matching is in your Activate() function – it is also a better place to find out what size the user really wants to create things at – currently WM has a monolithic resolution throughout the world but this will actually be changing not too far in the future, allowing you to define parts of the network at higher resolutions than others. In that case the world resolution is really only a default.