02:49 <+bridge> welcome to the internet 02:57 <+bridge> ddnet is so cool 02:57 <+bridge> i was like damn i wish i could reset search with a bind 02:58 <+bridge> br_search_string "" 02:58 <+bridge> already exists amazing 03:35 <+bridge> you can predict which of these exist because anything that gets saved after closing the game has to go in a config 03:35 <+bridge> ye so like anything ive made non-default 03:35 <+bridge> does it prune settings that are explicit defaults? probably not right 03:36 <+bridge> cus then migration from defaults messes up those users 11:22 <+bridge> I actually spotted what you meant now I'm pretty sure I fixed it now 12:37 <+bridge> lets cancel @gorp_tw for beeing such a hater! /s 12:38 <+bridge> @l._ouis monthly reminder about the eyes thing :justatest: 13:35 <+bridge> https://github.com/ddnet/ddnet/pull/7253 (reply to the q about `cl_sub_tick_aiming`) 14:32 <+bridge> @learath2 I'm still not done with IR refactor :pepeW: It's decided that I'll have HIR and gMIR/MIR. But another thing is that I wanted to use 14:32 <+bridge> enums for MIR: 14:32 <+bridge> ```rust 14:32 <+bridge> enum GenericInstruction { 14:32 <+bridge> Add(AddInstr), 14:32 <+bridge> Sub(AddInstr), 14:32 <+bridge> Target(I), 14:32 <+bridge> } 14:32 <+bridge> ``` 14:32 <+bridge> 14:32 <+bridge> I thought it'd be weird to use 1 enum type, since some passes could transform instructions and they wouldn't be present in the IR but would still be present in the enum type. So I played with an idea of having enum type per "stage", for example `GenericInstruction` has many generic instructions, and `GenericAfterIsel` would have only a few generic instruction variants(and function which would store those instructions be generic). 14:32 <+bridge> I tried to make this work, but after a few days of trying to make it compile and constantly having 200+ errors I gave up, the code looks ass with generics everywhere, instructions would have to me mapped form enum A to enum B :\ 14:32 <+bridge> 14:32 <+bridge> I'm fine with not using enums but I have one thing I don't like about the IR I have now(https://github.com/MilkeeyCat/tja/blob/5f54924385ddce959744a9c14c65db21f79610c7/tja/src/mir/instruction.rs#L16-L24), it takes multiple elements in `operands` vector to make a valid amd64 address operand(each part of an address is a separate `Operand`). It should be possible to use `operands: Vec>` 14:32 <+bridge> and have `Amd64Address` struct instead, but is dynamic dispatch a good idea? :\ 14:32 <+bridge> 14:32 <+bridge> How would you design an IR to be able to represent generic and target specific instructions(and operands)(and in rust btw). Do you think dynamic dispatch could be a good solution? 14:41 <+bridge> @learath2 I'm still not done with IR refactor :pepeW: It's decided that I'll have HIR and gMIR/MIR. But another thing is that I wanted to use 14:41 <+bridge> enums for MIR: 14:41 <+bridge> ```rust 14:41 <+bridge> enum GenericInstruction { 14:41 <+bridge> Add(AddInstr), 14:41 <+bridge> Sub(SubInstr), 14:41 <+bridge> Target(I), 14:41 <+bridge> } 14:41 <+bridge> ``` 14:41 <+bridge> 14:41 <+bridge> I thought it'd be weird to use 1 enum type, since some passes could transform instructions and they wouldn't be present in the IR but would still be present in the enum type. So I played with an idea of having enum type per "stage", for example `GenericInstruction` has many generic instructions, and `GenericAfterIsel` would have only a few generic instruction variants(and function which would store those instructions be generic). 14:41 <+bridge> I tried to make this work, but after a few days of trying to make it compile and constantly having 200+ errors I gave up, the code looks ass with generics everywhere, instructions would have to me mapped form enum A to enum B :\ 14:41 <+bridge> 14:41 <+bridge> I'm fine with not using enums but I have one thing I don't like about the IR I have now(https://github.com/MilkeeyCat/tja/blob/5f54924385ddce959744a9c14c65db21f79610c7/tja/src/mir/instruction.rs#L16-L24), it takes multiple elements in `operands` vector to make a valid amd64 address operand(each part of an address is a separate `Operand`). It should be possible to use `operands: Vec>` 14:42 <+bridge> and have `Amd64Address` struct instead, but is dynamic dispatch a good idea? :\ 14:42 <+bridge> 14:42 <+bridge> How would you design an IR to be able to represent generic and target specific instructions(and operands)(and in rust btw). Do you think dynamic dispatch could be a good solution? 14:42 <+bridge> @learath2 I'm still not done with IR refactor :pepeW: It's decided that I'll have HIR and gMIR/MIR. But another thing is that I wanted to use 14:42 <+bridge> enums for MIR: 14:42 <+bridge> ```rust 14:42 <+bridge> enum GenericInstruction { 14:42 <+bridge> Add(AddInstr), 14:42 <+bridge> Sub(SubInstr), 14:42 <+bridge> Target(I), 14:42 <+bridge> } 14:42 <+bridge> ``` 14:42 <+bridge> 14:42 <+bridge> I thought it'd be weird to use 1 enum type, since some passes could transform instructions and they wouldn't be present in the IR but would still be present in the enum type. So I played with an idea of having enum type per "stage", for example `GenericInstruction` has many generic instructions, and `GenericAfterIsel` would have only a few generic instruction variants(and function which would store those instructions be generic). 14:42 <+bridge> I tried to make this work, but after a few days of trying to make it compile and constantly having 200+ errors I gave up, the code looks ass with generics everywhere, instructions would have to me mapped form enum A to enum B :\ 14:42 <+bridge> 14:42 <+bridge> I'm fine with not using enums but I have one thing I don't like about the IR I have now(https://github.com/MilkeeyCat/tja/blob/5f54924385ddce959744a9c14c65db21f79610c7/tja/src/mir/instruction.rs#L16-L24), it takes multiple elements in `operands` vector to make a valid amd64 address operand(each part of an address is a separate `Operand`). It should be possible to use `operands: Vec>` 14:42 <+bridge> and have `Amd64Address` struct instead, but is dynamic dispatch a good idea? :\ 15:00 <+bridge> You are really scraping at the very edges of my compiler theory and rust knowledge here πŸ˜„ 15:01 <+bridge> To start with, why is an `Amd64Address` even taking "operands". Instructions take operands, not addresses 15:03 <+bridge> nono, I meant that right now 1 `Amd64Address` operand is represented as 4 `Operands` 15:06 <+bridge> if i have mov from register to memory instruction, operands look like this `[Operand::Register(..), Operand::Register(..), Operand::Register(..), Operand::Immediate(..), Operand::Immediate(..)]` where first register operand is.. the instruction's first operand, and `Operand::Register(..), Operand::Register(..), Operand::Immediate(..), Operand::Immediate(..)` represent base, index, scale and displacement 15:06 <+bridge> if i have mov from register to memory instruction, operands look like this `[Operand::Register(..), Operand::Register(..), Operand::Register(..), Operand::Immediate(..), Operand::Immediate(..)]` where first register operand is.. the instruction's first operand, and `Operand::Register(..), Operand::Register(..), Operand::Immediate(..), Operand::Immediate(..)` represent base, index, scale and displacement. 15:08 <+bridge> if i have mov from register to memory instruction, operands look like this `[Operand::Register(..), Operand::Register(..), Operand::Register(..), Operand::Immediate(..), Operand::Immediate(..)]` where first register operand is.. the instruction's first operand, and last 4 operands represent base, index, scale and displacement. 15:08 <+bridge> nono, I meant that right now 1 `Amd64Address` operand is represented as 4 `Operand`s 15:17 <+bridge> I see, I guess I don't see much of a way to avoid the dynamic dispatch there, perhaps you could hide it within a `Operand::TargetAddress()` so only that variant needs to incur a dyn dispatch 15:20 <+bridge> I guess, using `dyn Instruction` instead is also an option. 15:20 <+bridge> I yoinked this idea from LLVM btw 15:22 <+bridge> Which way would you choose? Dynamic dispatch yay or nay? 15:23 <+bridge> What is the other option again? 15:23 <+bridge> Live with this xd 15:24 <+bridge> 1. `dyn Instruction` 15:24 <+bridge> 2. `dyn Operand` 15:24 <+bridge> 3. keep https://discord.com/channels/252358080522747904/293493549758939136/1478393081635016715 15:28 <+bridge> or maybe you'd do it somehow else 15:33 <+bridge> I guess keeping it is also an option, it is kinda ugly though 15:33 <+bridge> I vote you keep it, it works 15:36 <+bridge> I have utils which take a vec of operands and gimme me proper type, and turn this proper type into a vec of operands(for example https://github.com/MilkeeyCat/tja/blob/5f54924385ddce959744a9c14c65db21f79610c7/tja/src/targets/amd64/address_mode.rs#L15-L78), so it's not thaaaat bad 15:36 <+bridge> thanks for making the decision xd 16:20 <+bridge> @ryozuki can you ask your clanker how to improve the code? xd 16:22 <+bridge> do u have arepo 16:22 <+bridge> ah u linked it 16:22 <+bridge> i should read 16:24 <+bridge> give me a sec 16:26 <+bridge> Good question. I've now read through your IR design β€” the flat Operand vector, the Opcode as usize with generic/target ranges, the OperandInfo trait, and the AddressMode being splayed across 4 consecutive slots. Here's my take: 16:26 <+bridge> 16:26 <+bridge> Dynamic dispatch: I'd avoid it 16:26 <+bridge> 16:26 <+bridge> Vec> sounds nice in theory but is painful in Rust for this use case: 16:26 <+bridge> 16:26 <+bridge> - No pattern matching on trait objects. You'd need Any-based downcasting everywhere, which is verbose and fragile. 16:26 <+bridge> - Clone is hard β€” Clone is not object-safe, so you need dyn_clone or manual machinery. 16:26 <+bridge> - Register iteration for regalloc β€” every dyn Operand impl needs a method to yield its registers. Doable but boilerplate-heavy, and you lose the ability to just match on an operand and directly grab registers. 16:26 <+bridge> - Heap alloc per operand + vtable indirection. Not catastrophic but unnecessary. 16:26 <+bridge> 16:26 <+bridge> You'd end up fighting Rust's type system more than solving your actual problem. 16:26 <+bridge> 16:26 <+bridge> Generics for the instruction type: also avoid 16:26 <+bridge> 16:26 <+bridge> You already discovered this. The "generics infection" is real β€” every function touching an instruction becomes generic, and mapping enum variants across stages is painful. LLVM avoids this entirely by using a single MachineInstr type across all phases. 16:27 <+bridge> 16:27 <+bridge> What I'd actually recommend 16:27 <+bridge> 16:27 <+bridge> Your core problem is narrow: address modes don't have first-class representation in the operand enum. The simplest fix is to add one: 16:27 <+bridge> 16:27 <+bridge> #[derive(Debug, Clone)] 16:27 <+bridge> pub enum Operand { 16:27 <+bridge> Register(Register, RegisterRole), 16:27 <+bridge> Frame(FrameIdx), 16:27 <+bridge> Global(GlobalIdx), 16:27 <+bridge> Function(FunctionIdx), 16:27 <+bridge> Block(BlockIdx), 16:27 <+bridge> Immediate(u64), 16:27 <+bridge> Address(Address), // new 16:27 <+bridge> } 16:27 <+bridge> Good question. I've now read through your IR design β€” the flat Operand vector, the Opcode as usize with generic/target ranges, the OperandInfo trait, and the AddressMode being splayed across 4 consecutive slots. Here's my take: 16:27 <+bridge> 16:27 <+bridge> Dynamic dispatch: I'd avoid it 16:29 <+bridge> -- 16:29 <+bridge> what do you think? 16:30 <+bridge> opus 4.6 16:32 <+bridge> I don't want to add address operand to `Operand` enum, but `Compound` variant is an interesting idea 16:37 <+bridge> That makes sense β€” keeping Operand target-agnostic is cleaner. The Compound idea could work well. A few thoughts on how to flesh it out: 16:37 <+bridge> 16:37 <+bridge> pub enum Operand { 16:37 <+bridge> Register(Register, RegisterRole), 16:37 <+bridge> Frame(FrameIdx), 16:37 <+bridge> Global(GlobalIdx), 16:37 <+bridge> Function(FunctionIdx), 16:37 <+bridge> Block(BlockIdx), 16:37 <+bridge> Immediate(u64), 16:37 <+bridge> Compound(CompoundOperand), 16:37 <+bridge> } 16:37 <+bridge> 16:37 <+bridge> pub struct CompoundOperand { 16:38 <+bridge> pub kind: u16, // target defines what this means 16:38 <+bridge> pub operands: SmallVec<[Operand; 4]>, 16:38 <+bridge> } 16:38 <+bridge> 16:38 <+bridge> Then the amd64 target defines: 16:38 <+bridge> 16:38 <+bridge> const ADDRESS_MODE: u16 = 0; 16:38 <+bridge> 16:38 <+bridge> // construction helper 16:38 <+bridge> impl AddressMode { 16:38 <+bridge> pub fn into_compound(self) -> Operand { 16:38 <+bridge> Operand::Compound(CompoundOperand { 16:38 <+bridge> kind: ADDRESS_MODE, 16:38 <+bridge> operands: smallvec![base, index, scale, displacement], 16:38 <+bridge> }) 16:38 <+bridge> } 16:38 <+bridge> 16:38 <+bridge> pub fn from_compound(c: &CompoundOperand) -> &Self { ... } 16:38 <+bridge> That makes sense β€” keeping Operand target-agnostic is cleaner. The Compound idea could work well. A few thoughts on how to flesh it out: 16:38 <+bridge> 16:38 <+bridge> ```rust 16:38 <+bridge> pub enum Operand { 16:38 <+bridge> Register(Register, RegisterRole), 16:38 <+bridge> Frame(FrameIdx), 16:38 <+bridge> Global(GlobalIdx), 16:38 <+bridge> Function(FunctionIdx), 16:38 <+bridge> Block(BlockIdx), 16:38 <+bridge> Immediate(u64), 16:38 <+bridge> Compound(CompoundOperand), 16:39 <+bridge> xD 16:39 <+bridge> i feed whatu said to it 16:52 <+bridge> does remind work via bridge 16:52 <+bridge> !remind 1m ping 16:54 <+bridge> !remind 1m ping 16:56 <+bridge> can you only put hours or days or something 17:03 <+bridge> m might be months 17:32 <+bridge> should be mo 17:32 <+bridge> :( 17:32 <+bridge> !remind 1h test 17:32 <+bridge> if only there was confirmation 17:32 <+bridge> !unremind ping 17:39 <+bridge> !ping 17:40 <+bridge> where pong 17:41 <+bridge> https://cdn.discordapp.com/attachments/293493549758939136/1478432032156549191/test_map_2026-03-02_20-51-12.demo?ex=69a860a0&is=69a70f20&hm=3bc01045456a7d3b609b4c997a61d3acbde9b3580371a0abd968457582a6529f& 17:44 <+bridge> Heh, the clanker came up with a similar solution to me. I also suggested an `Operand::Address` πŸ˜„ 17:45 <+bridge> xD 17:45 <+bridge> learath replaced 17:45 <+bridge> It's further thought on `Compound` is exactly what I had in mind with putting the dyn dispatch into that specific variant too 17:57 <+bridge> Looks perfect to me with the new code, no? I see no difference at all between 19.7 and my Version. Both with `cl_freezebars_alpha_inside_freeze` > 0 and = 0 17:59 <+bridge> didnt check with new code 17:59 <+bridge> but when i posted the comment 18:12 <+bridge> @gorp_tw: there is confirmation. The bot is just dead or muted since quite some time 18:12 <+bridge> Smh its hard to connect to irc with js xd 18:14 <+bridge> tested again and its broken now 18:14 <+bridge> ah i see 18:16 <+bridge> https://tenor.com/view/imgonnabreakmymonitoriswear-gif-26662566 18:32 <+bridge> why is ryozuki ai shill all of a sudden 18:32 <+bridge> ai has been decent for a while beforehand 18:33 <+bridge> bro got the openai check 18:46 <+bridge> They made him use it at work 18:53 <+bridge> <12944qwerty> wait is the menu background generated from a map? 18:55 <+bridge> yes 18:55 <+bridge> same thing as entities bg 19:02 <+bridge> <12944qwerty> wow 19:02 <+bridge> <12944qwerty> where is the ui icons located 19:04 <+bridge> I think it’s a font 19:05 <+bridge> yea 19:05 <+bridge> <12944qwerty> oh 19:07 <+bridge> <12944qwerty> i presume font awesome? 19:23 <+bridge> im pretty sure they just found a free unicode font that had support for most things, and if its ddnet specific its some pngs? 19:24 <+bridge> oh wait no im stupid 19:24 <+bridge> i get what u mean now 19:42 <+bridge> Now it has to work πŸ’” 19:49 <+bridge> not sure, has slight flicker when passing through freeze tile 19:49 <+bridge> and im unfrozen before the freeze bar fully completes 19:53 <+bridge> The flicker I can consider something I can still fix but the freezbar not being completly finished before getting unfrozen is something that exists in 19.7 as well and I have no clue how I would change this. This is generally just happening on that high of a ping. 19:54 <+bridge> It's inherent to how prediction works at high ping I would assume. 19:55 <+bridge> i see 19:55 <+bridge> but bar with start of freeze was fine before 19:55 <+bridge> and if end is still wrong then nothing changed? 20:05 <+bridge> Wait what do you mean? The flicker is unintended I somehow introduced that, so I'll get rid of that but other than that it basically does the same thing as the old code but removes the Issue described in #11775 20:05 <+bridge> https://github.com/ddnet/ddnet/issues/11775 20:05 <+bridge> idk how that issue works tbh 20:08 <+bridge> Basically to reproduce join any high ping KOG server with ddnet 19.7, make sure your prediction margin makes the other players get predicted into freeze and make sure you have `cl_freezebars_alpha_inside_freeze 100` set you will then preceive the flicker that is being talked about even tho the players are never actually frozen. 20:09 <+bridge> and with the changes I made this doesnt happen but clearly I keep managing to somehow smuggle in some other shitty issue while doing so 20:38 <+bridge> apparently in the code, 2-way and all-way stoppers seemed to be intended to be unskippable (grouped with the other unskippables) but they just are 21:03 <+bridge> The Flicker is gone now. If you don't spot any difference to the 19.7 release then I've done my works because the Issue the PR addresses is definitely gone at least. Then atleast it's only a matter of code quality for it to be merged, I guess :owo: 21:06 <+bridge> yea ill check it out 22:10 <+bridge> i need editor tabs so badly xD 22:10 <+bridge> ive closed and opened 2 different maps like 100 times today 22:10 <+bridge> at this point i should just open multiple clients 22:16 <+bridge> Test #11776 please 22:16 <+bridge> https://github.com/ddnet/ddnet/pull/11776 22:29 <+bridge> did compile time shorten? 22:29 <+bridge> after all the prs 22:30 <+bridge> i dont remember how i compiled with clang back then 22:30 <+bridge> Haven't checked yet. But there are still many `system.h` includes left, that should be replace with the individual headers. 22:56 <+bridge> claude*