Skip to content

Iron Man#72

Closed
duzos wants to merge 5 commits into
masterfrom
feat/ironman
Closed

Iron Man#72
duzos wants to merge 5 commits into
masterfrom
feat/ironman

Conversation

@duzos

@duzos duzos commented May 4, 2026

Copy link
Copy Markdown
Owner

Summary

Builds out the Iron Man kit on feat/ironman: combat (repulsor, uni-beam, missiles, shield), an intense flight system with boost/dive/barrel-roll, two new marks (mk50, mk85), a reusable per-pixel nano-assembly shader, sentry-mode AI, and a full Jarvis HUD overhaul. Branched from master with general suit/biped fixes cherry-picked from the spiderman + superman branches.

Cherry-picks

Commit What
1a044e3 dilation on Steve+Alex suit cuboids fixes z-fighting between suit and skin
de79cf0 flight tilt now runs inside setAngles so the biped follows the tilt
6298765 suit arm renders alongside vanilla; SuitFeature.copyTo after setAngles so biped picks up suit pose
5fe1225 FlightPower.hasFlight gates on the worn suit's powers (no pole-vault when swapping) + explicit walk-cycle in suit setAngles

Combat

Repulsor blast (left-click empty hand)

  • New Power.handlesLeftClick virtual hook + PowerLeftClickHandler polling attackKey
  • Server raycasts 32m from firing palm, applies damage profile + small knockback, spawns RepulsorBlastEntity for the visual line that fades over 8 ticks
  • 8-tick per-player cooldown
  • applyPose raises the firing arm forward for 6 ticks, lerped
  • RepulsorPower.fireFrom(LivingEntity, Vec3d) is reusable - the sentry-mode drone calls into it directly
  • SFX cue on fire

Uni-beam (hold key 4)

  • 20-tick charge then 40-tick continuous beam phase
  • Server: each shooting tick raycasts from entity.getBodyY(0.7), damages entities along the line, particles at the terminus
  • Client: UniBeamRenderer registered via WorldRenderEvents.AFTER_TRANSLUCENT draws a glowing line from chest to terminus
  • HUD energy bar fills during charge, switches colour during fire

Missile volley (key 3 on mk7/mk85)

  • 6 homing MissileEntity projectiles in a fan above the player, each homes on nearest hostile within 24m or arcs forward if no target
  • Smoke particle trail, explodes on impact
  • Block damage opt-in via /gamerule timelessSuitBlockDamage
  • 5-second cooldown

Shield (toggle key on mk5/mk7/mk85)

  • ShieldDamageMixin injects LivingEntity.damage HEAD; while active and damage source isn't fall/void/drown/wall, scale incoming by 0.4
  • 8-hit stamina; depleting force-toggles off + 60-tick cooldown
  • HUD shows SHIELD indicator while active

Flight overhaul

IronManFlightPower extends FlightPower adding boost + dive:

  • Boost - sprint while flying enables boost (isBoosting), sets a flag that the tilt mixin reads to lean further
  • Dive - sets IronDiving to true and retains horizontal velocity (v *= 1.0989 per tick) until ground or 80-tick timeout
  • Barrel roll (BarrelRollPower, key V) - sets a roll timer ±16 ticks; IronManFlightTilt rotates the body around its forward axis by rollProgress * 360° while the timer winds down

IronManFlightState is a per-player client-side smoothed timer (mirrors WebSwingState pattern):

  • flight, boost, dive timers each ramp 0..1 over 6 ticks via STEP = 1/6
  • IronManFlightTilt reads them, applies pitch (clamped -85..+25°) and roll (clamped ±45°) via LivingEntityRenderer.setupTransforms TAIL mixin (IronManFlightRendererMixin)

BipedFlightPoseMixin injects BipedEntityModel.setAngles HEAD and clears model.sneaking = false; leaningPitch = 0 while the entity is in any flight mode, so vanilla's sneak/swim crouch never fights the tilt at high speed.

Mark expansion

