#General & Development Help
1 messages · Page 11 of 1
carpet mod did a better job
also this is very dubious so i wont bother with it at all
is this a vanilla thing?
a 1.21 thing iirc
Nearly all video games (including Minecraft) are driven by one big program loop. Just as every gear in a clock is synchronized with the pendulum, every task involved in advancing a game simulation is synchronized with the game loop. Appropriately, one cycle of the game loop is called a tick.
yeah, basically the tick freeze from Carpet is just in vanilla now
you can freeze the game and step through a tick at a time, or have it go at the speed you want
its super useful for testing farms or timing contraptions
but carpetmod did it better
why do you have to check from the pre event also? is just isFrozen not enough?
nope, because theres a /tick step [n]
and that increases a counter
but decreases soon after ServerTickEvent.Post
and before ServerTickEvent.Post
so if it's set to 1, we never observe it in ServerTickEvent.Post
the flow goes like
/tick step -> Sets counter to 1 -(next tick)-> ServerTickEvent.Pre -> Decrements counter to 0 -> Everything else in the tick -> ServerTickEvent.Post
so by the time we get to post, we can only observe the counter being 0
to be precise the counter is called frozenTicksToRun and isSteppingForward() just checks if its > 0
on a semi-related note it also seems like DelayedSpellEvent delays for one tick shorter than duration
easy enough to work around at least
oh yeah this makes sense
the DelayedSpellEvent is created during the tick, then the event is fired in ServerTickEvent.Post
so in the same tick its created, its also decremented by one
not sure if its worth fixing
if it is, + 1 is a very easy fix
just hope no one wants a 2147483647 tick delay
on second thought that explanation seems a bit strange
youd still be waiting at least a tick with a duration of 1 in that case
but im observing no delay at all
ah, probably
public void tick(boolean serverSide) {
- duration--;
- if (duration <= 0 && serverSide) {
+ if (duration-- <= 0 && serverSide) {
i wonder if theres a nice way to check if the mod is running in a dev env
for doing cursed dev only mixins
dev only because actual dependency version might fix those stuff themselves
nvm it seems like something else
delays work fine
my own delays dont
i have a few guesses
my delays are only 1 tick long
public void sendPacket(Level world, HitResult rayTraceResult, @Nullable LivingEntity shooter, SpellContext spellContext, SpellStats spellStats, BlockHitResult blockResult, Entity hitEntity, SpellResolver spellResolver) {
if (spellContext.getCurrentIndex() >= spellContext.getSpell().size()) {
return;
}
int duration = 1 << spellStats.getBuffCount(AugmentExtendTime.INSTANCE);
var existing = spellContext.getDelayedSpellEvent();
var delayEvent = new DelayedSpellEvent(existing == null ? duration : duration + 1 + existing.duration, rayTraceResult, world, spellResolver);
spellContext.delay(delayEvent);
EventQueue.getServerInstance().addEvent(delayEvent);
Networking.sendToNearbyClient(world, BlockPos.containing(safelyGetHitPos(rayTraceResult)),
new PacketClientDelayEffect(duration, shooter, spellContext.getSpell(), spellContext, blockResult, hitEntity));
}
this works for some reason
the + 1 is important there
im extremely confused now
hm even that isnt perfect it seems
the lightning triggers on the same tick as the break
that delay looking glyph is a 1 tick delay
oh wait no it works fine
no it doesnt
im so confused
and now its working fine without any changes again
please dont tell me its random
maybe i was just mistaken about it not working?
but either way very strange workaround
yeah seems to work
this bug does seem to affect delay too
i say second but all delays after the first last 1 tick less
can be simplified to ```java
var delayEvent = new DelayedSpellEvent(spellContext.getDelayedSpellEvent() == null ? duration : duration + 1, rayTraceResult, world, spellResolver);
i dont know whats causing it
but i do know this fixes its effects
to clarify: for delay itd be 20 -> 19 -> 19 -> 19
not 20 -> 19 -> 18...
and for my smaller delays itd be 1 -> 0 -> 0
my initial wrong assumption was that the spell had a 1 tick delay from the cast to the first effect, which would have meant that everything was 1 tick off
but only the DelayedSpellEvents after the very first one are 1 tick off
a pretty bad bandaid would be
public void delay(DelayedSpellEvent spellEvent){
+ if (this.delayedSpellEvent != null) {
+ spellEvent.duration++;
+ }
this.delayedSpellEvent = spellEvent;
}
im gonna wait on this bug to be figured out before publishing my new glyph in controle
i still havent figured out why it happens
seems very strange to me
Anyone know a good resource on creating multiblocks?
@ me when you get
i figured out the issue
tick phases
at least i think
the first delay of the spell creates an event, but that event isnt ticked until the next tick
future delays create events that get ticked at the same time
now im not sure why the first one is special







castSpell: worldIn.getGameTime() = 7112

instant (7112)

EffectDelay::sendPacket: world.getGameTime() = 7112
1st DelayedSpellEvent::tick (duration from 20 to 19): world.getGameTime() = 7113
last DelayedSpellEvent::tick (duration from 1 to 0): world.getGameTime() = 7132
7132 - 7112 = 20 (good)

instant (7132)

EffectDelay::sendPacket: world.getGameTime() = 7132
1st DelayedSpellEvent::tick (duration from 20 to 19): world.getGameTime() = 7132 notice that no ticks have passed since sendPacket, unlike the first delay
last DelayedSpellEvent::tick (duration from 1 to 0): world.getGameTime() = 7151
7151 - 7132 = 19 (bad)

instant (7151)
all timings gotten from debugger
the second
is called in the same tick as the last tick of the first
because SpellResolver::resume calls onResolve until theres no more effects...
does this mean the EventQueue is getting a new event
then iterating it
in the same tick?
would make sense tbh
yep i fixed it
pushed to the same branch because its all EventQueue stuff
also simplified the previous commit
isSprinting was not necessary
but it looks like sprinting is broken when frozen in vanilla
sprints for longer than you ask it to
1 tick longer than asked, i think
fairly certain changing to iterator is going to crash concurrently
events can add other events
yeah that was also the problem with the new thing
but fastutils seems to handle it correctly
ArrayList$Itr seems to be broken in some way
I wouldnt really gamble on that, why are you changing it anyway?
granted i havent done excessive testing but ive messed around with enough delays in my spell and can confirm i didnt crash yet
fair enough
it is a fairly inconsistent crash, and the list size is really really tiny anyway so I wouldnt risk it
i was able to cause it very consistently just by firing multiple spells with 2 sleeps in the same tick
but this is fine
reverted to a stale list based implementation
switched it to using ObjectArrayList though
but ye ListIterator + remove is meant to prevent CME
not sure why ArrayList's doesnt though
hm its actually probably the addition that causes the CME with ArrayList
am I doing this right, let's say to give diamond helmet a perk provider?
@Override
public IPerkHolder<ItemStack> getPerkHolder(ItemStack itemStack) {
return null;
}});```
I know it's null, but am I in the right direction?
For 1.20 it's more like:
PerkRegistry.registerPerkProvider(ItemsRegistry.SORCERER_LEGGINGS, stack -> new ArmorPerkHolder(stack, Arrays.asList(
Arrays.asList(PerkSlot.TWO),
Arrays.asList(PerkSlot.TWO, PerkSlot.THREE),
Arrays.asList(PerkSlot.TWO, PerkSlot.TWO, PerkSlot.THREE)
)));
For 1.21 slightly different
thanks! here's what I had
String[] sets = { "wandering_magician", "pumpkin", "netherite_mage" };
String[] armorPieces = { "helmet", "chestplate", "leggings", "boots" };
for (var set : sets)
{
for (var piece : armorPieces)
{
String itemId = String.format("%s_%s", set, piece);
Item item = ForgeRegistries.ITEMS.getValue(new ResourceLocation(modname, itemId));
if (item == null) continue;
PerkRegistry.registerPerkProvider(item, stack -> new ArmorPerkHolder(stack, List.of(
empty(),
empty(),
empty(),
MAGIC_ARMOR_PERKS_T4,
MAGIC_ARMOR_PERKS_T5,
MAGIC_ARMOR_PERKS_T6)));
}
}```
I still need to adjust it though
Likely to work this way, yeah.
Unsure if the tooltip will show on its own
Maybe a way to test is try to put the item into the alteration table?
The problems with testing something only on higher tiers is that the items you will pick from creative are tier 1
oh yeah I was looking on how this works
I looked into the recipe and it the armor was not there, is iit like a tag?
For how it's made, it should match on all items with the perk holder attached
It checks on if there's the holder and its tier
No specific item
oh that's convenient. now it just depends on my code xd
I managed to get armors into the alteration table but as you said alexbuncle the tooltip does not show
I tried ItemStack capabilities, but I don't seem to get it to work. idk really if that's what I need to do though
I found out there's an ItemTooltipEvent and could prob append the thread tooltip but I was wondering if that'd be efficient
Probably your best bet unfortunately
I see thanks
hello, I found an issue. I made a threaded armor with only two tiers in code, but I was able to upgrade it to tier 3 via enchanting apparatus
then whenever getSlotsForTier() is called on that armor, it throws an exception. because you know it tries to grab tier 3 from a list of 2 tiers.
well, this only happened bc I'm making extra threaded armor sets
I don't think you can have just two tiers, unless you have them exist outside of the 1-3. I'd give tier 1 no threads and then add threads on the other tiers, so that when people do whatever it is to add threads to the armor, it puts them at tier 2
well my idea was to make this armor to have only two tiers (early game armor). but I was able to upgrade it into tier 3
despite it not being registered as having three tiers. is it related to the upgrading part?
Yeah upgrading doesn't check what the max tier it can be
You would have to give it a tier 3 slot identical to tier 2
So at least they don't lose slots or crash
Does anyone happen to have an example of a renderer that works for both armor slots and curios? I found one in Create but they are using some AbstractRegistrate and some weird model swapper. Couldn't get that to work.
I think Elemental might
Almost... 🫠
Why not just have separate renderers?
ICurio render only asks that you implement a render method
you probably can simply make a dummy class that calls the real renderer in that render method
Or even just render the model from create similar to how I do and adjust it
I don't have a 'real' renderer so far, still trying to make heads and tails out of these layer definition events and baking layers... I have the custom renderer but I don't even know how to load my model in there, it's tricky to find the right examples or docs
I managed to get armor from other mods to work with the alteration table and apply perks to it. now I need to make the perks functional but I don't know where to start xd I looked at the equipmentChangedEvent but it does not seem to apply it there. asking for help, where should I look?
ItemAttributeModifierEvent
declaration: package: net.minecraftforge.event, class: ItemAttributeModifierEvent
as uuids you can copy the map inside AnimatedMagicArmor
threads like chilling & kindling should work out of the box
oh I see that's helpful!
I was initially doing capabilities and I did not know what I was doing 😂
would be something like AnimatedMagicArmor's
if (this.type.getSlot() == pEquipmentSlot) {
UUID uuid = ARMOR_MODIFIER_UUID_PER_TYPE.get(type);
IPerkHolder<ItemStack> perkHolder = PerkUtil.getPerkHolder(stack);
if (perkHolder != null) {
attributes.put(PerkAttributes.MAX_MANA.get(), new AttributeModifier(uuid, "max_mana_armor", 30 * (perkHolder.getTier() + 1), AttributeModifier.Operation.ADDITION));
attributes.put(PerkAttributes.MANA_REGEN_BONUS.get(), new AttributeModifier(uuid, "mana_regen_armor", perkHolder.getTier() + 1, AttributeModifier.Operation.ADDITION));
for (PerkInstance perkInstance : perkHolder.getPerkInstances()) {
IPerk perk = perkInstance.getPerk();
attributes.putAll(perk.getModifiers(this.type.getSlot(), stack, perkInstance.getSlot().value));
}
}
}
But by using the event's methods
no, they're not saved as enchants
and there is no override changing the isEnchanted check
a grindstone for example wouldn't delete threads etc.
I see
I kind of did it. idk if this is efficient though I'm new to forge modding
starbuncle works 😮
yeah, seems fine
you should see the attributes applied on the tooltip
it's a vanilla thing
they should use the PerkUtil checks
which check the item's nbt field for the perkholder
so you should be fine
try for example kindling
what does it do?
or the totem one, or the elytra one
I actually have little idea about ars nouveau 💀 I'm just coding for a modpack of mine
kindling is the one that sets the target on fire right before a damage glyph resolve
the (slot tier 3 only) totem and glide threads act as if you have a totem of undying every day (recharge by sleep) or the elytra always equipped
turns out making the client send rotation to the server on every cast is pretty complicated
i was gonna tackle it today but i dont feel like dealing with refactoring all the usages of castSpell
also i feel like the discrepancy shouldnt exist in the first place, we arent doing anything weird afaict
its called on use
Won't trigger for spell turrets (and bookwyrms, but that's legacy anyways)
yeah but we only need to sync rotations for player casts
the worst part is probably just dealing with codecs
I made a custom attribute but unsure on how to attach it to the player so they have it by default. I tried mixin but it does not seem to work. how would I approach this?
Isn’t there an event for that?
you can also snatch it into Ars ones with the method
so you don't have to deal with making a registry and attach it
is it the EntityAttributeModificationEvent?
I tried but I failed to find it xd where is it?
I register a new block like this, and then I make sure to call BlockRegistry.register(modEventBus); before I get to EntityRegistry.register(modEventBus);, so it shouldn't be a timing issue...
But here, this fails:
public static final RegistryObject<BlockEntityType<SourceEngineBlockEntity>> SOURCE_ENGINE_BLOCK_ENTITY = registerBlockEntity(
"source_engine_block_entity",
BlockEntityType.Builder.of(SourceEngineBlockEntity::new, BlockRegistry.SOURCE_ENGINE.get()
));
BlockRegistry.SOURCE_ENGINE.get() says 'Registry Object not present: ars_technica:source_engine'
It does seem like the registry object is null, but I don't understand what I'm doing wrong, any ideas? 😥
wild guess would be suppliers
() -> BlockEntityType.Builder
what changes you'd ask?
with old code, you construct the BlockEntityType builder asap the BlockRegistry class is loaded into memory
causing BlockRegistry.SOURCE_ENGINE.get() to be still empty as the registries have yet to be filled
with the supplier, you defer that creation to when the BlockEntity registry need to be filled
Yes, that was it. Thanks Alex! I wasn't so familiar with suppliers but if I understand correctly they are (or can be) anonymous functions that allow you to lazy-load objects when needed. Here's the fixed version for good measure.
public static final RegistryObject<BlockEntityType<SourceEngineBlockEntity>> SOURCE_ENGINE_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register(
"source_engine_block_entity",
() -> BlockEntityType.Builder.of(SourceEngineBlockEntity::new, BlockRegistry.SOURCE_ENGINE.get()).build(null)
);
On a different note, I've been looking at 'Registrate' that Create uses to automate and centralize a lot of the registration pieces. It looks really nifty but I've been wary of picking it up because I'm not sure that works for NeoForge... anyone happen to know?
It looks like NeoForge is mostly the same as Forge currently - I want to minimize the effort of switching over when moving to 1.21
id just wait for 1.21
quite a few internal changes
personally im not a huge fan of abstracting over menial stuff
makes it harder to fix when the internals do
Gotcha, thanks. I'm on the fence on that, I don't really like how you have to register things in separate places (e.g. registering a block in place, its block entity elsewhere, the item representation a third place and the renderer in a fourth), I think it's quite nice if you can put everything in one place. But I can imagine you will run into problems with that at some point as well.
i kinda just have them in the same file
this is 1.21 though
I have blocks and block entities registered in the same file
Most blocks don't have a bespoke item representation, so I also register block items in the block registry file too
Renderer would be the only thing I have separate
ive yet to deal with renderers but im inclined to agree on separating that
also if anyone is curious, i absolutely do not make minecraft mods through neovim
jdtls is too crap
i use it for everything except java and kotlin
I was more interested in your color scheme
kanagawa
Forgot to mention after our brief disc on api channel, Elemental has a maven now. I just need to upload the older (1.20 at least) versions too
Then I'll make the announcement, I am not 100% sure if it's gonna help people who work with elemental in-dev but should allow to get the latest for testing purpose. For example with how the latest 1.21 on ars maven would crash with elemental curse latest but work with maven latest
It would make me happier fwiw and also help others, it took a bit of time for me to understand how to use cursemaven, and haven't used it for anything else yet.
You can copy the usage for Elemental from All-The-Arcanist-Gear
https://github.com/baileyholl/Ars-Nouveau/issues/1428 seems like an incompatibility with dimthread?
crash-2024-10-02_08.54.15-server.txt
https://github.com/2No2Name/worldthreader is the best but not 1.21 and not forge
Fabric mod that assigns each dimension their own thread. Based on https://github.com/wearblackallday/dimensionalthreading - 2No2Name/worldthreader
I'm very amazed at the level of modularity (or hacking around) that's possible with Minecraft.
As long as it's just vanilla you can be very hacky
When you start to have to account other people being hacky too, you may understand there's a limit to it in practice
I am looking for something to work on for modtober, and so I decided to check on projects that I am somewhat associated to.
does ars have any pending tasks that people have been putting off due to reasons (work or other important tasks)
Uhh, I have two WIP PRs that are unfinished if that fits the criteria
- Rework linger to propagate only on effected blocks, needs to have gravity compat added
- Make turrets and tiles use owner UUID, needs to replace ANFakePlayer usages with the new FakePlayer stuff where possible, and then tested
Other than that you could take a look through #1096849320608805123 or #1019639765093589153 for anything that seems interesting to you
oh those are interesting! I will check once if those qualify (because of PR date and main author). I will try to work on them regardless :)
PRs made before signing up qualify, but I'm happy to close mine if you wish to take over, so you're the main author
I am glad that you would do that but that doesnt feel fair
They're in a draft/abandoned state at the moment, I don't have time to push them any further
I will try and finish them
i feel like there's also more complex stuff, that might be not marked as will add in feature request
but usually it's due to needing input from the chiefs
Branch from here: https://github.com/Jarva/Ars-Nouveau
Jarva:feat/turret_rune_uuid
Jarva:feat/linger_rework
Closed both PRs now
you shouldn't have but thank you
I'd rather someone have motivation to work on them than a silly little name next to the commit message
wouldn't it work for them to PR to your PR ?
If you want to port Ars Fauna to 1.21 I wouldn’t object.😜
Life is hitting like a ton of bricks right now.
that was the plan yeah
Probably not because my repo isn't tracked in the modtober event
ah, that's fair then
Gotta submit Ars Fauna to the modtober event then 😄
is that still mcreator?
Yeah.
It’s MCreator with some custom code, but still based in MCreator.
I’ve moved over to IntelliJ for editing going forward.
I don’t even know what that is.😂
turns out i don't have to by using the most scuffed method on earth
life is good again
:3
do you prefer making an access transformer?
i replaced the player's curios by a clone of it but with the component i needed
quite scuffy but it works so it's fine
how so
Cross Platform, cleaner, less gradle bullshit, works on other mods/libraries and not just Mojank code
i agree for the most part but i hate the casting
maybe if java had better syntax id hate it less
i still use it over at though
hello there, i am facing quite a painful issue.
i've been trying to access the "Rarity" class, and it is located in the library when i go there by control clicking the path, however my env isn't "seeing" that the class is right there... what's even more infuriating is that dependencies that use this class indeed work just fine when i load the ClientRun task.
would any kind soul know the source of this predicament?
How are you including the lib in gradle?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
here it is
and which dependency is it?
iron's spells and spellbooks is loading the Rarity clas just fine
however i can't access it
as though it wasn't on my computer even though it's right there
same for the MobEffectCategory
it is here but my env is not acknowledging it's presence
i'll try to ask around in the neoforge server
since this is quite the painful situation
Oof, at least it was an easy fix
@zealous zenith how familiar are you with the workings of SPL? I'm trying to backport the new ForgeCraft 1.21 change to 1.20.1 SPL and it's not going well 😭
Any gradle experts? Or people brave enough to try?
I have fucked this build.gradle severely
i dont believe in god but may they save your soul
Modified version of: https://github.com/forgecraft/ServerPackLocator
The worst thing in my life rn is that ModDevGradle hasn't merged the legacy compat PR for working on older forge versions
jitpack the PR 
that wouldn't help me because I don't know how to include a jitpack gradle plugin
Nah they've refactored so much
backport is just updating one file
and the whole gradle system
😦
Wait, would my PRs to Bailey count?
Well, it marks them invalid because:
"Pull requests for your own projects or projects you maintain will not count towards your progress in the challenge"
Idk why
Maybe it's because I have too much edits on Ars
Ah maybe they simply signed me up as part of the team
Unsure if it's worth asking them
Perhaps
If you're owner, collaborator or member you can't gain benefit from it, but that was only added two days ago, so I could have snuck in, unsure if I count for any of them
maybe i could PR IWandable BlockPos -> GlobalPos but id have no idea what to do for the other 3 lol
also still not a fan of how it would break every single addon
maybe i should just take a look at the mods on the list and go eliminate some bad code
could make it a new method so that is it doesnt break exisiting users
would lead to unexpected behaviour though
connecting stuff in the same dimension while youre in another dimension for example
If globalpos is an extension of normal pos, make a default method take the global pos and call the old onr
Then replace the old Iwandable usages with globalpos?
yeah but level info would be lost
If you want everything IWandable to use globalpos it's a large scale edit
If you simply need that your IWandable receive a global pos, it will with that trick
this
You can't construct the global pos without the level though
Could grab the level from the player entity or target entity
yes but it might not be the intent
so better not to
and also would still require the receivers to handle it properly
at which point we should just switch to GlobalPos
For most, it won't matter, create default implementations that receive a global pos and have them call the normal pos methods
i think the default should probably be a noop if GlobalPos and Player level are different
If you only need to edit the wand it's pretty easy, but they want to change all receivers?
And then migrate the usages to use the global pos
Migrate only the usages, and create fallbacks for the receivers
i think this should at least maintain compat?
then anyone wanting to use the globalpos can just overwrite that instead
The flow should be:
Call to globalpos method -> default to call Blockpos method if dimension matches, to override for custom behavior
yep
I think you could mark Blockpos one as deprecated, but idk seems fine to keep as it is
yeah i think its fine too
I'd deprecate personally
theres more than a few blocks that dont need cross dimensionality
and entities
like starbies
They can handle that
fair
i will be doing the minimum amount of migration though
this is mainly just for controle's prism and remote lol
Yeah, they should handle it in their code, just deprecate for now
heyoooo
anyone here knows how i change how many domain glyphs i can use per spell
it is from adam's ars plus
Maybe ask in the relevant addon channel like I mentioned?
https://discord.com/channels/743298050222587978/1235001538611511357
Follow instructions? Since when has the general public done that?😜
anyone know what might be causing GeckoLib to flip out in my dev environment while i'm trying to port ArsÉng to 1.21? keep in mind i'm having to work with MC 1.21.1 since that's what the current builds of AE2 are built on top of, while Ars is still on 1.21.0
Ars is 1.21.1
Checklist for latest ars on devenv is:
- Modgradle or up neogradle to latest, so it uses Gradle 8.9
- latest geckolib
- neo forge .66+
As apparently some stuff added in recent neo is pretty useful to solve current issues in geckolib and other mods
And newer forge asks for newer gradle
yeah that was all sorted, turns out it was a GeckoLib issue only present on NF versions older than .62
Shaders:
Little shaders type example : https://gist.github.com/gigaherz/b8756ff463541f07a644ef8f14cb10f5
Vanilla Shaders Guide : https://docs.google.com/document/d/15TOAOVLgSNEoHGzpNlkez5cryH3hFF3awXL5Py81EMk/
Shadertoy : https://www.shadertoy.com/
A pretty old guide about mc shaders i forgot to link up at the channel start
Custom shader rendertype mini-howto example (forge 37.0.15+) - 00 Explanation.md
Guide to vanilla shaders Last updated 2021-03-10 for Minecraft 21w10a (WIP) Intro Vanilla Minecraft has a number of GLSL shaders that can be modified using a resource pack, allowing them to be included in a world or automatically applied when you join a server. Shaders are written in OpenGL Shad...
it's probably not 1:1 usable for modern mc, but the overall pipeline should be the same
So someone tried to help with Ars Fauna for modtoberfest by adding a config option for Thornsprig spawning.
Can someone look at the code in ThornsprigSpawnProcedure.javaand tell me why I’m getting an error on line 36? And ArsFaunaMod.java on line 57?
What is the error in ide?
Will have to get back to you on that. On my way to church now.
Was hoping it was something that someone with know how could look in the repository and go “oh, that guy has a typo right there”.
likely a missing import
hover over GameRuleFactory and it should prompt you for import
there was an import in the same page, tho
i wonder how the hell did they made the pr to not notice an error tho
try something like level in place of getWorld?
smells like ai generated code
Any idea how to make it work?
+1
Reverted the GitHub repository back and reopened the issue.
does the MobEffect class have anything akin to a "onTick" method ?
applyEffectTick
note that it only gets called when isEffectTick is true
and when shouldApplyEffectTickThisTick returns true
what the hell mojang
That's a great variable name
I doubt anyone will need it, but if anyone needs a script to convert rune and turret NBT from 1.20.1 to 1.21 let me know 
i can feel the pain from here….u ok ?
import * as NBT from "nbtify";
const file = await Deno.readFile("./arcane_library.nbt");
interface Structure {
blocks: NBT.ListTag<NBT.CompoundTag>;
palette: NBT.ListTag<NBT.CompoundTag>;
}
interface Block {
pos: [number, number, number];
state: number;
nbt?: RuneNBT | TurretNBT;
}
interface TurretNBT {
"ars_nouveau:turret_caster"?: Caster;
spell_caster?: Caster
}
interface Caster {
flavor: string;
hidden_recipe: string;
is_hidden: boolean;
current_slot: number;
spell_count: number;
spells: {
[key: string]: Spell
}
}
interface RuneNBT {
spell: Spell;
}
interface Spell {
sound: Sound;
name: string;
recipe: any;
spellColor?: Omit<Color, 'id'>;
color?: Omit<Color, 'type'>;
}
interface Sound {
volume: number;
soundTag?: SoundTag;
sound?: SoundTag;
pitch: number;
}
interface SoundTag {
id: string;
}
interface Color {
r: number;
b: number;
g: number;
type: string;
id: string;
}
const nbt = await NBT.read<Structure>(file);
const state = nbt.data.palette.reduce((acc, curr, index) => {
acc[index] = curr.Name;
return acc;
}, {});
const convertSpell = (spell: Spell) => {
spell.color = {
r: spell.spellColor?.r || 0,
g: spell.spellColor?.g || 0,
b: spell.spellColor?.b || 0 ,
id: spell.spellColor?.type || "",
}
delete spell.spellColor;
spell.sound.sound = spell.sound.soundTag;
delete spell.sound.soundTag;
const keys = Object.keys(spell.recipe).filter(key => key != "size");
keys.sort();
const recipe = [];
for (const key of keys) {
if (key in spell.recipe) {
const value = spell.recipe[key];
recipe.push(value);
}
}
spell.recipe = recipe;
return spell;
}
for (const item of nbt.data.blocks) {
const block = item as object as Block;
const id = state[block.state];
if (id === "ars_nouveau:rune") {
if (block.nbt == undefined || !("spell" in block.nbt)) continue;
convertSpell(block.nbt.spell);
}
if (id == "ars_nouveau:basic_spell_turret") {
if (block.nbt == undefined || ("spell" in block.nbt)) continue;
if (block.nbt["ars_nouveau:turret_caster"] != undefined) {
block.nbt.spell_caster = block.nbt["ars_nouveau:turret_caster"];
delete block.nbt["ars_nouveau:turret_caster"]
for (const [key, spell] of Object.entries(block.nbt.spell_caster.spells)) {
const transformedKey = key.replace("spell", "");
block.nbt.spell_caster.spells[transformedKey] = convertSpell(spell);
delete block.nbt.spell_caster.spells[key];
}
}
console.log("BLOCK", block.nbt)
}
}
const data = await NBT.write(nbt);
Deno.writeFile("./output.nbt", data);
read this and ask me again
Typescript, but it's easier to script in than writing it in Java
true
i was thinking of python
though i dont really like python it is a good scripting took
i wouldve just put it in ars nouveau as an init function so you have all the nbt machinery
Have to say it's funny to read " fixed a crash when mod was in another language"
Lowercase I in Turkish apparently is not i
It's í or something, which doesn't fit the A-z required for resource locations
they have 2 i in Turkish I ı and İ i
Pretty sure 1.21.1 will remain lts
hello there, how should i go about creating a key (client side) that sends data to the server (boolean or a nbt data)?
What's it going to do?
tell the server that the client wants to do an action (IE cast a spell, teleport forward, or do a thing™️)
overall all i need to know is that the client wants to do it, and then the server can handle all the rest by itself
sounds a lot like how a packet works
ill look into how they work in neo
thanks a lot :3c ill look into it tomorrow
expels a gold ingot from the south end 1.21?
btw do you gents know how i can add an attribute with "just" the Player player entity?
weird question, does anyone know if theres a name for NOT XNOR
in other words, !=
i could say not equal but that feels weird
of difference
im making combinatiorial filters
i guess its just XOR huh
is there a proper way to add spell validators or is mixins fine
ill roll with it for now
got OR, XOR, and XOR filters working
they were not working as well as i thought they were
there are no hooks for them it looks like
might scrap these, wrangling SpellContexts is not fun
been working on the same bug for like 2 hours now
despite using setCurrentIndex, im getting execution like 1, 2, 3, 4, 3
part of the problem is certainly because AbstractFilter doesnt get SpellContext so ive been getting it through onResolveBlock/Entity setting an object field
but i dont think its working too well
theres probably something i could do by storing the resolver instead but ill leave that to tomorrow me
i think the main cause of my troubles is chaining binary filters
so ill just make it impossible through a validator
yep that works
Folks, I'm struggling and I don't know why
FilterableItemHandler handler = data.getItemHandler(player.level());
if (handler == null) return true;
InventoryManager manager = new InventoryManager(List.of(handler));
ItemStack remainder = manager.insertStack(other);
update.accept(remainder);
return true;
I have this in the HandyHaversack, after all the code, I can see the capability is updated, but when I check the chest in-game it's not updated
Any ideas would be greatly appreciated
Needed to clone other 😦
were you setting it to empty afterwards?
you probably dont need to clone if it you dont set it to empty
Yeah I don't always set it to empty, but it's safer to just clone
today's finally the day, time to get started porting to 1.21.
Just gotta get some shopping done, otherwise I gotta starve tonight..
Anyone got a decent guide or a commit that I can leech off of?
I'm trying to make mixins work for Ars Technica, seems they were never actually shipped with the .jar.
I'm running into an issue, it's not able to find mappings for any methods/fields e.g. "Unable to locate obfuscation mapping for @Inject target tick"
Did anyone run into this issue before? I tried looking very closely at how Ars Elemental is doing it in build.gradle and the mixins.json file, but I must be missing something crucial 🤔
Are you using Intellij and if so, are you using the MC plugin? Iirc correctly it helps with mixins in that it gives you the correct annotation parameters to overwrite the thing your mixin wants to interact with.
Other than that, it's been far to long for me to remember, I'm sorry
Yes, I'm using IntelliJ IDEA. I don't have the MC plugin I believe, let me check that. Thank you!
jesus christ, it's really been ages since I opened up IntelliJ on my private machine
don't even have github copilot installed yet
Ahhh I think I was looking too closely at build.gradle and mixins.json... it was simpler than that
I forgot to add 'remap = false' to those annotations
But hey now I have that plugin for making my next mod, thanks 😉
if you are mixing into a mod, remember to do @Mixin(value = BlahBlah.class, remap = false)
oh oops you solved it
Cheers still, that is exactly the answer!
Best bet is the primers:
- snatch the build.gradle and don't forget the new gradle.properties file
- double check you don't miss/have extra deps on the Gradle you snatched
- start using the mass rename (or use the name porting script) to fix the old forge package names to neoforge
- Deferred registers replaced by Deferred holder, takes < T, ? extend T> as type Paramus
- item nbt data is stored in form of components, Ars has a few custom ones and you will need at least one for the armarium
Additions might have more similarities with Instrumentum so you might wanna check that git first
Gonna copy that message link for later, you could even pin that
Check the earlier pins too
Chonk sent the link to all the primers and before that I sent the renaming script to automate part of the forge -> neo
This were the first thing you would notice, ofc it's not exaustive
But the others might be a little more obvious than the "what hell goes here now"
Hows it going?
not great. Friends told me that I'm missing out on the monster hunter wilds open beta and that distracted me enough to admit that I'm not motivated enough to keep diving into something that doesn't feel fun right now 😦
On the plus side, Wilds looks absolutely amazing
Understandable, I ported half of Ars Additions and got burnt out, I had a friend of mine finish porting it
I do have a bored junior dev at work now that you mention it. And they did want to get into minecraft modding 🤔
😂
I need a friend like that.😂
if only it ran well... my poor PC was struggling something fierce
for once, overkill pays off 😁
I was surprised how much I liked the way the characters looked. Usually, I am sceptical about "realistic" humans since I'm quite susceptible to uncanny valley, but Wilds has been one of the few games where I'm just overall very happy with the way things look
certainly looks great, but I'm hoping I don't need to do an expensive upgrade to play it at all
I was messing around with the Switch axe in the area before they threw me into multiplayer and my frames died
now have 2 counter attacks, you have Offset Slash in axe mode where you can hit an attack with an attack to tank it, and a parry stance thing in sword mode that does a big attack if you do it right
yeah, it being on PC means there's going to be wild differences in how it runs. Unfortunately I'm not in the "works fine on my machine" crowd this time
the origami lightning monster is hilarious
lol yeah I've seen those
i did really like the new movesets anyway, i felt world too heavy by coming from rise
and wilds seems to strike a good balance
but i am also a glaive user
so i'm worried about lack of aerial gameplay
Hunting Horn is closer to World, which means I'm gonna stop using it lol. I loved how it worked in Rise
but now the combos feel unfamiliar
there are some improvements over world tho
I'm sure, but it'll take getting used to if I want to keep using it
my muscle memory is in Rise
you can add notes for the combo while setting up the aoe zone
so it immediately was feeling bad to use, which I'm sure is the experience all the horn users had coming to Rise
and few horns have a parry apparently
definitely excited for the bow changes. Can't wait to shoot off homing dragon piercers
I was doing a lot of Longsword and Glaive at the end of Rise
what are you porting? :)
Ars Instrumentum
was trying to make improved spellbook controls through mixins but minecraft gui code is wacky
will probably need to do it in the base mod or something
Is there a max number of ingredients for an enchantment table recipe?
you mean apparatus? i dont think theres a max but jei integration might fail after 8
Yes, I meant apparatus. I’m wanting to require 10-12 items for the tier 7 armor.
one scuffed workaround would be to make dummy items that cost some of those 10-12 items to make to bring the final recipe to 8 or lower
Hmmm didn’t think of that. That would actually work pretty well for what I’m doing. Just need to make sprites for “fused essences”.
Then I have to figure out how the elemental armors, bangles, and foci assign their perks so I can figure out how to assign multiple sets of them at the same time.
But right now my brain hurts from dissecting Elemental and rewriting its code for Elemancy.
Try it, but I think 12 should work
Wouldn't it be better to make a separate GUI class and hijack the call to open the GUI?
then id have to keep ot updated
got it working anyway
just lost a few features
wanted to make a way to shift part of a spell around using right click or something
theres a chance that i could do it with arrow keys
That part can be a PR
The custom ordering stuff is complex enough to require custom GUI elements so at max you could add hooks
The internal sorting system is index based in theory
I am not sure but I could have managed to detach it from the instance ofs ordering, but they are surely still used for the three categories
It's how the new filters go at the bottom of the book and the propagators on the top
oh yeah no im not doing sorting
Alex, I’m going through the code for Elemental (1.21 version) and think I have a vague idea as to how it assigns perks based on which element you are wearing. Which file(s) would I need to modify the code in to have a new “element” (say tempest, for example) assign two elements worth of perks?
perks as in?
Like the tempest armor should give the bonuses of both the water and air armor
Basically count as both schools
the base system only support one school, for the armor bonus to glyphs etc you could make the hybrid schools with an override to isPartofSchool(AbstractSpellPart p) to OR the two schools its made of
for the damage reductions, i could move the map filling to the doAbsorb function of the interface
so you would be able to fill it with both
Hmm. I’m thinking I might have an easier time if I just made each set individually instead of using the existing framework. Especially since I want to work in the bangles/foci as well.
Will have to tinker some more.
But I am determined to make this one without MCreator.😂
bangles do the getSchool().isPartOfSchool(part) too
so having a "Storm" school that OR water school check and air school check should be the less hacky option
MCreator will mostly slow you down in my opinion, so good riddance.
I used MCreator for Fauna and Artillery because I actually don’t know Java. I’m attempting to reverse engineer things from Elemental, but I have to figure out context from reading the code.
Okay, so I’m looking at the code for Ars Nouveau SpellSchools.java and I see that there is an ELEMENTAL school that has the four elements as subschools. How can I add spell schools like that for the six dual element combos?
do you want to add a new school ?
if yes, all you need to create is a (static) instance of SpellSchool class somewhere and use it accordingly
let me know if you need an example
not sure what subschools are meant to do but yeah you can probably just follow the same syntax
what do the errors say
have you imported them properly ?
which file is this ?
oh its because you are calling it wrong
since your schools sit in ArsNouveauRegistry class
you need to use ArsNouveauRegistry.TEMPEST
Okay that worked.
I’m reverse engineering the Ars Elemental code and was trying to use the same formatting that Alex used.
They are either unused or used for the "is part of school"
public boolean isPartOfSchool(AbstractSpellPart part) {
if (getSpellParts().contains(part))
return true;
for (SpellSchool spellSchool : getSubSchools()) {
if (spellSchool.getSpellParts().contains(part))
return true;
}
return false;
}
seems that if you set the two as subschools you don't have to make a subclass of spellschool
so Tempest with subschool Air and Water for example
amplification and discount will match
then you just have to override in your armors
default boolean doAbsorb(DamageSource damageSource) {
// check if the damage source is in the list of damage sources that this armor can absorb
return damageResistances.containsKey(getSchool()) && damageSource.is(damageResistances.get(getSchool()));
}
default boolean fillAbsorptions(DamageSource damageSource, HashMap<SpellSchool, Integer> bonusMap) {
// check if the damage source is in the list of damage sources that this armor can absorb
// then add the school to the bonus map
if (doAbsorb(damageSource)) {
bonusMap.put(getSchool(), bonusMap.getOrDefault(getSchool(), 0) + 1);
return true;
}else return false;
}
to check for the both schools and fill the map
added this little change now on git, so bump your indev version to use it @unreal summit
fun fact - ars controle has a mixin + mixin plugin to fix the event queue on older ars versions so that i didnt have to bump the dependencies lol
Fielding feedback from addon devs, anything you can think of that would be beneficial to include here?
Couple examples
Very nice!
Can someone tell me what's wrong. This is the log i get when i try to boot up minecraft with my Ars Elemancy build. It's not even getting far enough to get a crash log
I've also tried disabling Elemental and i get this when trying to start a world with just Elemancy. (I removed the dependency temporarily to allow it to load)
I don’t know how you people do this coding by hand. I’m about to pull my hair out trying to figure out why things won’t load. The mod builds just fine in IntelliJ, but won’t load in MC itself, so I can’t even start testing - but it won’t give me any indication as to WHY it isn’t loading, just “hey something happened with the MouseClicker” which isn’t even something I messed with.
I need a drink.😂
is the github up to date?
I don’t have a GitHub yet for this one. I’ve basically dissected the code from Elemental, scavenged the pieces I think I need, and jettisoned the stuff I know I don’t need. Then I’ve rebuilt files with all the new content.
I guess I can load it into GitHub to see if anyone can see where I’ve messed up.
well yeah, frankencoding has a lot of point of failures
you need to make it visible because it could be anything
Creating the repository now
An expansion for Ars Elemental, adding dual- and quad- element gear. - Lyrellion/Ars-Elemancy
Be gentle, I’m in over my head here.😂
I’m sure there are also more parts that I can strip out, but I don’t want to accidentally drop a piece of code that I need without realizing it was an important file
well yeah it's basically a repacked elemental
My first attempt I accidentally stripped out the foci code, which I will need for the dual-foci to work
i'd honestly have an easier time knowing your edits and nuking everything not needed than try to investigate on this
for some reason gradle refuse to cooperate
The main thing is that everywhere there is a reference to the four elements I added in the tempest, cinder, silt, mire, vapor, lava, and Elemancer schools
after adding these to the registry
public static final SpellSchool TEMPEST = new SpellSchool("tempest").withSubSchool(ELEMENTAL_AIR).withSubSchool(ELEMENTAL_WATER);
public static final SpellSchool CINDER = new SpellSchool("cinder").withSubSchool(ELEMENTAL_AIR).withSubSchool(ELEMENTAL_FIRE);
public static final SpellSchool SILT = new SpellSchool("silt").withSubSchool(ELEMENTAL_AIR).withSubSchool(ELEMENTAL_EARTH);
public static final SpellSchool MIRE = new SpellSchool("mire").withSubSchool(ELEMENTAL_EARTH).withSubSchool(ELEMENTAL_WATER);
public static final SpellSchool VAPOR = new SpellSchool("vapor").withSubSchool(ELEMENTAL_FIRE).withSubSchool(ELEMENTAL_WATER);
public static final SpellSchool LAVA = new SpellSchool("lava").withSubSchool(ELEMENTAL_FIRE).withSubSchool(ELEMENTAL_EARTH);
elemancer just references the original ELEMENTAL school in the base mod
i also added recipes for items, renamed a bunch of stuff from "elemental" to "elemancy", and replaced instances of "alexthw.ars_elemental" with "lyrellion.ars_elemancy", then made sure that all the links were intact in intellij
So the things to keep are few recipes in the datagen, schools and few items?
basically anything that says one of those 7 school names
almost there to have a better picture
@unreal summit does this one still crash out of IJ ?
How do i import a jar directly into IJ? I put the jar in the MC mod folder and it loaded okay...crashes when you try to search the creative inventory though
Yeah i meant simply in an instance
Haven't tried loading into a world even from inside IJ 😛
Can look later to what is the inventory issue, maybe rendering
The game crashed whilst chartyped event handler
Error: java.lang.NullPointerException: Cannot invoke "net.minecraft.core.Holder.value()" because "p_323783_" is null
Gonna open the PR so you can at merge it later
thank you so much
Maybe start from the addon example and add to it next time
Elemental is set as implementation dependency so IJ can import its code
Should have upped the elemental version now that I think about it, prolly doesn't have the push with the little edits that ease working with your armors
How has the dyeable system for the armor be done? I am trying to have something similar for my samurai mod. chonky helped me to implement it to my mage samurai armor(added method from ars). now I wanna try to do something like this for my samurai armor to remove the unnecessary gemstones.
to be honest I don't understand the perk util and all about data components. and I am on 1.21.1
I am trying to implement it into the base mod to get use of it with the addons I will create for 1.21.1 to seperate the code. So I can dye the basic armor and use it for the addon armor
Handmade
Each color has a texture
Data components are what replace nbt for items
Ars armors should be using the COLOR component, which is vanilla and otherwise used by beds and other single color dyables
Checking the color saved in the slot of that component of the item allow to switch the texture to use
If you know what a map is in programming, components are the keys of the map (that also define the type of the value) so it's way more efficient to read the data you need from the item
oh yes that is what I am searching for. But I don't understand data components.
https://docs.neoforged.net/docs/items/datacomponents/#adding-default-data-components-to-items
I found it on the docs.
Data components are key-value pairs within a map used to store data on an ItemStack. Each piece of data, such as firework explosions or tools, are stored as actual objects on the stack, making the values visible and operable without having to dynamically transform a general encoded instance (e.g., CompoundTag, JsonElement).
thanks it worked with the BASE_COLOR component
now texturing time. Thank you so much. It took me some time but it is working now.
heya, how could i check if something (an instnace of AbstractSpell) is tagged with my custom tags for the "AbstractSpell" class?
i've been searching for it but i haven't gotten any useful info so far
if you tag the glyph item, maybe getGlyph?
im using TagKey<AbstractSpell> DEFENSIVE = register(SPELL_REGISTRY_KEY, “defensive_spell_tag”)
that's just the tagkey creation, not how you're tagging them
i’m using a data provider
would you like to see the code?
i can send it
data providers
oh shoot
i forgot to add that when i wrote the code jn discord
what is being tagged is an inheritor of “AbstractSpell”
then you need to mixin into abstract spell and add an "is(TagKey)" method
or anyway a method to check into the registry holder
the problem is how can i check if the spell is tagged
which i am unsure on how and why it should work
since it relies on a registry and spells don't have registry but a simple map
since the addon is for irons spells and spellbooks, i have access to a registry containing the spells
i'd say start from itemstack#is and follow the breadcrumbs
oh i forgot about that one
or swap from tagging AbstractSpellPart to tagging the glyph item
then AbstractSpellPart#getGlyph#getDefaultInstance#is
are there any plans to backport source capabilities to 1.19.2 and 1.20?
"are there any plans to backport?" is usually a blanket "no"
i am have stupid, i left gui code in unsided classes and now controle 1.2.1 is singleplayer only
ill fix it when i get home lol
hello, how can i synchronize a field between the client and the server? found the answer
when i spawn my entity it has got the correct field in the server but the client side's value is null
i was gonna work on ars controle today but my student license expired and they wont let me redeem my new one because "You already have a JetBrains Product Pack for Students. Please check your JetBrains Account."
even though its expired
¯_(ツ)_/¯
Any news on this?
I had something to fix with it, I believe, but I forgot it existed until now
out of curiosity, why would someone need a lang datagen?
doesnt seem that useful imo
Not sure but likely has to do with translations
if you set it up right, then you only need to write lang keys once. and you get autocomplete/compilation checks whenever you use the keys
i mean i still get that with my IDE just with writing the json part
I get that with IJ modding plugin
I don't use that plugin
Or at least I think it's that
I also have a setup where I define the item name in the registration class so I have a single source of truth
that way I dont have missing strings for items at all
its all personal convenience tbh which is basically the case for all datagen
for EnderIO, this is extremely helpful since the actual code is split across java modules under a single mod which needs a single datagen pass else you overwrite entries
I have some programmatic translations and translation keys, so it's easier than writing the JSON
@Override
protected void addTranslations() {
this.add("tab.allthearcanistgear.armor", "All The Arcanist Gear");
for (ArcanistArmorSet set : AddonItemRegistry.ARMOR_SETS) {
String localizedName = set.getName().substring(0, 1).toUpperCase() + set.getName().substring(1);
this.add("item.allthearcanistgear." + set.getName() + "_hat", localizedName + " Arcanist Hat");
this.add("item.allthearcanistgear." + set.getName() + "_robes", localizedName + " Arcanist Robes");
this.add("item.allthearcanistgear." + set.getName() + "_leggings", localizedName + " Arcanist Leggings");
this.add("item.allthearcanistgear." + set.getName() + "_boots", localizedName + " Arcanist Boots");
this.add("item.allthearcanistgear." + set.getName() + "_spell_book", localizedName + " Spell Book");
}
}
I prefer having it all in Java though
also recently did some fun extension of codec stuff:
private static final MapCodec<ExtendedGlyphCasterData> BASE_CODEC = createCodec(ExtendedGlyphCasterData::new);
public static final MapCodec<ExtendedGlyphCasterData> CODEC = Codec.mapPair(
BASE_CODEC,
Codec.INT.fieldOf("bonus_slots")
).xmap(pair -> {
ExtendedGlyphCasterData data = pair.getFirst();
data.bonusSlots = pair.getSecond();
return data;
}, instance -> Pair.of(instance, instance.bonusSlots));
private static final StreamCodec<RegistryFriendlyByteBuf, ExtendedGlyphCasterData> BASE_STREAM_CODEC = createStream(ExtendedGlyphCasterData::new);
public static final StreamCodec<RegistryFriendlyByteBuf, ExtendedGlyphCasterData> STREAM_CODEC = StreamCodec.composite(
BASE_STREAM_CODEC, Function.identity(), ByteBufCodecs.INT, s -> s.bonusSlots, ExtendedGlyphCasterData::fromStream
);
public int bonusSlots = 0;
public ExtendedGlyphCasterData(Integer slot, String flavorText, Boolean isHidden, String hiddenText, int maxSlots, SpellSlotMap spells){
super(slot, flavorText, isHidden, hiddenText, maxSlots, spells);
}
private static ExtendedGlyphCasterData fromStream(ExtendedGlyphCasterData data, int bonusSlots) {
data.bonusSlots = bonusSlots;
return data;
}
createCodec and createStream are helpers in Ars, which I needed to extend in my own AbstractCaster, so I used a Codec pair to add a field to the codec and an xmap to resolve it, and for the stream I used a composite codec of the existing codec with an extra field
is there any sane way to check if a player can modify a block while respecting claims or should i just let the claim mods handle it themselves
Check BlockUtil in Ars
ah, just posting an event huuh
i love when i finally give AI a chance and it tells me to ignore warnings if i fear them
anyway im fairly sure its fine
at least until project valhalla
then its probably not fine
if you are unsure about safety, disable warnings
in what universe does that make sense lmao
ai is hilarious
@zealous zenith how much of spellbook model and and the UI can I use for my mod (not ars related) ? the usecase and functionality of the books will be wildly different but I love the way the model and GUI looks like. ofcourse I wont copy it 1:1 given that I going for a different theme
i believe the textures are also LGPL
though mods.toml says GPL
cant find anything to suggest textures are licensed differently
Ye it’s the same, you can use it
I wanted bailey's approval even if the license allows it
I am creating a portal kind of thing which players can use to do simple crafting. I want the portal to spawn around the player when they are underground. any idea how I could spawn it ?
its a block and not an entity. I could sprinkle them around with worldgen but I would prefer if they spawned around the player
Does Modrinth also have a similar 'rewards' function like CurseForge?
why is that?
the CI broke
Uh… what is CI
Continous Integration, or in this case, CD's probably better which means Continous Delivery or Continous Deployment.
Bascially automation to make a new build/version of a piece of software automatically available
also modrinth bad use CF
Why so? I don't know anything about modrinth but one user requested to upload to there. I'm guessing some people prefer it for modpacks (?) or something like that
I'm considering stealing the NEG conditional glyph loading code and adding chain to All The Arcanist Gear, thoughts?
My main reason is because I don't believe ATM will ever include NEG/TMG, and playing without Chain is rather unfortunate
Sneaky!
Yeah perhaps, but would improve the quality of life of a lot of players
I'd rather Chain be base, but that's a different conversation
Wish they’d add it for the spell binders
Seems like a good idea
@radiant depot any thoughts on this?
I'd be more curious on why they wouldn't include it while tmg was always in the prev vers?
well, i've improved original chain a bit with the sensitive stuff but it's not like it's mine
it feels very odd to have chain in an atm addon, but it's basically out of spite
so the thing kinda cancels out, lol
just make sure to tick all boxes for not clashing when both are present i guess?
Yeah, I may ask about TMG/NEG but it sucks to not have chain
Yep, that's the big change
Would it be possible to have an entity "cast" spells?
like a mob ?
it's possible ( i think there were familiar and special illagers that did that before, maybe in some addon)
Even just Weald Walk
heya, does anyone know how i could “kill” all entitids of a class on server startup?
i tried several methods but they only kill the client side mob
Why would you need to do it? Asking to hear if there maybe is another way around the issue.
Not sure it's possible to do without someone loading the chunk the entity resides in.
I'm thinking of adding an Enchant that adds Thread Slots in All The Arcanist Gear
a thread slot enchantment I do think could be cool, but I was thinking more for armor that doesn't already have threads
Yes definitely, would be adding for other armor sets, not compatible with armors that already have slots
like provides one thread slot equal to the level of the enchantment
Weald Walk?
Weald Walker
i finally get to delete like half of the code in remote
globalpos iwandable :D
does mean i have to finally bump controle's ars dependency, not that it matters
it was sitting at 5.0.10 for a long time lol
also doing that lets me remove my cursed eventqueue conditional mixin
the entities are "summons" and they should we wiped on world start to prevent players from stacking hundreds of them by leaving and clearing their spell cooldowns
idk on server startup but if you set an entity as nosave it won't be written to disk
ah how can i do this?
it sounds exactly like what i need
Check followprojectile entity
alr
Is there an example for setting up predetermined spell data? Like is there somewhere I could find the contributor tome data?
I got it
Is there supposed to be another big point bump in december? My points/day have doubled since October 31st
Yeah but that happened in September, my points/day has easily quadrupled since then
it's not instant, usually takes a bit to ramp up
Interesting
take it as a 2x for atm and 2x due to season if you got a 4x
obv with diminishing returns, but still chonk for big mods
Yeah I just had a 30 point per day bump from 30th November to 1st December
I did just hit 2M downloads on Additions
i got just a +15 from nov31
but a +70 from oct31
End or start?
I'm at +90 from oct31, so it adds up
no big change between sept and oct, mostly downloads shifting
neg is slowly ramping
instrumentum dropping as it's not on latest
lol mine looks a lot worse
revenue has stayed around the same despite the large dip though
basically all my mods are 1.21 though
and i dont think its shfiting down
that said i really need to get controle in a pack or something
I’m honestly surprised at how well Artillery and Eclectica are doing
Stonks. I didn't even have the statistics page before
That’s an interesting distribution. Mines all over the place
the income jumped but the downloads are flat lol
I really need to get back to trying to fix Elemancy. If I can get it working, I think it will be more popular than Fauna and Artillery and will give a nice boost.
mine counts more projects (not all as author) so it's a bit more spiked in october than nov
5.4Mil in Oct vs 4.9Mil in Nov
the daily downloads will always be a crazy weekend spike + the election day crash
I received some feedback on the domain glyph so I was going to try and rework it. Would there be an efficient way to check if a certain number of blocks around an entity are broken? Want to have it setup a "barrier" of blocks and then have the domain "collapse" (just end) if the blocks are destroyed
It's still just an idea but if there was a way to have the block update the domain entity when it's destroyed it'd be pretty easy to use that as a threshold and then kill the entity
I haven't made any blocks yet so I'm not sure if there's a way to track an "owner" like that
store the AABB + blocks broken + expiry time in a list for that level, then check block break events against those AABBs. then just use that object to increment the blocks broken and an expiry for when to evict from the list
and the ID of the entity its for
Ty, I’ll give it a try when I get back from work
yeah idk about this, i feel like most pack devs wouldnt really care much for more addons lol - especially for bigger packs
might try to suggest it for enigmatica though
but probably not atm
someone already suggested controle for atm actually, didnt get anywhere though (probably because it was in its infancy and barely added anything back then)
What's the consensus on 1.21.4?
gonna hold on 21.1, move forward or too early to say?
no reason for it to change
keep 21.1 as main until 22
the changes in smaller versions are enough to be very time consuming
What's the difference, there's no features, just bug fixes and api changes?
there are actually features, hidden by the feature flags
but also some pretty important changes to the api
the new biome
chunkloading ender pearls
When I run a gradle build in IntelliJS, why am I getting a .jar AND a sources.jar?
sources jar contains the actual source code of the mod. it is used so when other people use your mod as a library
it could be that you enabled it . check your build.gradle file
heh, source jar
I don’t even know how I would have enabled that. Do I need it? Because I am having a ton of problems getting this mod off the ground, and I don’t know what I’m doing wrong.
There is a withSources or smth in your build.gradle in theory
If you copied it from one of mine since I push to a maven, and there the sources are useful for other devs to download
Haven't listened to it yet, but this might be my new programming background music 😂
https://open.spotify.com/album/5cbmq8CMF3EiUs1LPrw4yn?si=AnPyErMwSueflO5hhmDVVw
If you use datagen to do some recipes, can you do other recipes manually in the resources/data folder in the same mod? Or does it have to all be one way or the other?
You can mix and match, make sure manual recipes are in the non-generated folder
I'm a proud mix-and-matcher just because sometimes it's not worth writing a lot of Java for a single type of recipe.
But it did get me thinking, when is it worth it? I guess if you have a lot of recipes and you foresee the ingredients changing
i do datagen for most recipes so that they dont break between versions
barring api changes of course
Generally I will use datagen when it's something I'm going to use frequently, or things that may change frequently like Qther said. In All-The-Arcanist-Gear everything other than geo models and textures is datagen, but for Ars Additions I have a mix-match where structure definitions are manual, but big files like processor lists are datagen
I'm entering a world of pain for 1.21, am I not 😂
Probably yes, 1.21 has so many changes. If you can start porting the mod but removing the create integration I feel like you'll have an easier job.
Just comment out anything create specific and port that once Create is out
Once I'm done with the mixing update for Ars Technica, I think that would be wise to begin on, yeah.
all the recipes will have a very small change breaking them
you may be luckly with a regex or have already the datagen and simply run it again
I’m realizing that my armor recipes don’t work without the central reagent being one of the armor pieces so that you can upgrade an existing piece without losing NBT. But then the problem is that each armor type needs at least two recipes (the quad element armor needs 6). And I have no idea how to set that up in datagen - I can’t even wrap my brain around the datagen that you set up the other day.
What do you mean that each armor type needs at least two recipes?
But if I can just make those recipes by hand, it solves 2 of the 8 issues I have on GitHub
Each armor type in my mod can come from two different bases.
Take Tempestmancer armor, for instance. You might be upgrading from Aethermancer or you might be upgrading from Aquamancer.
Oh gotcha. Yeah I think that might be a pain to maintain by hand, but possible. Did you take a look at how it's done in Ars Elemental or Ars Technica?
Shouldn’t be anything to “maintain” unless Alex decides to go in and rename all of his armors. Qther helped out the other day by setting up some datagen, among other things, but I’ve realized the recipes I had aren’t going to work. I just have no idea how to set up datagen, even after looking at Technica, All the Arcanist Gear, Elemental, and Qther’s code.
And the fact that it needs variable reagents makes it even worse.
I’m also not even sure which lines I need to comment out from the stuff Qther wrote.
Okay, I think I get the issue now, also looking at the AEApparatusProvider you have.
I don't have any version updating experience but if these recipes are using 90% mod items anyway, I think it could make sense to do it manually. The only annoying maintenance is if you decide that it should e.g. cost less/more source, other pedestal items etc, you need to adjust that manually in dozens of json files then.
Dunno if you can write anything custom to preserve/merge NBTs from pedestal items to the output. :/
Most of my code is either pulled directly from Elemental or written by Qther. I’ve done a few things like defining the new dual spell classes and creating the new items, but it’s all built on a framework I only partially understand
Like some of the armor perks work, others don’t - and I don’t fully understand why.
I think I need to refer to the events code in elemental, but don’t know how to do that, or if I need to just copy it into Elemancy.
There’s a reason my last two mods were written in MCreator.😂
Well, since the heavy and light armors gets pushed away by something not planned every time i try to start working on it, you may be safe for a few months
but ideally wouln't require renaming anything
Okay, why is this recipe not working or even showing in JEI:
{
"type": "ars_nouveau:enchanting_apparatus",
"keepNbtOfReagent": true,
"output": {
"item": "ars_elemancy:tempest_boots"
},
"pedestalItems": [
{
"item": "ars_elemancy:tempest_essence"
},
{
"item": "ars_elemancy:tempest_essence"
},
{
"item": "ars_elemental:mark_of_mastery"
},
{
"item": "ars_elemental:aqua_boots"
}
],
"reagent": [
{
"item": "ars_elemental:air_boots"
}
],
"sourceCost": 7000
}
If a recipe is invalid it will show in your client logs
If it's not showing up in the client logs nor ingame, might be the path of the recipe?
Reformatted the code to match similar items in other addons. Still not showing up. Nothing in the log showing a problem with it.
Path is /main/resources/data/ars_elemancy/recipes/
I’ve tried changing the recipe type to all of the following to try to find something that works:
ars_elemancy:armor_upgrade
ars_elemental:armor_upgrade
ars_nouveau:armor_upgrade
ars_nouveau:enchanting_apparatus
The recipes from Qther’s datagen show in JEI, but don’t work in the apparatus.
Maybe the folder is recipe without s?
Tried that too
If you try with items that are not from your mod, e.g. output minecraft:cobblestone and pedestal items as minecraft:dirt or something like this, it still doesn't show up?
Just to make sure it does not fail silently because of a typo or missing item registration
The items exist in the registry, as I can give them to myself directly via the creative inventory, I just can’t get the recipe to function. Mine won’t show up at all, and Qther’s datagen one shows, but does not work in the apparatus itself
compile time safety. the datagen run fails if you dont have a proper resource. be in a regular registry object like item or external files like textures
you also get a nice error message telling you exactly what you need
Items show in JEI and the creative menu, and can be given to inventory and worn
recipe by qther shows
but does not function
it's a magic armor upgrade recipe
so it will check the tier
maybe ?
can you paste that specific recipe?
pretty sure you should either make your own recipe type to merge the nbt of the two armors or choose one of the two to be the main reagent
as you would lose the enchantments et simila this way
this is Qther's version from datagen that i tried in the screenshots
{
"type": "ars_elemancy:armor_upgrade",
"pedestalItems": [
{
"item": "ars_elemental:air_boots"
},
{
"item": "ars_elemental:aqua_boots"
},
{
"item": "ars_elemancy:tempest_essence"
},
{
"item": "ars_elemancy:tempest_essence"
}
],
"reagent": {
"item": "ars_elemental:mark_of_mastery"
},
"result": {
"count": 1,
"id": "ars_elemancy:tempest_boots"
},
"sourceCost": 7000
}
oh, it is a custom recipe type
which one did you use?
elemental's
as a base i mean
this is the manually made recipe i made:
{
"type": "ars_elemancy:armor_upgrade",
"keepNbtOfReagent": true,
"pedestalItems": [
{
"item": "ars_elemancy:tempest_essence"
},
{
"item": "ars_elemancy:tempest_essence"
},
{
"item": "ars_elemental:mark_of_mastery"
},
{
"item": "ars_elemental:aqua_boots"
}
],
"reagent": {
"item": "ars_elemental:air_boots"
},
"result": {
"count": 1,
"id": "ars_elemancy:tempest_boots"
},
"sourceCost": 7000
}
i have tried changing the type to "ars_elemental:armor_upgrade" and even to "ars_nouveau:enchanting_apparatus"
did you try making the air boots from scratch instead of from creative?
i was asking for the json of this
well, i can't dive like usual because i have something to do but i can check if the recipe type code on gith has any explanation why it wouldn't work
public class ElemancyArmorRecipe extends EnchantingApparatusRecipe implements ITextOutput {
public int tier = 3; // 0 indexed
public ElemancyArmorRecipe(Ingredient reagent, ItemStack result, List<Ingredient> pedestalItems, int cost) {
super(reagent, result, pedestalItems, cost, true);
//this.tier = tier;
}
@Override
public boolean matches(ApparatusRecipeInput input, Level level) {
ArmorPerkHolder perkHolder = PerkUtil.getPerkHolder(input.catalyst());
if (!(perkHolder instanceof ArmorPerkHolder armorPerkHolder)) {
return false;
}
return armorPerkHolder.getTier() == 2 && super.matches(input, level);
}
See this?
for the moment replace matches with just
@Override
public boolean matches(ApparatusRecipeInput input, Level level) {
return super.matches(input, level);
}
brief expl:
your reagent is the mark of mastery, which would fail both checks specific of the armor upgrade thing
loading up to test
still doesnt work, but i think the key is to get my recipe to show up instead of the datagen one since it uses the armor as the reagent anyway
ok i tried making a recipe for enchanting dirt into stone and it didnt show up either
gonna go work on christmas decorations for a bit, this is giving me a headache😂
Ok, I tried just making a super basic crafting recipe and it STILL isn't showing up
it's just not seeing ANYTHING that i put in that folder
Can you put it in the generated folder instead to check if it's then working?
Just temporarily to confirm
Can you put manually made files in the generated folder without it messing things up?
I think you can but if you run the data target it might wipe the folder (?) and then regenerate recipes
So if you just runClient it should not try to generate anything iirc
I always test by building the jar and running it in an actual Minecraft client.
And putting that recipe in the generated recipe folder didn’t do anything…
That is quite a cumbersome way of testing? So you build the jar and move it over? I think you'd would save a lot of time by using e.g. IDEA, you can just run the changes immediately. Or even debug and put breakpoints to inspect line by line, variable by variable.
it will be simply be nuked at next runData
assuming the same file isn't in both folders
in which case a copy conflict would arise
since on build it merges the generated and the "classic" folder
i think i have a hunch now that you mentioned you are building jars...
Maybe it's something to do with your build.gradle here:
data {
data()
// example of overriding the workingDirectory set in configureEach above, uncomment if you want to use it
// gameDirectory = project.file('run-data')
// Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources.
programArguments.addAll '--mod', project.mod_id, '--all', '--output', file('src/generated/resources/').getAbsolutePath(), '--existing', file('src/main/resources/').getAbsolutePath()
}
there are two options usually
- the folder path is wrong
- the logs will say why the recipe file was found but not read
the folder in 1.21 would be src/main/resources/data/{modid}/recipe
Folder path is main/resources/data/ars_elemancy/recipes
same file structure as all the other addons I’ve looked at
1.20 and 1.21 have different folder
Can you send over the latest .jar?
that's why i pointed out the s earlier
even assuming the recipe loads, it's very likely that the jei plugin to display the custom recipe type was not added
which means the jei wouldn't know what to show
which leads to testing as the only way (and for that your should fix matches() )
But even for the very normal vanilla recipe it was not loading/showing up in jei
the recipe folder should be recipe in 1.21
(rather than recipes)
Okay…changed to recipe and the basic recipe still doesn’t work
Also, the CurseForge link to the Ars Elemental source apparently defaults to the 1.20.x build
Thought I was looking at the most recent
This might be a fatal issue for my work thus far because I might have been building off of 1.20.x code😞
If you open up the .jar file with an archiver tool you can see if it's even moving the recipes over when building
at this point maybe just datagen lol
I don’t understand datagen. I tried reading the code you wrote and I just don’t get it. Much less how to rewrite it to make it where either of the armor pieces in the recipe can be the reagent and the other be on a pedestal
tbf thats because my code is bad
just wanted to get it working
and apparently it doesnt work anyway
Like I can write a recipe with air_boots as the reagent and aqua_boots as an ingredient; and then a second recipe with that reversed. But I have NO idea how to make a datagen that would do that.
k i wrote the datagen for that
cba to pr
just override that file
unfortunately the recipe still doesnt start
oh wait i might know why
tell me whyyyYyyY
i hope you removed the perkholder check for debug
im not sure if its registering properly yet
forgot to launch with debugger last launch
?
tbh the whole perk/tier check should be removable
since we're only dealing with elemental armor which is always t3
^ remove the whole matches method
it will default to only super.matches
no tier shenanigans involved this way
yep works
i thought removing the matches was because it was using a mark of mastery instead of an armor piece
yes
but now its using an armor piece
but also that the tier might not match
ah
it's looking for a tier 3 armor
elemental ones are either tier 4 or 0
can't remember
especially because there is a weird thing with picking them from creative menu
oh yeahh the tiers
elemental is tier 4, same as technica
we should probably find a way to give some sort of feedback to the user, if we're falling for this trap ourselves several times
so if i'm understanding this correctly, once datagen is run if you make changes to things in the generated folder the changes stay as long as you dont run datagen again?
huh i thought elemental was t3?
elemental is made fROM t3
you arent meant to change the generated folder but technically yes?
yeah, but i don't think you should be putting things there manually in the long run
remember that in code the count start from 0
if you see a tier == 2 it's looking for a tier 3
You can use verifyComponentsAfterLoad to edit the data component on the item once it's created
https://github.com/Jarva/All-The-Arcanist-Gear/blob/main/src/main/java/com/github/jarva/allthearcanistgear/common/items/armor/AddonArmorItem.java#L59-L62
small issue, it will probably wipe the pedestal armors' threads
solution: dont do that
the idea is that you would be upgrading the reagent one with a plain version of the ingredient one...if you use an upgraded one as an ingredient i would expect it's data to be lost in the process anyway
Posted this in a few places, also open to anyone here:
Hey folks, I've been building an update manifest API that automatically generates the data from CurseForge
Does anyone have mods with a decently sized version history that they'd be interested in alpha testing with?
I'm hoping to get the prototype deployed this week.
The interface looks something like this:
/manifest/<provider>/<mod_id>/<loader>
Currently supports CF as well as Forge/Neo (they use the same manifest format), but plans for Modrinth for versioning too
What does it do ?
It produces a json file that allows neoforge to check if your mod has updates and display that in the mod menu
ah cool!
are you making a mod menu ? or is this meant to plugged in the forge's inbuilt system
No, it's built into Neoforge
Yeah
Compatible with both forge and neoforge, going to talk to prospector about adding fabric support too
Is there a way to test for a blockentity?
if (Sphere.test(BlockUtil.distanceFromCenter(p, blockPosition()))) {
BlockState state = level().getBlockState(p);
BlockEntity var12 = level().getBlockEntity(p);
if (var12 instanceof DomainShellTile) {
DomainShellTile tile = (DomainShellTile)var12;
tile.domainEntity.refinement = ((DomainShellTile) var12).domainEntity.refinement;
if(tile.domainEntity.refinement == this.refinement){
breaks--;
} else if (tile.domainEntity.refinement < this.refinement) {
var12.setRemoved();
}
}
}
}```
This has been throwing me errors
```Caused by: java.lang.NullPointerException: Cannot read field "refinement" because "var12.domainEntity" is null
BlockState state = world.getBlockState(p);
if (state.canBeReplaced() && world.isUnobstructed(((DomainShell)
ModBlocks.DOMAIN_SHELL_BLOCK.get()).defaultBlockState(), p, CollisionContext.of(fakePlayer))) {
world.setBlockAndUpdate(p, (BlockState)((DomainShell) ModBlocks.DOMAIN_SHELL_BLOCK.get()).defaultBlockState().setValue(DomainShell.TEMPORARY, true));
BlockEntity var12 = world.getBlockEntity(p);
if (var12 instanceof DomainShellTile) {
DomainShellTile tile = (DomainShellTile)var12;
tile.color = spellContext.getColors();
tile.lengthModifier = spellStats.getDurationMultiplier();
tile.domainEntity = entityDomainSpell;
world.sendBlockUpdated(p, world.getBlockState(p), world.getBlockState(p), 2);
}
entityDomainSpell.shellblocks++;
}``` Did I mess up something when I was placing the blocks?