Skip to content

ServerEntityEvents.ALLOW_FRESH_LOAD and AFTER_FRESH_LOAD event#5206

Open
bleudev wants to merge 12 commits intoFabricMC:26.1from
bleudev:26.1
Open

ServerEntityEvents.ALLOW_FRESH_LOAD and AFTER_FRESH_LOAD event#5206
bleudev wants to merge 12 commits intoFabricMC:26.1from
bleudev:26.1

Conversation

@bleudev
Copy link
Copy Markdown

@bleudev bleudev commented Feb 14, 2026

Add two simple server-side events which calls before/after a living entity was added to level (spawned). It is useful for developers who wants do something before/after entity spawn.

Sample:

// Allow fresh load sample
ServerEntityEvents.ALLOW_FRESH_LOAD.register((entity, level) -> {
	if (entity instanceof Creeper creeper) {
		// Spawn with 25% chance zombie instead of creeper
		if (level.getRandom().nextFloat() <= 0.25f) {
			var zombie = EntityType.ZOMBIE.create(level, EntitySpawnReason.EVENT);
			if (zombie != null) {
				zombie.copyPosition(creeper);
				level.addFreshEntity(zombie);
				return false;
			}
		}
	}
	return true;
});

@modmuss50
Copy link
Copy Markdown
Member

What is the difference between this and ServerEntityEvents.ENTITY_LOAD?

@sylv256 sylv256 added the enhancement New feature or request label Feb 15, 2026
@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 15, 2026

What is the difference between this and ServerEntityEvents.ENTITY_LOAD?

The entity load event is called when an entity is loaded upon creation, as well as when the server starts once the entity has been added. My event is called only when an entity is added to the server.

@modmuss50
Copy link
Copy Markdown
Member

Could you use data attachments to keep track of if its the first time the entity was added to the world? E.g store a marker to indicate that your mod has done what it needs to the entity?

@cassiancc
Copy link
Copy Markdown
Member

I'm personally happier with this than having to needlessly keep track of things myself - I've had to mixin in order to do this instead of having an equivalent event to the one on NeoForge. It'd save on unnecessary calls to mod logic by only running when needed instead of every time the entity is loaded/unloaded.

@modmuss50
Copy link
Copy Markdown
Member

At the very least please fix the build issues, and explain the documentation what its for, why it differs from the other and when its fired.

@Patbox
Copy link
Copy Markdown
Member

Patbox commented Feb 16, 2026

Would it maybe make more sense to run the event before entity is actually added to world rather than after? I think for cases where you want to modify it in some way it would be probably cleaner (and maybe allow canceling that within the event).

Maybe rename would be good, since just "adding" an entity feels little bit unspecific, maybe calling it "ON_FRESHLY_ADDED" would be better (since it's more descriptive). Probably would make sense to document it too that it's called when ServerLevel#addFreshEntity runs

@DennisOchulor
Copy link
Copy Markdown
Contributor

Could this be expanded to cover all entities? I'm thinking something like ServerEntityEvents.BEFORE_FRESH_ENTITY_LOAD that's cancellable.

Then ENTITY_LOAD would need some indicator of whether the entity was freshly added or not, similar to #5112 for chunks.
This is for use cases where you want to do some action only if the entity is definetly being spawned, which may not be the case in the cancellable event.

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 17, 2026

Could this be expanded to cover all entities? I'm thinking something like ServerEntityEvents.BEFORE_FRESH_ENTITY_LOAD that's cancellable.

Then ENTITY_LOAD would need some indicator of whether the entity was freshly added or not, similar to #5112 for chunks. This is for use cases where you want to do some action only if the entity is definetly being spawned, which may not be the case in the cancellable event.

Great idea, I thought about it before.

But parameters (similar to chuck load event) - i think no. It will be unnecessary breaking change

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 17, 2026

Could you use data attachments to keep track of if its the first time the entity was added to the world? E.g store a marker to indicate that your mod has done what it needs to the entity?

What do you mean? Sorry for my misunderstanding)

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 17, 2026

Would it maybe make more sense to run the event before entity is actually added to world rather than after? I think for cases where you want to modify it in some way it would be probably cleaner (and maybe allow canceling that within the event).

