File Details
Combat Toggle 1.2.0 (Forge 1.19.2)
- R
- May 8, 2026
- 53.50 KB
- 4.8K
- 1.19.2
- Forge
File Name
combattoggle-1.2.0.jar
Supported Versions
- 1.19.2
Curse Maven Snippet
[1.2.0] - 2026-05-08
The 1.19.2 line's first server-installable release. Vanilla clients can now join modded servers running Combat Toggle and use /ct without installing anything client-side. Internal architecture rewritten around a Forge capability and a hybrid common/server/client package layout. Breaking for the 1.1.x persistent-timer schema (mode preserved; tags and cooldowns reset on first login).
Server-installable, vanilla-client-tolerant
mods.tomlnow declaresdisplayTest = "IGNORE_SERVER_VERSION". Vanilla clients no longer see the red ❌ in the multiplayer list when targeting a modded server.- The network channel uses
NetworkRegistry.acceptMissingOr(PROTOCOL::equals). Vanilla clients pass the handshake; the channel quietly drops S2C packets to peers without it registered. - Player commands are the new baseline UX for vanilla-client users:
/cttoggles/combatand/peaceset explicitly/combattoggle statusand/combattoggle helpview + discover
PvP enforcement hardening
- Primary cancel moved from
LivingHurtEventtoLivingAttackEvent(HIGH priority). Stops the hurt pipeline before knockback, hurt sound, and thePLAYER_HURT_ENTITYadvancement criterion fire — no more free knockback shots on Peace targets.LivingHurtEventremains as defence-in-depth and clears residualdeltaMovement+hurtMarked. - Attacker resolution walks the standard ownership chain: direct hit → projectile owner → primed-TNT owner → tamed pet (
OwnableEntity). Wolves, snow golems, ignited TNT are now correctly gated by Combat Toggle.
Capability-backed state
CombatToggleDatais now a Forge capability attached to everyPlayer.CombatToggleData.get(player)returns the same in-memory instance for the lifetime of that player — no per-call NBT alloc, no async-mutation races.- Time-based fields migrated from wall-clock millis to game ticks (
level.getGameTime()). Monotonic, persisted, restart-safe. - Clone-on-respawn copies state via
PlayerEvent.Clonewith the standardreviveCaps/invalidateCapsdance.
One-shot legacy NBT migration
- On first 1.2.0 login, the pre-1.2.0
combat_togglecompound onplayer.getPersistentData()is read. Theenabledflag is preserved into the new capability; the wall-clock-millis timestamps (lastToggleMs,combatTagUntilMs,lastPvpMs) are dropped — they cannot be safely interpreted against the new game-tick clock. The legacy compound is removed after migration. Logged once per player asMigrated legacy combat_toggle data for {name} (preserved mode={MODE}, dropped expired timers).
Configurable HUD position
New client-config keys in combattoggle-client.toml:
| Key | Default | Notes |
|---|---|---|
hudEnabled |
true |
Master switch |
hudShowInCombatMode |
true |
Hide while in Combat |
hudShowInPeaceMode |
true |
Hide while in Peace |
hudAnchor |
TOP_CENTER |
9-anchor + CUSTOM (absolute screen coords) |
hudOffsetX |
0 |
Inward pixel offset from anchor |
hudOffsetY |
6 |
Inward pixel offset from anchor |
hudScale |
1.0 |
0.5 – 3.0 |
hudShowTimers |
true |
Tag + cooldown countdown text |
The 1.1.0 server config key showHud is dropped — HUD visibility is purely client-side now. Operator configs keep the orphan key on first read with a Forge unused-key warning; harmless.
Architecture
Source split into three packages:
common/— config spec, capability state + registration, network packets. No client-class imports; loadable on dedicated server.server/— gameplay logic (commands, lifecycle events, PvP enforcement, scoreboard teams). Loaded on every logical server (dedicated and integrated). Zeronet.minecraft.client.*references.client/— HUD overlay, keybind, client-side cache. Every subscriber gated with@Mod.EventBusSubscriber(value = Dist.CLIENT)so dedicated server never classloads them.
Network
- Protocol version
"1"(1.2.x line). 1.1.x modded clients are cleanly handshake-rejected; vanilla clients pass throughacceptMissing. - Wire format for
S2CSyncStatePacket:boolean | varInt seconds | varInt seconds. ~5 bytes total. C2SRequestTogglePacketcarries no payload — the server identifies the requester viactx.getSender().

