TS1 Chunks

Discussion in 'Programming' started by Cytlan, Mar 21, 2016.

  1. Cytlan

    Cytlan New Member

    I've been spending a lot of time decoding the various chunks found in TS1 houses that have yet to be documented. I'll use this thread for my sharing my efforts with decoding these chunks, and keep my SimAntics thread strictly about SimAntics.

    Currently I'm able to load objm, objt, arry and simi chunks, but there are still a lot of unknown fields, especially in the objm and simi chunks.
    Here's a rundown of what I know so far:
    • objm - This is a field encoded chunk contains a table mapping object IDs from Arry's to fields found in objt. There's also a lot of data after the table which I'm not able to read yet. I'm guessing it contains the object states. It's also compressed using the same field encoding found in other chunks, but I'm not sure what sizes are used here.
    • objt - Contains a list of object GUIDs, object names, and 5 other fields I don't know the purpose of yet. This chunk contains unique objects found on the lot, so no object will ever appear twice here.
    • arry - As the name would suggest, these are arrays, containing info about where on the lot objects, floors, pools, etc. are stored. There seems to be at least 4 different formats used to store the data, and some chunks define more than just a single array. I've only been able to decode Arry(3) (objects) and Arry(9) (pools) so far.
    • simi - This is by far the least researched chunk I have, but I have found that this chunk defines the lot size and the lot price. It seems like it also contains info about the in-game time, and when the chunk was modified. Unlike objm, this chunk is more or less of a fixed size.
    Putting all of these together, I'm currently able to make a map like this of Sim Lane 2:
    (The map is mirrored, but that's just because of the way I've been storing the decoded data internally.)

    Coordinates in the Arry chunks are always encoded using 2 bytes, in one of the following formats:
    1000 yyyy yyxx xxxx (Arry(9))
    100y yyyy yxxx xxxf (Arry(3))
    Where x and y are the xy coordinates, and f is a flag with an unknown purpose.
    The first entry in the arry defines the absolute position, and all entries afterwards are relative to this initial position.

    As you can see, each axis is encoded using only 6 bits, which places the hard limit of 64x64 tiles lots. Interestingly, I haven't encountered any position defined in 16th tile-widths yet. My guess is that it's only found in the SimAntics data for objects.

    When a relative x coordinate overflows 6 bits, the y coordinate will be incremented by 1. You'll often see entries using 63,0 as their position, which is their way of incrementing y by 1 and x by 0. The x coordinate is incremented by 1 for every entry in the arry, which explains why they use this overflow trick when they only want to increment the y coordinate.

    Arry(9) has been a massive headache for me, because I couldn't for the life of me figure out when an array ended. Unlike Arry(3) which only contains one big array, Arry(9) may contain multiple arrays, but it uses a very strange end of array marker.
    Basically, an array in Arry(9) is terminated when the current position resolves to 0,0. Given that Arrys use relative positions most of the time, this means that the end of array marker is never the same twice. Confusing, huh?

    Anyway, I'll eventually share some code here for parsing these chunks as I finish decoding them.
    NubSmoo likes this.
  2. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    Cool! This will be pretty useful when porting the engine to TS1. My advice for walls is that they contain these fields (this may not be in the right order - this was taken and extended for runtime from the blueprint format)
            public WallSegments Segments;
            //the patterns of each side of the tile's wall.
            public ushort TopLeftPattern;
            public ushort TopRightPattern;
            public ushort BottomLeftPattern;
            public ushort BottomRightPattern;
            //the style of the wall at the top left and top right. bottom left and bottom right are to be obtained from the tiles in those directions.
            //1 generally means "normal wall". Not sure how to deal with cutouts while keeping these as "normal wall".
            public ushort TopLeftStyle;
            public ushort TopRightStyle;
        public enum WallSegments
            TopLeft = 1,
            TopRight = 2,
            BottomRight = 4,
            BottomLeft = 8,
            HorizontalDiag = 16,
            VerticalDiag = 32
    Note that there may also be extra state for custom wall styles applied by objects, and wall/floor "exclusive placement flags", which would probably be in the segments format for walls and just a bool for floors.

    For 16th tile positions, try pausing the game while an object like the roaches, rabbit or duck are moving, and save the lot. These simply snap 2 subtiles in a given direction every few frames to move.
  3. Cytlan

    Cytlan New Member

    Hmm, interesting. I'll switch my focus to the walls for the next few days and see what I can figure out.

    My desktop computer decided to go on vacation, so I won't be able to make any more test lots, but I'll keep it in mind. I'm almost entirely certain that it isn't stored in Arry(3), though. The sims themselves are defined and positioned in Arry(3) like any other object, and they don't have any extra data there (the only unknown field is always 0). The 16th position must be stored somewhere else, and I think objm is the most likely candidate.
  4. francot514

    francot514 Well-Known Member

    Good work, this is valuable and useful information, i have also worked a few with some of these chunks, this is what i can tell you so far:
    -Objm: Seems that it stores all the Object Data attributes (like the table found in edit object inspector)
    -Objt: It store the objects by showing persist ID, GUID, name, Alpha (layer???), room ID.
    -Simi: It store all the Simulation Information Hours, Minutes, Day, house number, house size, etc.

    I have worked in this chunk before. All my current changes can be found here:
  5. damondamore

    damondamore New Member

    Rhy suggested I chip in with the sims 1 lot data so here I am.

    I can say based on spec docs I dug up that simi is the simulation data. However the game engine has a lot of unused "features" which don't explode and can be made to function - such as references to in game weather and temperature - I suspect there's a lot of actually unused bits in there so you may find some of the things are simply unused.

    I think the objt also contains object version numbers -- the game is set up to reload objects if the iff file of an object has a different version in its object data than the one on the saved lot file and if my memory is right this functions correctly. Meaning the a saved object version number has to be stored in the lot data somewhere. It could be in an array, but it seems more logical to stuff it into the objects table. That is one of the few things which all instances of an object on a lot would share.
  6. damondamore

    damondamore New Member

    By doing resource swapping here's what each arry resource appears to contain in practial terms of the game (this is not decoding but at least I can verify what data appears to be contained in them).
    0 - altitude - Terrain Height
    1 - floors - floors - If you open the IFF file you may find this resource named simply "1" but it is floors. Floor tiles seem to always render correctly.
    2 - walls - contains wall placement info probably relative to an origin point. NOT affected by the lot facing flag. - If you open the IFF file you may find this resource named simply "1" but it is, in fact walls. Wallpapers do not always render correctly, depending on the lot.
    4 - ground - Not sure. Seems to change the growth state of the grass back to the default. Could be used as a template from which growth rates offset? Or a leftover from before grass "grew".
    6 - grass - actually contains the grass/dirt pattern data.
    7 - target grass - possibly the default grass state for community lots which do not save after being simulated.
    8 - flags - various lot data flags such as which way the lot faces and also seems to have something to do with which tiles are user-editable (which can be changed in game with the map_edit cheat).
    10 - water - contains locations of the lot water. Swappable with #9 the pool so I think it is safe to say they are set up identically. NOT affected by the lot facing flag.
    101 - floors 2 - Contains second floor floor data. (probably) NOT affected by the lot facing flag. Can be swapped out with #1, floors safely so it is likely they are set up the same. Sometimes just called "1" like some other resources.
    102 - walls2 - second floor walls. Swappable with #2 walls. Sometimes just called "1" like some other resources.
    103 - obejcts2 - guess what. It's second floor objects live and in person.
    108 - flags2 - it's the lot data flag's reunion tour! May differ from #8 flags but the game didn't explode on swapping so most likely any data not relevant to the second floor is safely ignored.

    An interesting additional point with the walls and floors is that while all the floor tiles always rendered (at least in my tests, your mileage may vary?) under some circumstances walls would render the edges but fail to draw the wallpaper and leave a transparent gap. I have some guesses why this happens but I don't want to shoot too much in the dark.
    RHY3756547 likes this.
  7. RHY3756547

    RHY3756547 FreeSO Developer Staff Member Moderator

    Walls can have certain segments set, and use the normal wall style of 1, but be missing a valid pattern for that side of the wall. That might explain it attempting to draw thick walls and leaving a gap.
  8. damondamore

    damondamore New Member

    I copied the resource from a real working lot where the walls were correctly drawn. Unless I'm misunderstanding then the wall patterns should be valid when transplanted to another lot. Some wallpapers would draw correctly, others would not.

    I did just have a thought I will need to test, though - the floors rendered 'correctly' but if a ground slope would prevent a floor tile it would not draw it even if the arry resource said one should be there. It is possible that if the walls changed height or are otherwise placed somewhere they normally could not be the game isn't sure what to do.
  9. damondamore

    damondamore New Member

    So after some double checking and experimentation....
    The game seems to index the used wallpapers somewhere in the data and then references them by a local id. When wallpapers did render "correctly" I neglected to verify that they were in fact the same as the target lot.

    They often were not.

    So I can only assume that when the wallpaper failed to draw it was copied from a lot with more unique wallpapers and was trying to reference a local id/index which was not actually defined for the lot they were transplanted onto.

    Floors seem to be doing the same thing, by chance my first test actually matched the correct floors and walls so I didn't keep verifying (oops!). I wonder if some walls and floors are consistently defined (or if maxis was lazy, had some defined in a template lot that rolled into all other lots!) -- the ones that seem to carry over correctly the most consistently seem to be from the base game.

    Interestingly the wall cutout data for doors (and probably windows) seems to be applied in the wall resource as well.
  10. francot514

    francot514 Well-Known Member

    More research of TS1 chunks:

    FAMI: FamilyInformation.
    It does contian family house number, house value, house rooms, sims in family.
    FAMh: Family History.
    It does contain days after moving and all the billing info.

Share This Page