Existing mk3/mk5/mk7 swap from basic FLIGHT/BOOSTED_FLIGHT to IRON_FLIGHT and gain combat powers:

  • mk3: + REPULSOR
  • mk5: + REPULSOR, UNI_BEAM, SHIELD
  • mk7: + REPULSOR, UNI_BEAM, MISSILE_VOLLEY, SHIELD, BARREL_ROLL

Two new marks:

  • mk50 (MarkFiftySuit, nano-tech, red glow) - IRON_FLIGHT, HOVER, MASK_TOGGLE, REPULSOR, UNI_BEAM, MISSILE_VOLLEY, SHIELD, BARREL_ROLL, NANO_ASSEMBLE, JARVIS
  • mk85 (MarkEightyFiveSuit, top-tier, gold glow) - everything mk50 has + SENTRY

Both implement the new NanoAssemblableSuit interface with distinct edge colours.

Reusable per-pixel nano-assembly

For any suit that implements NanoAssemblableSuit (provides edge colour + max radius + assemble ticks):

  • NanoAssemblePower ramps a per-player NanoProgress 0..1 over getNanoAssembleTicks() ticks; re-triggered on onLoad (so re-equipping replays the animation)
  • Custom core shader at assets/timeless/shaders/core/nano_assemble.{json,vsh,fsh} registered via CoreShaderRegistrationCallback in NanoShaderHolder
  • Fragment shader computes per-pixel distance from the suit's chest origin in model space, normalises against NanoMaxRadius. Adds per-fragment scatter noise via a hash function. If dist > progress + scatter, discard. Edge band tinted with NanoEdgeColor
  • NanoAssembleRenderLayer.of(texture) builds a custom RenderLayer.MultiPhaseParameters with the shader, translucent transparency, no culling
  • SuitFeature swaps the render layer when the worn suit is NanoAssemblableSuit && progress < 1, calling NanoShaderHolder.setUniforms(progress, originY, maxRadius, edgeColor) first

Per-pixel reveal sweeps from chest outward with a scattered fuzzy boundary glow.

Sentry AI

Replaced the stub goal in IronManEntity with two new goals:

  • RepulsorAttackGoal - within 24m of any hostile, fires repulsor every 30 ticks via RepulsorPower.fireFrom. Reuses the player repulsor.
  • MoveToTargetGoal - while target > 12m away, navigates toward it at 1.2 speed
  • Existing FollowOwnerGoal retained at lower priority

Jarvis HUD

JarvisGui extended with five new panels (only render with mask closed):

  • EnergyBar - bottom centre uni-beam charge + repulsor cooldown
  • SuitIntegrity - bottom-left chestplate-durability percentage with colour-coded bar
  • FlightMode - bottom-right HOVER / CRUISE / BOOST / DIVE
  • TargetingReticle - centre-screen corner brackets on hostile under crosshair within 32m
  • ThreatList - top-right 3 nearest hostiles by distance

Controls

Input Effect
Left-click (empty main hand) Repulsor blast
Power key 1 (Z) Toggle iron flight
Power key 2 (R) Hover toggle
Power key 3 (G) Mask toggle
Power key 4 (H) Charge + fire uni-beam
Power key 5 (V) Barrel roll
Sprint while flying Boost
Toggle flight while sprinting+airborne Dive
Power keys 6-9 (B/N/M/J) Reserved for additional powers per mark

SFX

9 new sound events registered: ironman_repulsor, ironman_unibeam_charge, ironman_unibeam_fire, ironman_missile_launch, ironman_shield_hit, ironman_targetlock, ironman_nano_assemble, ironman_boost, ironman_dive. Placeholder ogg files cloned from ironman_powerup so audio plays during testing; final assets to be sourced.