Maybe rename would be good, since just "adding" an entity feels little bit unspecific, maybe calling it "ON_FRESHLY_ADDED" would be better (since it's more descriptive). Probably would make sense to document it too that it's called when ServerLevel#addFreshEntity runs

Maybe i will do something like BEFORE_FRESH_LOAD and AFTER_FRESH_LOAD?

@bleudev bleudev changed the title ServerLivingEntityEvents.AFTER_ADD event ServerEntityEvents.ALLOW_FRESH_LOAD and AFTER_FRESH_LOAD event Feb 17, 2026
@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 17, 2026

Done some recommendations. Can anyone review?

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 17, 2026

I can't check build issues, workflow awaiting approval

@DennisOchulor
Copy link
Copy Markdown
Contributor

Then ENTITY_LOAD would need some indicator of whether the entity was freshly added or not, similar to #5112 for chunks.

I still think it would be better to add to ENTITY_LOAD instead of a new AFTER_FRESH_LOAD event.

Yes it's a breaking change but if #5112 was considered fine I don't see why this would be unacceptable.

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 20, 2026

Yes it's a breaking change but if #5112 was considered fine I don't see why this would be unacceptable.

Maybe you're right. Probably, we can do breaking changes cause it's snapshots. But I'm waiting for @modmuss50. What he will say about it?

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Feb 21, 2026

I've fixed all issues from checkStyleMain task. Can anyone approve workflow again?

@bleudev bleudev requested a review from modmuss50 February 25, 2026 08:39
@bleudev
Copy link
Copy Markdown
Author

bleudev commented Mar 2, 2026

Will be this pull request reviewed?

Comment on lines +44 to +48
* Called before an Entity is added to a ServerLevel.
*
* <p>If return value is {@code false} entity will not be added to a server.</p>
*
* <p>Should be used when you want to add another entity instead of added or to block adding specific entities.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still doesnt explain when this is invoked and why its different from the other entity events.

Im a little bit concerned about this injection point as it doenst really do anything special: https://mcsrc.dev/1/26.1-snapshot-11/net/minecraft/server/level/ServerLevel#L951-953 and is possibly going to miss certain types of spawns.

* <p>When this event is called, the entity is already in the level.</p>
*
* <p>Should be used when you need to do something after entity summon, naturally spawn or any other add reason.</p>
* <p>If you need to do something after entity every entity load (not the first one) use ENTITY_LOAD event.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do wonder if the regular ENTITY_LOAD event could do with some sort of context instead? E.g being able to target only spawn eggs, or natural spawns. It would be a lot more robust than just another event that is fired within a questionable method.

@modmuss50
Copy link
Copy Markdown
Member

Been thinking some more, could this event just be replaced by:

	public static ScopedValue<LoadContext> LOAD_CONTEXT = ScopedValue.newInstance();

	public enum LoadContext {
		SPAWN_EGG,
		NATURAL_SPAWN,
		/// Others here
	}

in ServerEntityEvents? And then you would just need some trivial mixins in the specific places you care about to set the context around the addEntity calls?

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Mar 4, 2026

Been thinking some more, could this event just be replaced by:

	public static ScopedValue<LoadContext> LOAD_CONTEXT = ScopedValue.newInstance();

	public enum LoadContext {
		SPAWN_EGG,
		NATURAL_SPAWN,
		/// Others here
	}

in ServerEntityEvents? And then you would just need some trivial mixins in the specific places you care about to set the context around the addEntity calls?

Okay, it's great idea. I will try to do that

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Mar 4, 2026

Been thinking some more, could this event just be replaced by:

	public static ScopedValue<LoadContext> LOAD_CONTEXT = ScopedValue.newInstance();

	public enum LoadContext {
		SPAWN_EGG,
		NATURAL_SPAWN,
		/// Others here
	}

in ServerEntityEvents? And then you would just need some trivial mixins in the specific places you care about to set the context around the addEntity calls?

I have a question. Do you suggest to remove FRESH_LOAD events and use LOAD_CONTEXT in code? If you do, i suggest to rename ALLOW_FRESH_LOAD to ALLOW_ADD and do not remove it. It's simple way to discard entity add before adding.

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Mar 4, 2026

I've probably did it, but not sure (I can't run Fabric Gradle project for some reason)

@bleudev
Copy link
Copy Markdown
Author

bleudev commented Mar 4, 2026

I've used EntitySpawnReason cause it contains all need reasons and it is used in EntityType.spawn() method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants