Skip to content

Data Driven

The Sims 4 is extremely data driven, so we’re not going to cut corners. You don’t need to remember all the details, but it’s useful to have heard at least once.

Computers store information in a format called binary. Binary stores individual 1s and 0s, called bits. These bits are stored in groups of 8, called bytes. Finally, one or more bytes can be used to create a primitive data type that stores information. Here’s the standard types:

TypeDescriptionExamplesBytes
Boolean boolTrue / Falsetrue, false1-8
ByteWhole Numbers1, 17, -141
ShortWhole Numbers1, 17, -142
Integer intWhole Numbers2, 18, -134
LongWhole Numbers3, 19, -128
FloatFractions3, 2.4, -3.3454
DoubleFractions4, 3.7, -4.4278
StringText”text123”, “John Smith”Varies

Primitive data types are used as the building blocks for all other data types, as we’ll see later on.

Numbers are infinite. Fractions are infinite. Because of this, there are several number types depending on if you want to store whole numbers or fractions, and what you want the max value to be. Integer and Float tend to be the most common. You may also sometimes see a number marked as unsigned, which means it doesn’t support negatives but has a larger max value.

When modding, you’ll often see numbers stored as hexadecimal (aka hex), which uses the 0x prefix (0xB6FA7167, for example). While we normally use base 10 (which has 10 digits, 0-9), hex uses base 16 (16 digits, 0-F). Hex is often used when displaying numbers or binary as text to save space.

There are tools available for converting between decimal and hex if required.

Now we can define data using explicit types!

name : String = "John"
tv_on : Boolean = true
temperature : Float = 36.4
user_id : Integer = 89104328

We often want to group data conceptually into some sort of object. Consider a person with a first name, last name, and age. There isn’t a single data type for that, so let’s create a Person object using multiple types from earlier.

This concept is called different things, but you’ll often hear object, class, and struct.

Person {
firstName : String
lastName : String
age: Int
socialSecurityNumber: Int
}

Now we have a way to store information about people! We even added a socialSecurityNumber as a little treat. Let’s use it to store some information.

p1 = Person(firstName="John", lastName="Smith", age=45, socialSecurityNumber=85037826)
p2 = Person(firstName="Rachel", lastName="Doe", age=39, socialSecurityNumber=79815634)
p3 = Person(firstName="Jeremy", lastName="Jones", age=65, socialSecurityNumber=10348534)

Now we can resolve p1.firstName to John!

While this example used a person, objects can use primitive data types, as well as other objects, to define virtually any new data type.

Next we might want to group many people together into a single structure. We’ll look at two common ones, array and map, using the People from the previous example.

An array (also known as a list) stores values as, you guessed it, a list. The entires can be indexed by number, typically starting at index 0.

people_array = [p1, p2, p3]

Now people[0].firstName resolves to John and people[1].firstName resolves to Rachel. Yes, people[0] = p1 due to indexes starting at 0, but the variable names from earlier starting at 1. That’s how it goes sometimes. You’ll get used to it.

Arrays are easy to iterate though, so they are great for tasks like “print every person’s name” or “filter people by age”.

Sometimes we want to map a key to a value. For example, we can map a person’s socialSecurityNumber from earlier to the person object for easy lookup.

people_map = {
85037826: p1,
09815634: p2,
10348534: p3,
}

Now if we have a person’s socialSecurityNumber, we can get resolve the rest of their information without having to iterate through every person. people_map[85037826].firstName now resolves to John.

There are other types of data structures (set, tree, queue, etc), but you don’t need them unless you get into more advanced programming topics. For general modding array and map are sufficient.