Test plan

  • Equip mk7, left-click - repulsor fires, hits creeper, knocks it back
  • Hold H wearing mk7 - 1s charge then 2s continuous beam visible third-person
  • mk7 missile volley (key 3 reused if it's bound) - 6 missiles fan out, home on hostile
  • mk5 shield toggle - incoming arrow damage reduced ~60%
  • mk50 equip - per-pixel nano sphere expands from chest with red boundary glow
  • mk85 equip - same effect with gold boundary
  • Flight: jump+fly, sprint to boost, V to barrel roll mid-air
  • Flight pose: no high-speed sneak-pose breakage
  • Sentry mode (mk7 SENTRY power) - drone engages nearby hostile with repulsors
  • HUD elements only render when mask closed; FlightMode label updates HOVER/CRUISE/BOOST/DIVE
  • /gamerule timelessSuitBlockDamage true then volley a wall - blocks break; default false leaves them intact
  • Cherry-picks: no z-fighting on any Iron Man suit; flight tilt syncs to biped

duzos added 5 commits May 4, 2026 23:01
base cuboids on stevesuitmodel and alexsuitmodel had dilation 0.0 - same dimensions as the player skin underneath - so the suit z-fought with the body wherever they overlap (whole torso, arms, legs).

bumped base layer to dilation 0.25 (suit always slightly outside the player skin) and overlay layer to 0.5 (always slightly outside the new base) so the layering is body < suit-base < suit-overlay with clear depth separation. matches the convention vanilla uses for armor models.

bonus: revert from previous commit was that supermansuit's isalwaysvisible removal still applies; that was a separate visibility-during-invisibility issue, not the z-fight one.
rotateParts (the procedural flight tilt + roll on body/limbs) was being called inside each suit model's render() method. but suitfeature already does:

  copyfrom(biped)  -> suit takes biped pose
  setangles(...)   -> suit runs animations
  copyto(biped)    -> player biped takes suit pose
  model.render()   -> rotateparts ran here, too late

so the tilt landed on the suit only. the player's actual biped (which the suit visually overlays) kept its un-tilted pose, leaving a visible mismatch in flight.

centralized the timing: suitmodel.setangles now calls a protected rotateparts hook (default no-op) right after runanimations, gated on the same anim/transform condition the subclasses used. moved the actual implementations from private to @OverRide protected in stevesuitmodel, alexsuitmodel, genericironmanmodel, markfivemodel and removed the rotateparts call from each render(). the per-model translates/scales that lived alongside rotateparts in render() stay where they were (those are render-only matrix ops, not part-state mutations).
…ield, nano-assembly, mk50/mk85, jarvis hud

- intense flight overhaul: iron flight power with sprint-boost, dive (horizontal velocity retention), barrel roll (V key), pose presets (hover/cruise/boost/dive)
- flight tilt mixin clamps body pitch/roll smoothly; biped flight pose mixin suppresses vanilla sneak/swim breakage at speed
- repulsor: left-click empty hand fires raycast blast 32m with knockback, brief arm-up pose, 8-tick cooldown
- uni-beam: hold key 4 to charge 1s then continuous chest beam 2s, damages along line, hud charge bar
- missile volley: 6 homing missiles in fan, smoke trail, explode on impact (block damage gated on gamerule)
- shield: toggle blocks 60% damage with stamina drain + 3s cooldown, mixin into LivingEntity.damage
- per-pixel nano-assembly: custom core shader expands sphere from chest with scattered noise threshold, edge glow tint per-suit; reusable via NanoAssemblableSuit interface
- mk3/mk5/mk7 power lists upgraded with iron flight + combat kit; mk50 (nano-tech, red glow) and mk85 (full kit + nano gold) added
- sentry mode ai: repulsor attack goal + move-to-target goal; drone engages hostiles in 32m radius
- jarvis hud extended: energy bar, suit integrity %, flight mode, targeting reticle, threat list (top 3 hostiles)
- timelessSuitBlockDamage gamerule for opt-in block destruction
- Power.java gains handlesLeftClick + applyPose virtual hooks; PowerLeftClickHandler + PowerRightClickHandler dispatch via UsePowerC2SPacket
- 9 power keybinds (1-4 + V/B/N/M/J for 5-9)
- 9 new sfx events registered with placeholder oggs cloned from ironman_powerup
- access-widener exposes RenderPhase.ShaderProgram + Texture for the custom nano render layer
Copilot AI review requested due to automatic review settings May 4, 2026 22:40
@duzos duzos requested a review from a team as a code owner May 4, 2026 22:40
@github-actions github-actions Bot added S: Untriaged Status: Indicates an item has not been triaged and doesn't have appropriate labels. A: Datagen Area: Datagen implementation & API. C: Audio Changes: Might require knowledge of audio. C: Textures Changes: Might require knowledge of spriting or visual design. and removed S: Untriaged Status: Indicates an item has not been triaged and doesn't have appropriate labels. labels May 4, 2026
@duzos duzos added the enhancement New feature or request label May 4, 2026
@duzos

duzos commented May 4, 2026

Copy link
Copy Markdown
Owner Author

lame

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR expands the Iron Man feature set across suits, powers, rendering, HUD, entities, and input handling. It introduces new combat/flight mechanics (repulsor, uni-beam, missiles, shield, barrel roll, iron-flight tilt), adds Mk50/Mk85, implements a reusable nano-assembly shader/render layer, and updates sentry AI + Jarvis HUD panels.

Changes:

  • Adds new Iron Man powers (repulsor, uni-beam, missiles, shield, barrel roll, nano-assemble) and wires them into Mk3/Mk5/Mk7 + new Mk50/Mk85 suit sets.
  • Adds new entities/renderers (missiles, repulsor blast) and new client render systems (iron-flight tilt state, uni-beam world renderer, nano shader + render layer).
  • Extends the suit model pipeline to support procedural per-frame pose hooks and power-driven pose application.

Reviewed changes

Copilot reviewed 55 out of 74 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
src/main/resources/timeless.mixins.json Registers new mixins for shield damage scaling and iron-flight pose/renderer tweaks.
src/main/resources/timeless.accesswidener Adds access widening needed for custom RenderLayer MultiPhase + shader plumbing.
src/main/resources/assets/timeless/shaders/core/nano_assemble.vsh Nano-assemble vertex shader for per-pixel reveal pipeline.
src/main/resources/assets/timeless/shaders/core/nano_assemble.json Shader program definition (samplers/uniforms/blend config).
src/main/resources/assets/timeless/shaders/core/nano_assemble.fsh Nano-assemble fragment shader (discard threshold + edge tint).
src/main/java/mc/duzo/timeless/Timeless.java Initializes new TimelessGameRules.
src/main/java/mc/duzo/timeless/suit/set/SetRegistry.java Registers new Mk50/Mk85 suit sets.
src/main/java/mc/duzo/timeless/suit/ironman/mk85/MarkEightyFiveSuit.java Adds Mk85 suit definition + nano-assemble config + power list.
src/main/java/mc/duzo/timeless/suit/ironman/mk85/client/MarkEightyFiveModel.java Mk85 client model wrapper resolving suit from SetRegistry.
src/main/java/mc/duzo/timeless/suit/ironman/mk7/MarkSevenSuit.java Updates Mk7 powers to use IRON_FLIGHT + combat suite.
src/main/java/mc/duzo/timeless/suit/ironman/mk50/MarkFiftySuit.java Adds Mk50 suit definition + nano-assemble config + power list.
src/main/java/mc/duzo/timeless/suit/ironman/mk50/client/MarkFiftyModel.java Mk50 client model wrapper resolving suit from SetRegistry.
src/main/java/mc/duzo/timeless/suit/ironman/mk5/MarkFiveSuit.java Updates Mk5 powers to use IRON_FLIGHT + repulsor/uni-beam/shield.
src/main/java/mc/duzo/timeless/suit/ironman/mk5/client/MarkFiveModel.java Adjusts flight-rotation hook visibility to integrate with new base rotation pipeline.
src/main/java/mc/duzo/timeless/suit/ironman/mk3/MarkThreeSuit.java Updates Mk3 powers to use IRON_FLIGHT + repulsor.
src/main/java/mc/duzo/timeless/suit/ironman/IronManEntity.java Adds sentry-mode goals: repulsor attack + move-to-target.
src/main/java/mc/duzo/timeless/suit/ironman/client/GenericIronManModel.java Moves procedural rotations into shared setAngles-driven pipeline.
src/main/java/mc/duzo/timeless/suit/client/render/SuitModel.java Adds rotateParts hook + per-power applyPose dispatch + biped part accessors.
src/main/java/mc/duzo/timeless/suit/client/render/SuitFeature.java Adds nano-assemble render layer swap + copies pose back to biped after setAngles.
src/main/java/mc/duzo/timeless/suit/client/render/generic/SteveSuitModel.java Adjusts dilations and routes walk-cycle via setAngles, integrating rotateParts hook + bone accessors.
src/main/java/mc/duzo/timeless/suit/client/render/generic/AlexSuitModel.java Same as Steve model changes for Alex proportions.
src/main/java/mc/duzo/timeless/suit/api/NanoAssemblableSuit.java Introduces nano-assemble marker/config interface (edge color, radius, ticks).
src/main/java/mc/duzo/timeless/power/PowerRegistry.java Registers new Iron Man powers including IRON_FLIGHT/combat/nano.
src/main/java/mc/duzo/timeless/power/Power.java Adds click-handling hooks and per-frame pose hook for powers.
src/main/java/mc/duzo/timeless/power/impl/UniBeamPower.java Adds uni-beam charge/fire server logic + per-tick damage/particles.
src/main/java/mc/duzo/timeless/power/impl/ShieldPower.java Adds shield toggle + hit stamina + cooldown + damage scaling helper.
src/main/java/mc/duzo/timeless/power/impl/RepulsorPower.java Adds repulsor blast server logic + beam entity spawn + pose hook entry points.
src/main/java/mc/duzo/timeless/power/impl/NanoAssemblePower.java Adds nano-assemble progress tracking and on-load retrigger behavior.
src/main/java/mc/duzo/timeless/power/impl/MissileVolleyPower.java Adds missile volley spawning with cooldown tracking.
src/main/java/mc/duzo/timeless/power/impl/IronManFlightPower.java Adds iron-flight boost/dive state tracking and dive velocity retention.
src/main/java/mc/duzo/timeless/power/impl/FlightPower.java Ensures flight booleans are gated by currently worn suit flight powers.
src/main/java/mc/duzo/timeless/power/impl/BarrelRollPower.java Adds barrel-roll timer state for renderer-driven roll animation.
src/main/java/mc/duzo/timeless/mixin/ShieldDamageMixin.java Scales incoming damage while shield active (except select environmental sources).
src/main/java/mc/duzo/timeless/mixin/client/PlayerEntityRendererMixin.java Renders suit arm at renderArm tail (no longer cancels vanilla).
src/main/java/mc/duzo/timeless/mixin/client/IronManFlightRendererMixin.java Applies iron-flight tilt in LivingEntityRenderer.setupTransforms tail.
src/main/java/mc/duzo/timeless/mixin/client/BipedFlightPoseMixin.java Clears vanilla sneak/lean pose during flight modes to avoid fighting tilt.
src/main/java/mc/duzo/timeless/entity/RepulsorBlastEntity.java Adds short-lived visual beam entity with synced endpoint.
src/main/java/mc/duzo/timeless/entity/MissileEntity.java Adds homing missile entity with optional block-damage via gamerule.
src/main/java/mc/duzo/timeless/datagen/TimelessDataGenerator.java Adds translations for new power keys, items, and sound events.
src/main/java/mc/duzo/timeless/core/TimelessSounds.java Registers new Iron Man sound events.
src/main/java/mc/duzo/timeless/core/TimelessGameRules.java Adds timelessSuitBlockDamage gamerule.
src/main/java/mc/duzo/timeless/core/TimelessEntityTypes.java Registers REPULSOR_BLAST and MISSILE entity types.
src/main/java/mc/duzo/timeless/core/items/SuitItem.java Adds int/float SuitItem.Data helpers with sync support.
src/main/java/mc/duzo/timeless/client/TimelessClient.java Initializes flight state + nano shader registration; registers uni-beam world renderer; registers new entity renderers.
src/main/java/mc/duzo/timeless/client/render/UniBeamRenderer.java Renders uni-beam line in world for shooting players.
src/main/java/mc/duzo/timeless/client/render/NanoShaderHolder.java Registers nano shader and provides uniform update helper.
src/main/java/mc/duzo/timeless/client/render/NanoAssembleRenderLayer.java Defines custom RenderLayer using nano core shader + translucent params.
src/main/java/mc/duzo/timeless/client/render/IronManFlightTilt.java Computes/apply pitch+roll transforms based on flight/boost/dive/roll state.
src/main/java/mc/duzo/timeless/client/render/IronManFlightState.java Adds client-smoothed timers for flight/boost/dive state.
src/main/java/mc/duzo/timeless/client/render/entity/RepulsorBlastRenderer.java Renders repulsor blast line effect.
src/main/java/mc/duzo/timeless/client/render/entity/MissileRenderer.java Renders missile as oriented line strip placeholder.
src/main/java/mc/duzo/timeless/client/keybind/TimelessKeybinds.java Adds power keybinds 5–9 and per-tick click handlers.
src/main/java/mc/duzo/timeless/client/keybind/PowerRightClickHandler.java Sends UsePower packet when a power claims right-click.
src/main/java/mc/duzo/timeless/client/keybind/PowerLeftClickHandler.java Sends UsePower packet when a power claims left-click.
src/main/java/mc/duzo/timeless/client/gui/JarvisGui.java Adds new HUD panels: energy bar, integrity, flight mode, targeting reticle, threat list.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


@Override
public boolean shouldRender(MissileEntity entity, Frustum frustum, double camX, double camY, double camZ) {
return true;
Comment on lines +59 to +63
matrices.pop();
super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light);
// Use MathHelper to silence the unused-import warning if any.
if (false) MathHelper.sin(0);
}
Comment on lines +29 to +32
@Override
public boolean shouldRender(RepulsorBlastEntity entity, Frustum frustum, double camX, double camY, double camZ) {
return true;
}
Comment on lines +32 to +36
// Dive: triggered when client sends a flight-toggle while sprinting at speed.
// For the MVP, derive it server-side: if was-flying, now-not-flying, sprinting, fast → dive.
if (isDiving(player)) {
int diveTicks = SuitItem.Data.contains(player, K_DIVE_TICKS) ? SuitItem.Data.getInt(player, K_DIVE_TICKS) : 0;
diveTicks++;
Comment on lines +16 to +20
@ModifyVariable(method = "damage", at = @At("HEAD"), argsOnly = true)
private float timeless$shieldScaleIncoming(float amount, DamageSource source) {
LivingEntity self = (LivingEntity) (Object) this;
if (!(self instanceof PlayerEntity player)) return amount;
if (!ShieldPower.isActive(player)) return amount;

import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;

import net.minecraft.client.network.ClientPlayerEntity;
Comment on lines +55 to +58
float progress = mc.duzo.timeless.power.impl.NanoAssemblePower.progress(livingEntity);
mc.duzo.timeless.client.render.NanoShaderHolder.setUniforms(progress, 1.0f, nano.getNanoMaxRadius(), nano.getNanoEdgeColor());
consumer = vertexConsumerProvider.getBuffer(mc.duzo.timeless.client.render.NanoAssembleRenderLayer.of(model.texture()));
} else {
Comment on lines +114 to +117
public void applyPose(LivingEntity entity, SuitModel model) {
if (!(entity instanceof PlayerEntity player)) return;
Integer poseLeft = POSE_REMAINING.get(player.getUuid());
if (poseLeft == null || poseLeft <= 0) return;
Comment on lines +64 to +67
EntityHitResult hit = ProjectileUtil.raycast(shooter, origin, end,
new Box(origin, end).expand(1.0),
e -> e instanceof LivingEntity && e != shooter && !e.isSpectator(),
RANGE * RANGE);
Comment on lines +88 to +90

if (shooter instanceof PlayerEntity p) POSE_REMAINING.put(p.getUuid(), POSE_TICKS);
}
@duzos duzos closed this May 5, 2026
@duzos duzos deleted the feat/ironman branch May 5, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A: Datagen Area: Datagen implementation & API. C: Audio Changes: Might require knowledge of audio. C: Textures Changes: Might require knowledge of spriting or visual design. enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants