Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9a3ed83
Add example boss, ore, and incursion content
Jamesp1989SL Jan 20, 2026
515f085
Merge pull request #4 from DrFair/master
Jamesp1989SL Jan 20, 2026
8b2fe81
Add ExampleAI and ExampleAILeaf for mob behavior
Jamesp1989SL Jan 20, 2026
3eca28d
Refactor item structure and add Example Bar item
Jamesp1989SL Jan 21, 2026
e4e729d
Add example sound and play packet for boss mob
Jamesp1989SL Jan 21, 2026
978f2a7
Refactor item/object IDs and add ExampleStoneItem
Jamesp1989SL Jan 22, 2026
17d29f0
Play sound for AI leaf on both teleport and failure
Jamesp1989SL Jan 22, 2026
4439c77
Add landscaping recipes and update item textures
Jamesp1989SL Jan 22, 2026
785c7d2
Add example loot table and preset, update incursion level
Jamesp1989SL Jan 23, 2026
7512ef3
Refactor ExamplePreset and add utility classes
Jamesp1989SL Jan 23, 2026
bab2f9e
Add example wall, door, and window objects
Jamesp1989SL Jan 24, 2026
6406686
Refactor mod initialization into loader classes
Jamesp1989SL Jan 27, 2026
ebde9ad
Add example armor set, categories, and refactor items
Jamesp1989SL Jan 29, 2026
c304209
Refactor and update mod category structure and objects
Jamesp1989SL Feb 1, 2026
28cd55e
Add example tree, sapling, log, and chair objects
Jamesp1989SL Feb 2, 2026
f6844b9
Add examplesapling loot and update assets
Jamesp1989SL Feb 2, 2026
b044a04
Add detailed comments to example preset classes
Jamesp1989SL Feb 2, 2026
6498fca
Add pre-antialias textures Gradle task
Jamesp1989SL Feb 2, 2026
daa3b92
Add example grass biome, tile, object & seed
Jamesp1989SL Feb 3, 2026
7f2bb19
Add example level event, object, and loader
Jamesp1989SL Feb 4, 2026
e326567
Add summon weapon, mob, and level-event object
Jamesp1989SL Feb 5, 2026
b9f6025
Add arrow ammo, bow, projectile & arrow buff
Jamesp1989SL Feb 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,16 @@ task createModInfoFile(type: JavaExec) {
// Makes compiling also create mod info file
classes.dependsOn("createModInfoFile")

task preAntialiasTextures(type: JavaExec) {
group "necesse"
description "Runs pre-antialiasing on all textures in the resources folder"

classpath = files(gameDirectory + "/Necesse.jar")

main "PreAntialiasTextures"
args "-folders", "${sourceSets.main.resources.srcDirs.stream().map {file -> file.path}.toArray().join(";")}"
}

task runClient(type: JavaExec) {
group "necesse"
description "Run client with current mod"
Expand Down
118 changes: 21 additions & 97 deletions src/main/java/examplemod/ExampleMod.java
Original file line number Diff line number Diff line change
@@ -1,126 +1,50 @@
package examplemod;

import examplemod.examples.*;
import examplemod.examples.items.ExampleFoodItem;
import examplemod.examples.items.ExampleHuntIncursionMaterialItem;
import examplemod.examples.items.ExampleMaterialItem;
import examplemod.examples.items.ExamplePotionItem;
import necesse.engine.commands.CommandsManager;
import examplemod.Loaders.*;
import examplemod.examples.maps.biomes.ExampleBiome;
import necesse.engine.modLoader.annotations.ModEntry;
import necesse.engine.registries.*;
import necesse.gfx.gameTexture.GameTexture;
import necesse.inventory.recipe.Ingredient;
import necesse.inventory.recipe.Recipe;
import necesse.inventory.recipe.Recipes;
import necesse.engine.sound.SoundSettings;
import necesse.engine.sound.gameSound.GameSound;
import necesse.level.maps.biomes.Biome;

@ModEntry
public class ExampleMod {

// We define our static registered objects here, so they can be referenced elsewhere
public static ExampleBiome EXAMPLE_BIOME;
public static GameSound EXAMPLESOUND;
public static SoundSettings EXAMPLESOUNDSETTINGS;

public void init() {
System.out.println("Hello world from my example mod!");

// Register a simple biome that will not appear in natural world gen.
EXAMPLE_BIOME = BiomeRegistry.registerBiome("exampleincursion", new ExampleBiome(), false);

// Register the incursion biome with tier requirement 1.
IncursionBiomeRegistry.registerBiome("exampleincursion", new ExampleIncursionBiome(), 1);

// Register the level class used for the incursion.
LevelRegistry.registerLevel("exampleincursionlevel", ExampleIncursionLevel.class);

// Register our tiles
TileRegistry.registerTile("exampletile", new ExampleTile(), 1, true);

// Register our objects
ObjectRegistry.registerObject("exampleobject", new ExampleObject(), 2, true);

// Register our items
ItemRegistry.registerItem("exampleitem", new ExampleMaterialItem(), 10, true);
ItemRegistry.registerItem("examplehuntincursionitem", new ExampleHuntIncursionMaterialItem(), 50, true);
ItemRegistry.registerItem("examplesword", new ExampleSwordItem(), 20, true);
ItemRegistry.registerItem("examplestaff", new ExampleProjectileWeapon(), 30, true);
ItemRegistry.registerItem("examplepotionitem", new ExamplePotionItem(), 10, true);
ItemRegistry.registerItem("examplefooditem", new ExampleFoodItem(),15, true);

// Register our mob
MobRegistry.registerMob("examplemob", ExampleMob.class, true);

// Register our projectile
ProjectileRegistry.registerProjectile("exampleprojectile", ExampleProjectile.class, "exampleprojectile", "exampleprojectile_shadow");

// Register our buff
BuffRegistry.registerBuff("examplebuff", new ExampleBuff());

// Register our packet
PacketRegistry.registerPacket(ExamplePacket.class);
// The examples are split into different classes here for readability, but you can register them directly here in init if you wish
ExampleModCategories.load();
ExampleModEvents.load();;
ExampleModBiomes.load();
ExampleModIncursions.load();
ExampleModTiles.load();
ExampleModObjects.load();
ExampleModItems.load();
ExampleModMobs.load();
ExampleModProjectiles.load();
ExampleModBuffs.load();
ExampleModPackets.load();
}

public void initResources() {
// Sometimes your textures will have a black or other outline unintended under rotation or scaling
// This is caused by alpha blending between transparent pixels and the edge
// To fix this, run the preAntialiasTextures gradle task
// It will process your textures and save them again with a fixed alpha edge color

ExampleMob.texture = GameTexture.fromFile("mobs/examplemob");
ExampleModResources.load();
}

public void postInit() {
// Add recipes
// Example item recipe, crafted in inventory for 2 iron bars
Recipes.registerModRecipe(new Recipe(
"exampleitem",
1,
RecipeTechRegistry.NONE,
new Ingredient[]{
new Ingredient("ironbar", 2)
}
).showAfter("woodboat")); // Show recipe after wood boat recipe
// load our recipes from the ExampleRecipes class so we can keep this class easy to read
ExampleModRecipes.registerRecipes();

// Example sword recipe, crafted in iron anvil using 4 example items and 5 copper bars
Recipes.registerModRecipe(new Recipe(
"examplesword",
1,
RecipeTechRegistry.IRON_ANVIL,
new Ingredient[]{
new Ingredient("exampleitem", 4),
new Ingredient("copperbar", 5)
}
));

// Example staff recipe, crafted in workstation using 4 example items and 10 gold bars
Recipes.registerModRecipe(new Recipe(
"examplestaff",
1,
RecipeTechRegistry.WORKSTATION,
new Ingredient[]{
new Ingredient("exampleitem", 4),
new Ingredient("goldbar", 10)
}
).showAfter("exampleitem")); // Show the recipe after example item recipe

// Example food item recipe
Recipes.registerModRecipe(new Recipe(
"examplefooditem",
1,
RecipeTechRegistry.COOKING_POT,
new Ingredient[]{
new Ingredient("bread", 1),
new Ingredient("strawberry", 2),
new Ingredient("sugar", 1)
}
));

// Add our example mob to default cave mobs.
// Spawn tables use a ticket/weight system. In general, common mobs have about 100 tickets.
Biome.defaultCaveMobs
.add(100, "examplemob");

// Register our server chat command
CommandsManager.registerServerCommand(new ExampleChatCommand());
}

}
15 changes: 15 additions & 0 deletions src/main/java/examplemod/Loaders/ExampleModBiomes.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package examplemod.Loaders;

import examplemod.ExampleMod;
import examplemod.examples.maps.biomes.ExampleBiome;
import necesse.engine.registries.BiomeRegistry;

public class ExampleModBiomes {
public static void load() {
// Register a simple biome that will not appear in natural world gen.
ExampleMod.EXAMPLE_BIOME = BiomeRegistry.registerBiome("examplebiome", new ExampleBiome(), false);
}
}



13 changes: 13 additions & 0 deletions src/main/java/examplemod/Loaders/ExampleModBuffs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package examplemod.Loaders;

import examplemod.examples.buffs.*;
import necesse.engine.registries.BuffRegistry;

public class ExampleModBuffs {
public static void load(){
// Register our buff
BuffRegistry.registerBuff("examplebuff", new ExampleBuff());
BuffRegistry.registerBuff("examplearmorsetbonus", new ExampleArmorSetBuff());
BuffRegistry.registerBuff("examplearrowbuff", new ExampleArrowBuff());
}
}
118 changes: 118 additions & 0 deletions src/main/java/examplemod/Loaders/ExampleModCategories.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package examplemod.Loaders;

import necesse.engine.localization.message.LocalMessage;
import necesse.inventory.item.ItemCategory;

public final class ExampleModCategories {
private ExampleModCategories() {}

/*
* IMPORTANT (Creative Menu requirement)
* ------------------------------------
* The Creative menu tabs currently only browse a small set of hard-coded ROOT categories but this will be changed in the future.
*
* Placeables tab roots: tiles / objects / wiring
* Items tab roots: equipment / consumable / materials / misc
* Mobs tab roots: mobs
*
* So: your itemCategoryTree MUST start with one of those roots, otherwise the item/object
* will not appear in Creative even though it is registered.
*/

// VANILLA PLACABLE
// ===== ROOT =====
public static final String ROOT_TILES = "tiles";
public static final String ROOT_OBJECTS = "objects";
public static final String ROOT_WIRING = "wiring";

// ===== VANILLA: TILES children =====
public static final String TILES_FLOORS = "floors";
public static final String TILES_LIQUIDS = "liquids";
public static final String TILES_TERRAIN = "terrain";

// ===== VANILLA: OBJECTS children =====
public static final String OBJECTS_SEEDS = "seeds";
public static final String OBJECTS_CRAFTINGSTATIONS = "craftingstations";
public static final String OBJECTS_LIGHTING = "lighting";
public static final String OBJECTS_FURNITURE = "furniture";
public static final String OBJECTS_DECORATIONS = "decorations";
public static final String OBJECTS_WALLSANDDOORS = "wallsanddoors";
public static final String OBJECTS_FENCESANDGATES = "fencesandgates";
public static final String OBJECTS_COLUMNS = "columns";
public static final String OBJECTS_TRAPS = "traps";
public static final String OBJECTS_LANDSCAPING = "landscaping";
public static final String OBJECTS_MISC = "misc";

// ===== VANILLA: FURNITURE children =====
public static final String FURNITURE_MISC = "misc";
public static final String FURNITURE_OAK = "oak";
public static final String FURNITURE_SPRUCE = "spruce";
public static final String FURNITURE_PINE = "pine";
public static final String FURNITURE_MAPLE = "maple";
public static final String FURNITURE_BIRCH = "birch";
public static final String FURNITURE_WILLOW = "willow";
public static final String FURNITURE_DUNGEON = "dungeon";
public static final String FURNITURE_BONE = "bone";
public static final String FURNITURE_DRYAD = "dryad";
public static final String FURNITURE_BAMBOO = "bamboo";
public static final String FURNITURE_DEADWOOD = "deadwood";

// ===== VANILLA: DECORATIONS children =====
public static final String DECORATIONS_PAINTINGS = "paintings";
public static final String DECORATIONS_CARPETS = "carpets";
public static final String DECORATIONS_POTS = "pots";
public static final String DECORATIONS_BANNERS = "banners";

// ===== VANILLA: LANDSCAPING children =====
public static final String LANDSCAPING_FORESTROCKSANDORES = "forestrocksandores";
public static final String LANDSCAPING_SNOWROCKSANDORES = "snowrocksandores";
public static final String LANDSCAPING_PLAINSROCKSANDORES = "plainsrocksandores";
public static final String LANDSCAPING_SWAMPROCKSANDORES = "swamprocksandores";
public static final String LANDSCAPING_DESERTROCKSANDORES = "desertrocksandores";
public static final String LANDSCAPING_INCURSIONROCKSANDORES = "incursionrocksandores";
public static final String LANDSCAPING_CRYSTALS = "crystals";
public static final String LANDSCAPING_TABLEDECORATIONS = "tabledecorations";
public static final String LANDSCAPING_PLANTS = "plants";
public static final String LANDSCAPING_MASONRY = "masonry";
public static final String LANDSCAPING_MISC = "misc";

// ===== VANILLA: WIRING children =====
public static final String WIRING_LOGICGATES = "logicgates";


// YOUR MOD ROOT CATEGORY
public static final String MOD = "examplemod";
// YOUR MOD SUB CATEGORY
public static final String MOD_OBJECTS = "objects";

public static final String EXAMPLEWOOD = "examplewood";

public static void load() {

// ITEM CATEGORIES (not Creative-visible right now, but valid categories)
ItemCategory.createCategory("Z-EXAMPLEMOD",
new LocalMessage("itemcategory", "examplemodrootcat"),
MOD);

ItemCategory.createCategory("Z-EXAMPLEMOD-OBJECTS",
new LocalMessage("itemcategory", "examplemodobjectsubcat"),
MOD, MOD_OBJECTS);

ItemCategory.createCategory("Z-EXAMPLEMOD-OBJECTS-FURNATURE",
new LocalMessage("itemcategory", "examplemodfurnaturesubcat"),
MOD, MOD_OBJECTS,EXAMPLEWOOD);

// CRAFTING CATEGORIES
ItemCategory.craftingManager.createCategory("Z-EXAMPLEMOD",
new LocalMessage("itemcategory", "examplemodrootcat"),
MOD);

ItemCategory.craftingManager.createCategory("Z-EXAMPLEMOD-OBJECTS",
new LocalMessage("itemcategory", "examplemodobjectsubcat"),
MOD,MOD_OBJECTS);

ItemCategory.craftingManager.createCategory("Z-EXAMPLEMOD-OBJECTS-FURNATURE",
new LocalMessage("itemcategory", "examplemodfurnaturesubcat"),
MOD,MOD_OBJECTS,EXAMPLEWOOD);
}
}
12 changes: 12 additions & 0 deletions src/main/java/examplemod/Loaders/ExampleModCommands.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package examplemod.Loaders;

import examplemod.examples.ExampleChatCommand;
import necesse.engine.commands.CommandsManager;

public class ExampleModCommands {
public static void load(){

// Register our server chat command
CommandsManager.registerServerCommand(new ExampleChatCommand());
}
}
33 changes: 33 additions & 0 deletions src/main/java/examplemod/Loaders/ExampleModEvents.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package examplemod.Loaders;

import examplemod.examples.events.ExampleEvent;
import examplemod.examples.events.ExampleLevelEvent;
import necesse.engine.GameEventListener;
import necesse.engine.GameEvents;
import necesse.engine.network.server.ServerClient;
import necesse.engine.registries.LevelEventRegistry;

public class ExampleModEvents {
public static void load() {
// Register our Level Event to the registry
LevelEventRegistry.registerEvent("examplelevelevent", ExampleLevelEvent.class);

// Register our ExampleEvent Listener
GameEvents.addListener(ExampleEvent.class, new GameEventListener<ExampleEvent>() {
@Override
public void onEvent(ExampleEvent event) {
if (event.level == null || !event.level.isServer()) return;

ServerClient client = event.level.getServer().getClient(event.clientSlot);
if (client != null) {
client.sendChatMessage(event.message);
client.sendChatMessage("PONG: this message was sent from the ExampleEvent Listener ");
}
}
});

}
}



17 changes: 17 additions & 0 deletions src/main/java/examplemod/Loaders/ExampleModIncursions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package examplemod.Loaders;

import examplemod.examples.maps.incursion.ExampleIncursionBiome;
import examplemod.examples.maps.incursion.ExampleIncursionLevel;
import necesse.engine.registries.IncursionBiomeRegistry;
import necesse.engine.registries.LevelRegistry;

public class ExampleModIncursions {
public static void load() {

// Register the incursion biome with tier requirement 1.
IncursionBiomeRegistry.registerBiome("exampleincursion", new ExampleIncursionBiome(), 1);

// Register the level class used for the incursion.
LevelRegistry.registerLevel("exampleincursionlevel", ExampleIncursionLevel.class);
}
}
Loading