Skip to content

Java API (Advanced) ​

With a vehicle pack you do not need this page. An add-on mod keeps the vehicle with the rest of your mod; its assets are exactly a pack's (in the mod's src/main/resources). The example project is VetturaExample.

The project ​

  1. Copy the VetturaExample folder; change mod_id, mod_name and mod_group_id in gradle.properties, then rename the Java package and the assets/vettura_example and data/vettura_example folders to your mod id.
  2. vettura_repo and vextris_repo in gradle.properties point at the two libraries' Maven repositories (local folders in the example; the public addresses once released).
  3. build.gradle depends on Vettura and Vextris with implementation fg.deobf(...): in development they load as their own mods. Do not bundle them into your jar.
  4. META-INF/mods.toml declares a dependency on vettura, ordering="AFTER".
  5. Keep the two mixin properties in the example's build.gradle (mixin.env.remapRefMap, mixin.env.refMapRemappingFile): the development environment needs them.

Build: .\gradlew.bat build. Client: .\gradlew.bat runClient.

Registering (four things) ​

The example code is src/main/java/com/example/vetturaexample/VetturaExample.java. Keep this order:

java
// 1. the vehicle type: physics, frame, sounds, the damage HUD's panes. Registered before the entity type is built
public static final VehicleType COUPE = VehicleType.builder(COUPE_ID)
        .spec(coupeSpec())
        .layout(coupeLayout())
        .hudPanes(...)          // optional
        .sounds(...)            // optional; the T15's diesel without
        .fuel(Fuel.PETROL)      // optional; diesel without
        .keyless()              // optional: a start button (the key anywhere on the driver, hold the start key); without, the key goes in and turns
        .paints(List.of(new VehicleSpawnerItem.Paint("my_red", 0xA51616, 0xA51616), ...))   // optional: factory colours (main, second), at least two
        .handbrake(null, null)  // optional: the parking brake set and let off; null for silent (an electric one); without, the T15's ratchet lever
        .shiftSound(null)       // optional: a gear change's sound; null for none (an automatic); without, the T15's lever
        .register();

// 2. the entity type: Vettura's vehicle entity, under the same id
ENTITY_TYPES.register("whitebox_coupe",
        () -> EntityType.Builder.<PickupTruckEntity>of(PickupTruckEntity::new, MobCategory.MISC)
                .sized(1.9F, 1.4F).clientTrackingRange(10).build("whitebox_coupe"));

// 3. the spawner and the key
ITEMS.register("whitebox_coupe", () -> new VehicleSpawnerItem(new Item.Properties().stacksTo(1), COUPE_ENTITY));
ITEMS.register("whitebox_coupe_key", () -> new VehicleKeyItem(new Item.Properties().stacksTo(1), COUPE_ID));

// 4. the client: Vettura's renderer
event.registerEntityRenderer(COUPE_ENTITY.get(), PickupTruckRenderer::new);

An entity finds its vehicle type by its entity type's id (VehicleType.of), so the two ids must match. The entity's sized only sets vanilla's picking box and pathfinding; the real collision comes from the frame and the hull.