MFC serialized data
MFC serialized data is used in Creatures 1 and Creatures 2 for saved worlds (.sfc files) and creatures (.exp files). Similar to CreaturesArchive data, it contains serialized objects from the game engine, essentially an on-disk representation of the internal game state. Objects are serialized using the built-in Windows MFC serialization routines.
Although the format is not fully understood, openc2e is capable of extracting enough data from SFC files to enable default worlds (or any without creatures present) to be loaded almost entirely. Its source code contains a Python script for doing this, as well as the C++ code used by the engine itself.
Contents
- 1 SFC files
- 2 EXP files
- 3 File format
- 3.1 CArchive object header
- 3.2 strings
- 3.3 Creatures 1 SFC file
- 3.4 Creatures 1 MapData
- 3.5 Creatures 1 CGallery
- 3.6 Creatures 1 Entity
- 3.7 Creatures 1 Macro
- 3.8 Creatures 1 Object
- 3.9 Creatures 1 Scenery
- 3.10 Creatures 1 SimpleObject
- 3.11 Creatures 1 PointerTool
- 3.12 Creatures 1 Bubble
- 3.13 Creatures 1 CallButton
- 3.14 Creatures 1 CompoundObject
- 3.15 Creatures 1 Vehicle
- 3.16 Creatures 1 Lift
- 3.17 Creatures 1 Blackboard
- 3.18 Creatures 1 Creature
- 3.19 Creatures 1 BodyPart
- 3.20 Creatures 1 Body
- 3.21 Creatures 1 Limb
- 3.22 Creatures 1 CBrain
- 3.23 Creatures 1 CBiochemistry
- 3.24 Creatures 1 CInstinct
- 4 External links
SFC files
SFC files (.sfc) are the world save format for Creatures 1 and Creatures 2. They contain all modifiable information about worlds - such as rooms, agents and creatures.
The default world - which the Emergency Kit and World Switcher use to reset or make a new world - is stored in Eden.sfc, and the current world in World.sfc - although you can also use different files if you're using cheats or the World Switcher. Third-party worlds come with their own SFC files.
EXP files
EXP files are files for exported creatures in Creatures 1 and Creatures 2. EXP files include a snapshot of the chemical condition of the norn, the genetic D-DNA, the state of the norn brain and information about pregnancies. A common trick for preserving the original exp file in Creatures 1 was to open its properties and check 'read-only'. The game would not then delete the original file upon importing the creature, although it made the game hang a bit.
File format
MFC serialized data is a dump of binary engine data, with most objects serialized with a CArchive header.
CArchive object header
Objects serialized through CArchive start with a header which specifies whether the object is:
type | description |
---|---|
2 bytes | persistent id |
4 bytes | 32-bit persistent id (only if 16-bit persistent id == 0x7FFF) |
If the persistent id is 0, this is a NULL object.
If the persistent id & 0x8000 is not empty, then this is a new object using an already-seen class at persistent_id & ~0x8000.
If the persistent id is -1 (0xFFFF), then this is a new object using a new class, specified by the following:
type | description |
---|---|
2 bytes | schema number |
2 bytes | class name length |
... | class name in ASCII |
If the persistent id is anything else, then it is a reference to an already-seen object.
New persistent ids are assigned whenever a new class is seen, and whenever a new object is seen (if both, then the new class is assigned an id first).
strings
type | description |
---|---|
1 byte | length |
2 bytes | length (only if 8-bit length == 255) |
4 bytes | length (only if 16-bit length == 65535) |
length | string (ASCII-encoded in Creatures 1, CP-1252-encoded in Creatures 2) |
Creatures 1 SFC file
All CArchive objects in a Creatures 1 SFC file have a schema number of 1.
type | description |
---|---|
MapData | world map |
4 bytes | number of objects |
Object | objects[0] |
... | |
4 bytes | number of sceneries |
Scenery | sceneries[0] |
... | |
4 bytes | number of scripts |
1 byte | scripts[0].event number |
1 byte | scripts[0].species |
1 byte | scripts[0].genus |
1 byte | scripts[0].family |
string | scripts[0].text |
... | |
4 bytes | scrollx maybe? |
4 bytes | scrolly maybe? |
2 bytes | currently logged norn? might be a CArchive object, hopefully NULL |
string | favorite_places[0].name |
2 bytes | favorite_places[0].x |
2 bytes | favorite_places[0].y |
... | up through favorite_places[5], inclusive |
2 bytes | size of speech history |
string | speech_history[0] |
... | |
4 bytes | number of macros |
Macro | macros[0] |
... |
Creatures 1 MapData
CArchive serialized:
type | description |
---|---|
4 bytes | unknown, always zero |
4 bytes | time of day |
CGallery | background sprite |
4 bytes | number of rooms |
4 bytes | rooms[0].left |
4 bytes | rooms[0].top |
4 bytes | rooms[0].right |
4 bytes | rooms[0].bottom |
4 bytes | rooms[0].type (0=Indoors, 1=Surface, 2=Undersea) |
... | |
4 bytes | groundlevel[0] |
... | up through groundlevel[260], inclusive |
1 byte | bacteria[0].state (0 = Not present, 1 = Dormant, 2 = Active) |
1 byte | bacteria[0].antigen |
1 byte | bacteria[0].fatal_level |
1 byte | bacteria[0].infect_level |
1 byte | bacteria[0].toxin1 |
1 byte | bacteria[0].toxin2 |
1 byte | bacteria[0].toxin3 |
1 byte | bacteria[0].toxin4 |
... | up through bacteria[99], inclusive |
Creatures 1 CGallery
CArchive serialized:
type | description |
---|---|
4 bytes | number of images |
4 bytes | filename |
4 bytes | first sprite |
4 bytes | number of references, maybe |
CGallery | images[0].parent |
1 byte | images[0].status (bitfield: 0 = incache, 2 = ownmem, 4 = locked) |
4 bytes | images[0].width |
4 bytes | images[0].height |
4 bytes | images[0].offset |
... |
Creatures 1 Entity
An object part, CArchive serialized:
type | description |
---|---|
CGallery | |
1 byte | current sprite |
1 byte | image offset |
4 bytes | z-order (maybe a signed integer) |
4 bytes | x |
4 bytes | y |
1 byte | has animation |
1 byte | animation frame (only if has animation) |
32 bytes | animation string (null-padded) (only if has animation) |
Creatures 1 Macro
Currently running scripts, CArchive serialized:
type | description |
---|---|
4 bytes | destroy object afterwards |
4 bytes | INST |
4 bytes | text length? |
string | script |
4 bytes | instruction pointer |
4 bytes | stack[0] |
... | up through stack[19], inclusive |
4 bytes | stack pointer |
4 bytes | vars[0] |
... | up through vars[9], inclusive |
Object | OWNR |
Object | FROM |
Object | EXEC |
Object | TARG |
Object | _IT_ |
4 bytes | PART |
4 bytes | label of most recently visited subroutine |
4 bytes | address of most recently visited subroutine |
4 bytes | WAIT |
Creatures 1 Object
Parent class of other objects, and appears as the first part of their data. CArchive serialized:
type | description |
---|---|
1 byte | unused portion of classifier (e.g. eventno, which makes no sense here) |
1 byte | species |
1 byte | genus |
1 byte | family |
1 byte | movement status (0 = autonomous, 1 = mousedriven, 2 = floating, 3 = invehicle, 4 = carried) |
1 byte | ATTR |
4 bytes | limit_left |
4 bytes | limit_top |
4 bytes | limit_right |
4 bytes | limit_bottom |
Object | carrier |
1 byte | ACTV |
CGallery | sprite |
4 bytes | tick time |
4 bytes | tick state |
Object | OBJP |
4 bytes | current sound name |
4 bytes | OBV0 |
4 bytes | OBV1 |
4 bytes | OBV2 |
4 bytes | number of scripts |
1 byte | scripts[0].eventno |
1 byte | scripts[0].species |
1 byte | scripts[0].genus |
1 byte | scripts[0].family |
string | scripts[0].text |
... |
Creatures 1 Scenery
Subclass of Object:
type | description |
---|---|
Entity | part |
Creatures 1 SimpleObject
Subclass of Object:
type | description |
---|---|
Entity | part |
4 bytes | z-order (should match the part's z-order) |
3 bytes | click bhvr |
1 byte | touch bhvr |
Creatures 1 PointerTool
Subclass of SimpleObject:
type | description |
---|---|
4 bytes | relx |
4 bytes | rely |
Bubble | speech bubble |
25 bytes | text |
Creatures 1 Bubble
Subclass of SimpleObject:
type | description |
---|---|
1 byte | life |
4 bytes | creator |
25 bytes | text (null-padded) |
Creatures 1 CallButton
Subclass of SimpleObject:
type | description |
---|---|
Lift | |
1 byte | button id |
Creatures 1 CompoundObject
Subclass of Object:
type | description |
---|---|
4 bytes | number of parts |
Entity | parts[0].entity |
4 bytes | parts[0].x (only if parts[0] is not NULL) |
4 bytes | parts[0].y (only if parts[1] is not NULL) |
... | |
4 bytes (signed) | hotspots[0].left |
4 bytes (signed) | hotspots[0].top |
4 bytes (signed) | hotspots[0].right |
4 bytes (signed) | hotspots[0].bottom |
... | up through hotspots[5], inclusive |
4 bytes | functions[0].hotspot |
... | up through functions[5], inclusive |
Creatures 1 Vehicle
Subclass of CompoundObject:
type | description |
---|---|
4 bytes (signed) | x velocity * 256 |
4 bytes (signed) | y velocity * 256 |
4 bytes | coordx * 256 |
4 bytes | coordy * 256 |
4 bytes | cabin left |
4 bytes | cabin top |
4 bytes | cabin right |
4 bytes | cabin bottom |
4 bytes | bump |
Creatures 1 Lift
Subclass of Vehicle:
type | description |
---|---|
4 bytes | number of floors |
4 bytes | next or current floor |
4 bytes (signed) | current call button |
1 byte | delay counter |
4 bytes | floors[0].y |
CallButton | callbuttons[0] |
... | repeats up through floors[7] and callbuttons[7], inclusive |
Creatures 1 Blackboard
Subclass of CompoundObject:
type | description |
---|---|
1 byte | background color |
1 byte | chalk color |
1 byte | aliascolor |
1 byte | text x position |
1 byte | text y position |
4 bytes | words[0].value |
11 bytes | words[0].text (null-padded) |
... | up through words[15], inclusive |
Creatures 1 Creature
Subclass of Object:
type | description |
---|---|
4 bytes | moniker |
4 bytes | mother's moniker |
4 bytes | father's moniker |
string | mother's name |
string | father's name |
Body | body |
Limb | head |
Limb | left thigh |
Limb | right thigh |
Limb | left arm |
Limb | right arm |
Limb | tail |
1 byte | direction facing |
1 byte | downfoot (0=left 1=right) |
4 bytes | foot x |
4 bytes | foot y |
4 bytes | z-order |
string | current pose |
1 byte | expression (0=normal 1=happy 2=sad) |
1 byte | eyes open |
1 byte | asleep |
4 bytes | unconscious |
string | poses[0] |
... | up through poses[99], inclusive |
string | gait_animations[0] |
... | up through gain_animations[7], inclusive |
string | vocabulary[0].in |
string | vocabulary[0].out |
4 bytes | vocabulary[0].strength |
... | up through vocabulary[79], inclusive (80 words? is that right?) |
4 bytes | remembered_objects[0].x |
4 bytes | remembered_objects[0].y |
... | up through remembered_objects[39], inclusive |
1 byte | stimuli[0].significance |
1 byte | stimuli[0].input |
1 byte | stimuli[0].intensity |
1 byte | stimuli[0].features (bitfield, 0=modulate 2=iprange 4=ifasleep) |
1 byte | stimuli[0].chemical0 |
1 byte | stimuli[0].amount0 |
1 byte | stimuli[0].chemical1 |
1 byte | stimuli[0].amount1 |
1 byte | stimuli[0].chemical2 |
1 byte | stimuli[0].amount2 |
1 byte | stimuli[0].chemical3 |
1 byte | stimuli[0].amount3 |
... | up through stimuli[35], inclusive |
Brain | brain |
Biochemistry | biochemistry |
1 byte | sex |
1 byte | age |
4 bytes | biological tick |
4 bytes | gamete (my moniker) |
4 bytes | zygote (child's moniker, if pregnant) |
1 byte | dead |
4 bytes | age in ticks |
4 bytes | number of instincts to be processed |
4 bytes | dreaming |
CInstinct | instincts[0] |
... | |
4 bytes | goals[0][0] |
... | up through goals[0][16], inclusive (drives related to object) |
... | up through goals[39], inclusive (up to 40 remembered objects) |
SimpleObject | zzzz |
SimpleObject | stars |
SimpleObject | bubbles |
4 bytes | status of hand before it was disregarded |
4 bytes | voice_lookup_table[0][0] (NOTE: voice data is similar to VCE files, but the lookup table comes first) |
... | up through voice_lookup_table[0][26], inclusive |
... | up through voice_lookup_table[2], inclusive |
4 bytes | voices[0].name |
4 bytes | voices[0].delay_ticks |
... | up through voices[31], inclusive |
4 bytes | history_moniker |
string | history_name |
4 bytes | history_moms_moniker |
string | history_moms_name |
4 bytes | history_dads_moniker |
string | history_dads_name |
string | history_birthday |
string | history_birthplace |
string | history_owner_name |
string | history_owner_phone |
string | history_owner_address |
string | history_owner_email |
4 bytes | history_state (0=ok 1=dead 2=exported) |
4 bytes | history_gender |
4 bytes | history_age_in_seconds |
? | padding |
Creatures 1 BodyPart
Subclass of Entity:
type | description |
---|---|
4 bytes | angle |
4 bytes | view |
Creatures 1 Body
Subclass of BodyPart:
type | description |
---|---|
1 byte | body_data[0][0].x |
1 byte | body_data[0][0].y |
... | up through body_data[0][9], inclusive |
... | up through body_data[5], inclusive |
Creatures 1 Limb
Subclass of BodyPart:
type | description |
---|---|
1 byte | limbdata[0].startx |
1 byte | limbdata[0].starty |
1 byte | limbdata[0].endx |
1 byte | limbdata[0].endy |
... | up through limbdata[9], inclusive |
Limb | next limb |
Creatures 1 CBrain
Creatures 1 CBiochemistry
type | description |
---|---|
Creature | owner |
4 bytes | number of emitters |
4 bytes | number of receptors |
4 bytes | number of reactions |
1 byte | chemicals[0].concentration |
1 byte | chemicals[0].decay |
... | up through chemicals[255], inclusive |
1 byte | emitters[0].organ |
1 byte | emitters[0].tissue |
1 byte | emitters[0].locus |
1 byte | emitters[0].chemical |
1 byte | emitters[0].threshold |
1 byte | emitters[0].rate |
1 byte | emitters[0].gain |
1 byte | emitters[0].effect |
... | |
1 byte | receptors[0].organ |
1 byte | receptors[0].tissue |
1 byte | receptors[0].locus |
1 byte | receptors[0].chemical |
1 byte | receptors[0].threshold |
1 byte | receptors[0].nominal |
1 byte | receptors[0].gain |
1 byte | receptors[0].effect |
... | |
1 byte | reactions[0].reactant1_amount |
1 byte | reactions[0].reactant1_chemical |
1 byte | reactions[0].reactant2_amount |
1 byte | reactions[0].reactant2_chemical |
1 byte | reactions[0].rate |
1 byte | reactions[0].product1_amount |
1 byte | reactions[0].product1_chemical |
1 byte | reactions[0].product2_amount |
1 byte | reactions[0].product2_chemical |
... |
Creatures 1 CInstinct
type | description |
---|---|
4 bytes | dendrites[0].lobe_to_be_stimulated |
4 bytes | dendrites[0].cell_to_be_stimulated |
... | up through dendrites[2], inclusive |
4 bytes | decision to be taken (motor) |
4 bytes | reinforcement chemical (reinforcer) |
4 bytes | reinforcement amount |
4 bytes | phase |