Skip to content

Making a New Sensor

Tslat edited this page Jan 7, 2023 · 6 revisions

If none of the existing sensors serve your needs, you can always make another custom sensor.

Design Philosophy

While making a sensor, it's important to note the design philosophy of the brain system itself. Failing to do so starts to erode many of the benefits of the brain system

  1. A sensor should be designed to fill one function only.
  2. A sensor should not perform any actions on the entity besides settings/clearing/checking memories.

Sharing

If your sensor is generic enough that it could be feasibly used on different entities or by other people, consider sharing it to SBL so that it can be bundled and other people who use SBL can make use of it! Either make a PR with the new sensor, or create an issue linking to its source in your mod with permission to use it.

The more we build up the library, the better!

Making a Sensor

Sensors have two components:

  1. The SensorType
  2. The Sensor instance

The SensorType

The SensorType is a factory method registered via DeferredRegister on the SENSOR_TYPES registry. See the SBLSensors registry for examples

The Sensor Class

The sensor class is the actual functional sensor your entity uses. Your entity is given an instance of it, which then performs the scanning operations.

All sensors must extend one of the base ExtendedSensor classes SBL provides, must provide the SensorType, and the list of memory types the sensor uses.

You can see what each of the base classes do on the builtin sensors page

Let's make a new sensor that detects whether the entity is in lava or not:

public class InLavaSensor<E extends LivingEntity> extends PredicateSensor<E, E> { // Extend PredicateSensor so we can use the builtin predicate to check for lava
    private static final List<MemoryModuleType<?>> MEMORIES = ObjectArrayList.of(MyMemoryTypes.IS_IN_LAVA); // Make a static list of memories this sensor applies to. For this example we'll assume we registered a custom MemoryModuleType in MyMemoryTypes

    public InLavaSensor() { // Sensors should have a parameter-less constructor. Use functional methods to set additional variables
        super((entity2, entity) -> entity.isInLava()); // Set the predicate to use in the scan, in our case we'll check if the entity is in lava
    }

    @Override
    public List<MemoryModuleType<?>> memoriesUsed() {
        return MEMORIES; // Return our memory list
    }

    @Override
    public SensorType<? extends ExtendedSensor<?>> type() {
        return MySensorTypes.IN_LAVA.get(); // Return the SensorType for this sensor. For this example we'll assume we registered our sensortype in MySensorTypes
    }

    @Override
    protected void doTick(ServerLevel level, E entity) {
        if (predicate().test(entity, entity)) { // Use the predicate we set in the constructor to check if entity is in lava
            BrainUtils.setMemory(entity, MyMemoryTypes.IS_IN_LAVA, true); // Set the memory status if we're in lava
        }
        else {
            BrainUtils.clearMemory(entity, MyMemoryTypes.IS_IN_LAVA); // Clear the memory if no longer applicable.
        }
    }
}

That's it!

For using the sensor, see Making an Entity With SmartBrainLib

Clone this wiki locally