#Hotpatching Rust code 🔥

1 messages · Page 3 of 1

mellow flint
#

it has an entity() method

elder heart
#

The only thing now though is that we replace RegisteredSystem's system field with the local function by initializing it via System trait with that old system's local data. However, this isn't a public struct. but that system will get access to the local state

#

I feel like I'm just saying words now, system has lost all meaning temporarily. this seems possible

mellow flint
mellow flint
elder heart
#

how do you feel about flaky macros

mellow flint
elder heart
# mellow flint what do you mean?

introducing bevy_kill_my_system_params. Inspired by bevy_kill_my_cache, this macro will add a random amount of unused system parameters to ensure your system's typeid never remains constant

mellow flint
#

Seriously, it's a prototype crate 😄

#

If that's what it takes, that's fine by me

#

Most important is the user experience imo

#

I have to go to a thingy now. I'll still be on my laptop, but I don't have much in the way of a coding setup on it. But I can still review stuff 🙂

idle stone
mellow flint
#

Could we also use register_system and cache the system id ourselves, then register the system again on a hot patch?

#

Per the docs, registering a system multiple times is allowed

elder heart
#

but I think that without doing this, that function pointer's not going to change since the typeid doesn't change. it's still in memory somewhere...but idk

#

maybe we need a third function

#

you have
hotpatch which yknow, for caching
outer for being registered in world so those local vars keep state
inner - the user-facing fn, which outer for passes its local state and other query params into
so now the registered system doesn't change either

mellow flint
#

There’s also the possibility of making #[hot] not support changing signatures by default

#

Since the code generated by that variant is supremely trivial, it would support everything we can throw at a system
Trouble only starts when you change signatures or want to rerun systems

viral dust
#

Ey nice, dx serve --hot-patch works in PowerShell too, so my normal VSCode editing experience "just works"

viral dust
#

I have noticed I need to run cargo clean and usually stop RA too, but otherwise it's much more seamless now

mellow flint
#

I found the getrandom "drama" very entertaining to read btw 😄 certainly made my commute more interesting haha

mellow flint
viral dust
viral dust
#

RA I suspect for the same reason I need to clean; it starts building so it might prevent linker environment variables being set for dx to see

#

Or just otherwise "mess" with things

mellow flint
viral dust
#

I actually didn't know that, I'll try that next time!

viral dust
#

Ideally a checkbox to control whether the reload should happen immediately, and a button that's active when a reload is pending

#

That way things like struct migrations, signature changes, etc. can be controlled by the user

mellow flint
#

Fair enough, I see the merit in that. But I primarily want a prototype in which slapping #[hot] on a function will work for most usecases

#

Having a side by side view of the game and the code at the same time and seeing my changes without even moving my mouse at all was kinda electrifying, ngl

viral dust
mellow flint
#

Though I wouldn’t be opposed to also adding a visual / hotkey mode

mellow flint
#

"Here’s the default with very few caveats"
"Here’s the spicy features with lots of caveats"

elder heart
#

definitely want a jesus-take-the-wheel feature

raven valley
#

This is where the argument for the editor being in-process starts to take hold again

elder heart
#

I think we can fix this bug. I've failed twice and sleepy but will try at it in the am

mellow flint
elder heart
#

yeah that really shewn the light

viral dust
#

I think that power feels good right now because we're missing other tools that are better suited for that niche. Like, editing UI elements spawned at startup. That should be something handled in an inspector or BSN hot reloading rather than patching. Bevy needs both for a wholistic "fast" experience IMO

#

Basically code vs data

mellow flint
#

I will say though that I had quite the "aha!" moment when my roommate was standing next to me and telling me how to change the n-body simulation at runtime, e.g make the black holes bigger the longer you click on it

#

Being able to just hack in feature after feature without recompiling is quite mindblowing.

#

And doing fun things like adding a query to despawn certain objects for testing, then spawning some others in.
Again something that is the job of an editor, if we had one

quartz whale
#

I'm glad it worked! And I'm glad you figured out how to do, sorry for dipping out, I forgot to check discord 😂

quartz whale
#

I think the first time I got that aha feeling of hot reloading was editing shaders and having then automatically update the visuals, but this is basically the same thing, but for logic, which is marvelous

#

Is there a video showcasing the hot reloading yet? Would be really nice to have it in the readme so I can send it to my friends 😄

#

By the way, how does the hotpatching run so quickly? Do you just have super fast computers, or is hot patching faster than a normal recompile somehow?

raven valley
#

In fact with the dynamic linking bevy version he was recompiling in 150ms

quartz whale
#

I'm definitely gonna have to mess around with this over the weekend 😄

raven valley
#

Hell yeah

mellow flint
raven valley
#

Has anyone tried doing the hot patch without debug info + crainlift?

#
  • dynamic linking?
#

How fast is that on Linux with mold

mellow flint
#

That is without dynamic linking, as that is broken on Linux

raven valley
#

Did u remove debug info?

mellow flint
#

note: wild is even faster, but does not work with subsecond right now

mellow flint
#

should try that later

raven valley
#

Yes

#

We gotta just maximize the speed

#

I wanna get sub 100ms recompile hehe

median vale
#

maybe crainlift would help with speed?

#

there's an experimental backend for rust which is pretty quick

quartz whale
idle stone
#

the real timesave is not losing my in-game context though

quartz whale
#

Yeah, it could even be several seconds slower and it would still be better than restarting 😂

idle stone
#

i'm already happy but i would be even happier with actual subsecond hotpatching (on my machine / project)

mellow flint
#

Happy to get suggestions 😉

quartz whale
idle stone
idle stone
#

but i think release builds already default to debug = none and my dev builds in CI already have debug = line-tables-only for cache size savings

idle stone
#

basically .config_fast_builds.toml as a cli tool

idle stone
mellow flint
late stratus
# idle stone like 5-10s i think

wheres your target dir stored? Rust reads/writes a lot during compiles, and having target dir on a spinny disk is a fast way to kill compile times

#

might even be worth detecting and warning about that at some point

celest magnet
#

Has it already been reported that events are triggered twice when a system is annotaded with #[hot]?

elder heart
#

getting pulled into a work thing for a few hours but will try again on the Local, Changed/Added query, and EventReader types later

#

hopefully someone else will figure it out 😅

#

the thing that's irking me the most is observers honestly

#

I feel like there’s a way to caress (this is the bevy discord) two birds with one stone

late stratus
#

have yall considered implementing System on a custom type? like, in a way which allows you to exchange the function being called internally but allowing you to keep the SystemState around as a separate field?

#

from what i can tell, currently theres only nested functions and systems are stored in a resource, but maybe you could store most state in the "system" itself if that system was a struct and not a function?

late stratus
#

it might even be possible to allow them to not be exclusive systems, if and only if ScheduleGraph::build_schedule is enough to refresh this. after digging in, i dont think it is, but yeah

elder heart
#

only question is how to handle local state

#

If we were to handle local query data outside of World, something feels off about that. I'm gonna try out this direction though

late stratus
#

well, local state handling was why i had this idea originally lol

elder heart
#

oh, please elaborate!

#

I don't know all the ins and outs of local state storage

late stratus
#
pub struct FunctionSystem<Marker, F>
where
    F: SystemParamFunction<Marker>,
{
    func: F,
    state: Option<FunctionSystemState<F::Param>>,
    system_meta: SystemMeta,
    archetype_generation: ArchetypeGeneration,
    // NOTE: PhantomData<fn()-> T> gives this safe Send/Sync impls
    marker: PhantomData<fn() -> Marker>,
}
struct FunctionSystemState<P: SystemParam> {
    /// The cached state of the system's [`SystemParam`]s.
    param: P::State,
    /// The id of the [`World`] this system was initialized with. If the world
    /// passed to [`System::update_archetype_component_access`] does not match
    /// this id, a panic will occur.
    world_id: WorldId,
}

this is one way bevy stores systems

#

so, all you'd need to do is make sure that FunctionSystemState persists after hotpatch

#

how? recreate this and its trait impls and go from there

elder heart
#

I love where this is going. This sounds fantastic. I'm gonna sandbox this

late stratus
#

(this is one of the things which implements System)

#

you also then have to implement System::run_unsafe which is this body:

#[cfg(feature = "trace")]
let _span_guard = self.system_meta.system_span.enter();

let change_tick = world.increment_change_tick();

let param_state = &mut self.state.as_mut().expect(Self::ERROR_UNINITIALIZED).param;
// SAFETY:
// - The caller has invoked `update_archetype_component_access`, which will panic
//   if the world does not match.
// - All world accesses used by `F::Param` have been registered, so the caller
//   will ensure that there are no data access conflicts.
let params =
    unsafe { F::Param::get_param(param_state, &self.system_meta, world, change_tick) };
let out = self.func.run(input, params);
self.system_meta.last_run = change_tick;
out

as you can see, this is is how the param state gets used: self.func.run(input, params) where params was given the state

#

so basically, you can just... store the state and only replace self.func with the new one

#

weeeelllllllll

#

its not gonna be that easy because if you want to support changing system params you'd need to somehow match/transfer from the previous params state to the new one

elder heart
#

that would be the cherry on top. Discarding all local state and starting with fresh state due to new typeid could be the first step

late stratus
#

well

#

you already have that no?

elder heart
#

Yes, but without any param that requires world cache

late stratus
#

?

#

ah

elder heart
#

so like any Local or Changed will not run correctly right now

late stratus
#

exactly

#

OH WAIT ofc the typeid would only change if the signature changes?

elder heart
#

right

late stratus
#

i get it, so you reduce the loss of state from "every time" to "only when signature changes" with this, thats what you meant

elder heart
#

yes!

late stratus
#

gotcha gotcha

#

anyways feel free to keep me up-to-date with what you're doing (or maybe we could hop in VC at some point?) - i've read through a lot of the systems/state/schedule code to come up with this idea so i might have some ideas

elder heart
#

however, @mellow flint's macro will actually produce an exclusive system world as you mentioned, getting half-way there. So this approach is kinda like, orthogonal to that.

#

yeah that sounds great!

#

I'm gonna work on this for a few hours and ping when I do something dumb

late stratus
#

the System implementation would have to act like its a exclusive system, for now. at least for testing thats easiest

#

i did try to check and sadly, it seems bevy just doesnt expose the stuff needed to recompute schedule for a existing system after it changes, so no luck on getting rid of the exclusiveness requirement

elder heart
#

also feel free to try it yourself 😅 I'm doing this to learn, not necessarily to execute. there will be bumps

late stratus
#

like, its almost there, i feel it'd be a 5 line function in the Schedule to make it work

elder heart
#

yeah...seems ilke there's some really valuable stuff I found that isn't public

late stratus
#

hell, i haven't actually tested the current state, i just saw the discussion, read the code, and thought of this

#

has someone kept track of a list of changes to bevy itself which would be good to have or well, needed to integrate this fully?

late stratus
#

yea

elder heart
#

yes, there's a resource called __HotPatchedSystems in bevy_simple_subsecond. Looks like:

    #[derive(Resource, Default)]
    pub struct __HotPatchedSystems(pub HashMap<TypeId, __HotPatchedSystem>);

    #[doc(hidden)]
    pub struct __HotPatchedSystem {
        pub system_ptr_update_id: SystemId,
        pub current_ptr: u64,
        pub last_ptr: u64,
    }
}
late stratus
#

like, if it was upstreamed what currently non-pub stuff in bevy should be changed, that kinda thing

elder heart
#

ohhh

#

great point.

late stratus
#

i would bet a lot that when considering upstreaming sth like this, its gonna look completelydifferent in the end, but it might be worth writing down the ideas everyone has had "if i could edit bevy source" to not loose that collective brainstorming

raven valley
#

Track location doesnt work with spawning on the normal commands api? It only works when spawning from world?

#

This seems like an oversight

elder heart
#

oh, hmm

#

I didn't know that...explains a ton

elder heart
#

reason being...

#
pub fn plugin(app: &mut App) {
    app.add_systems(
        Update,
        (|| subsecond::call(|| tick())).run_if(common_conditions::on_timer(Duration::from_secs(1))),
    );
}

fn tick() {
    info!("owo");
}

as long as you connect the dioxus cli notification to subsecond::apply_patch, you can get away with a ton. I really really like the idea of an extension trait, somewhat similar to how Malek added the ability to add and remove systems

#

the idea is that calling app.hotpatch() would return some type that wraps App and essentially allows for hot reloading of literally everything. Interception of adding/removing plugins, observers, and systems. This might be a bike shed moment

#

but I've written code about 5 different ways now 😆 gotta start from the basics

#

oh and this actually sucks. This would break all plugins. maybe it needs to be called last.

raven valley
#

Yeah I think there's tons of potential designs here and we all should probably iterate through several

mellow flint
elder heart
#

you don't sleep! that's cool!

mellow flint
elder heart
#

hahaha lovely

raven valley
#

The sad part is I would have liked ~a few weeks to iterate on a buncha designs and come out with an awesome 3rd party crate but we only have 7 days left

#

For game jam

mellow flint
raven valley
#

Haha true

mellow flint
elder heart
#

what

#

omg

#

it's okay. I'm so far out in another direction right now, totally lost it around 11am

elder heart
#

not until I can implement System

#

just wait (I feel like there's a lot of me saying this, but this time I mean it)

#

this is my current very small problem

#

like do I really need to go <T as System>::In

#

ok yeah

#

I need to sleep

#

use an =

median vale
raven valley
#

@median vale u did the track location work right?

#

Is there a reason it doesnt exist for commands.spawn?

#

@mellow flint guess what I have working Hehe

#

Auto despawn startup schedule

#

I did a gigabrained move

#

It only works if you use spawn directly on a &mut World tho, because track location doesnt exist on commands

idle stone
median vale
#

and i think spawning is implemented on main?

#

location tracking does exist for commands, it's just cursed

#

and behind it's own flag, i think?

raven valley
#

Hnm?

#

OH?

#

What flag!

#

Gimme gimme gimme

#

Wait or maybe im just stupid and it does have it

#

And I just didn't see

#

One sec

#

Nope

#

Okay si

#

I think it exists for components on commands

#

But yall just forgot to add it to spawn_empty

#

On commands

#

@fathom spruce @quick bloom

#

If this does exist as I think it does it would be goodly for a bug fix bevy patch before the jam 🥺

quick bloom
#

Good catch ❤️ I got World::spawn_empty but forgot about Commands::spawn_empty; that's the trouble with API duplication. Gonna make a PR in a minute.

raven valley
#

Yayy @languid sable could this make it into a 0.16.1?

median vale
#

mira, knower of locations

#

keeper of the source map

opaque mulch
quick bloom
#

bevy_mikktspace getting labeled Hic Sunt Dracones?

late stratus
#

dammnit, the more i think about this the more i want to try it myself

raven valley
#

though if we end up doing my thing of allowing you to write new systems during hot reload then caching local state for reload doesnt make much sense ( we may not end up doing write new systems but I hope we do!)

late stratus
#

well

#

overwriting how bevy runs each of the #[hot] systems

elder heart
late stratus
#

fair fair

#

it did kind a sound like you were gonna go for something quite different

elder heart
#

I'm tearing into the fabric of reality searching for answers. can't even see my screen

raven valley
#

!!

#

Lmao

#

Though u can add it

#

It doesnt hurt

raven valley
#

Nope

#

I do schedule stuff

#

U can look at my old pr on Jan's repo

late stratus
#

aight so my option is still not explored

#

dont wanna duplicate work

raven valley
#

Yeyeey

#

Yeah go for your option im interested to see what lies yonder

celest magnet
#

Why is the #[hot] annotation making the EventReader have duplicate events?

late stratus
#

because it doesnt store local state as of yet

#

see the limitations documented at the bottom of readme

idle stone
#

it effectively makes your system an exclusive system called by run_system_once

celest magnet
raven valley
celest magnet
#

Its interesting that even on a normal run (without hot reloading) it still triggers twice when annotated.

late stratus
raven valley
#

Yeah

#

I was trying to debug this with occurus

late stratus
#

LMAO

#

sorry

raven valley
#

Yeee

#

Okay wait so I think my reloadable chunk works

#

Lemme test

idle stone
#

in order to make potential hot patching work

raven valley
#

Yep!

#

@celest magnet with my pr it works lol, not hot reload annotation

#

Just put em in here instead lol

#

And u can hot reload the write event and stuff

late stratus
#

nice!

raven valley
#

Hmmm im wondering if I should break this out into its own crate given its basically a different approach 🤔

late stratus
#

maybe?

raven valley
#

bevy_simpler_subsecond

#

Heheheh

late stratus
#

inb4 tomorrow i have to make bevy_evensimpler_subsecond

idle stone
raven valley
#

Yeah!

#

I mean ig might as well collate all the strategies together in the same crate

#

No reason not to

idle stone
#

yeah so i can experiment with all of them easily :)

raven valley
#

:)

#

Wait so I am confused @grave bane are you trying to persist system state between reloads or just have it work during runs?

late stratus
raven valley
#

Okie

late stratus
#

ALSO

#

wrong ping

raven valley
#

OWO?

#

Oh shit

late stratus
#

lmao

raven valley
#

My pseudo-dislexia strikes again

late stratus
#

i can.. see

#

-# *dyslexia

raven valley
#

Wahhhhh

#

Also my method means systems aren't exclusive

#

The only downside of my method is you can't schedule systems inside the hot reload relative to systems outside the hot reload ( because its actually a secret different schedule )

#

@late stratus we might be able to combine our approaches depending on what you do here 🤔

elder heart
#
pub trait AppExt {
    fn add_hotpatched_systems<S, M1, F, M2>(
        &mut self,
        schedule: impl ScheduleLabel,
        systems: S,
    ) -> &mut Self
    where
        S: IntoSystem<(), (), M1, System = FunctionSystem<M2, F>>,
        F: SystemParamFunction<M2>;
}

slowly but surely...

raven valley
#

Actually I might be able to simplify my crate even more? Okay the question is can I remove a system from a schedule

#

Does anyone know?

late stratus
#

maybe

raven valley
#

Hmmm

#

Its not quite what I wanted because u could have systems on multiple schedules

#

But good enough let's see what I can cook

#

I might be able to make reloadable systems act exactly identical and work every way like normal systems

#

Except they are relodable

#

And then whatever system state preservation thing u guys do when the signature doesnt change, I can also add

#

Or wait

#

I might be able to just do it?

#

OwO?

#

Hmmm

#

Lets see

mellow flint
#

That way, every signature that Bevy accepts should work exactly the same for #[hot]

#

The "change your signature at runtime" feature is then opt-it by using #[hot(hot_patch_signature = true)]

#

Which comes with the previous caveats

late stratus
#

gaahhh why is everything i need private!

#

bevy is teasing me with the ability to implement the System trait easily but making me duplicate half of bevy_ecs!

median vale
late stratus
#

but i do

median vale
#

Implement IntoSystem

#

If you can

late stratus
#

i want to keep param_state but replace func

#

that was the whole idea

median vale
#

If you are implementing system, that probably deserves to live in the ECS crate

late stratus
median vale
#

I don’t think it’s really built for public use

late stratus
elder heart
# median vale Implement IntoSystem

for a second I thought this was like the answer, but you'd still have to have some type that implement System...I guess recursively this could be a function?

#

but not FunctionSystem. only way to get this is to call .into_system on an inner type. My type in question can't do this properly

#

it would be some F that implements IntoSystem that ends up being some system I'm guessing

median vale
elder heart
#

ig just calling into_system on F will do?

late stratus
#

but honestly, if i'm allowing myself to edit bevy_ecs, i'm just gonna use a far simpler and nicer approach of making the ability to replace the underlying func an inherent part of the the System trait

#

or maybe just a method on App/World/Schedule or sth

median vale
#

that would probably be a better way to go about things.

#

modify the ecs and take the nice path

#

no reason to hack around it, it's not like it's closed source

late stratus
#

yes but i had a hunch this may be possible without that, being usable as a normal plugin

#

still might, i just might need a &mut World to create such a system. no nice extension trait to App for add_hotpatch_systems()

elder heart
#

is what I'm saying super wrong? my strat is to have a wrapper that will, on the call to .run_unsafe. The struct wraps some function that calls into dioxus's hotpatching function, and in turn, calls the inner types' .run_unsafe with the world args

#

I feel like a copy of FunctionSystem is kind of necessary. edit: I think at this point, I've failed. Gonna let the pros handle this, but yknow, it was fun and maybe productive? Just wish I'd figured out how to embed hotpatching into the fabric of SubApp

languid sable
raven valley
#

Hmmm. Schedules are not manipulatable enough

#

For what I want

#

Its totally doable I just cant do it with how scheudles work rn

#

Sadge

mellow flint
raven valley
#

Okay actually, so the more I think about it the more I think that what might end up being ideal is the following: we have a hot macro you can apply to systems, this allows you to change the insides but not their signature, and this works for any system anywhere. It's quick, and easy development debugging and modification.

Then, I think that local state issue is too much of a handicap so that's as far as the macro goes.

Then for everything else we have fully manipulatable hot reloadable systems you can write and edit at runtime non exclusively using my hotpatch closure.

We have a second macro called like "startup_respawn". This is for the StartupRerun schedule ( its needed to do the auto despawn ).

This is my vision rn

mellow flint
#

Also note that the #[hot] macro you're describing is what systems will be doing by default when enabling the correct bevy feature on Francois PR

#

So no macro needed for those 🙂

raven valley
#

Ooo yeah

#

Hmm I hope what francois does doesnt somehow conflict with what I do

#

I would guess not but I honestly dont know 😂

mellow flint
#

Pretty sure it does not 🙂 @lone token

raven valley
#

But yes that would be an even better future!

#

Does francois systems allow u to modify signatures without losing local state every run ?

#

Like the event reader problem

#

If not its fine but if so then it really makes things much much better, then u just write inside the closure when u are actively developing ( and u can leave it there if u want )

#

Otherwise there is extra reason to leave stuff in the closure ( the ability to modify signatures)

raven valley
#

So it auto despawns entities

#

I got it working here

#

With hot

raven valley
raven valley
#

Then I can remove all the new systems added during the last hot update, and then re-add them for this hot update

#

So that way you can still schedule relative to other things in normal Update

#

Systems as entities would help this lol

#

I dont think the changes I want will get added until systems as entities

vivid ember
#

That should be doable if we swap to slotmaps to be able to remove systems, and add a way to go from TypeId -> SystemTypeSet -> query the hierarchy graph to find the corresponding system NodeId to remove specific ones

raven valley
vivid ember
#

hmm actually I don't think we can do TypeId -> SystemTypeSet, unless we swap SystemTypeSet to storing a TypeId rather than be generic

#

which is probably doable

#

I will take the nerdsnipe and do a minimal PR to swap to using slotmaps this weekend

#

unless someone else wants to meowsmile

late stratus
#

hmm

#

do you think re-computing a existing systm as if it was just added is reasonable?

#

in the schedule

languid sable
vivid ember
#

yea slotmaps + some graph querying functions should be all we need

raven valley
vivid ember
#

just uhhh, don't know it too often because big schedules are expensive to rebuild afaik HMM

mellow flint
raven valley
#

Only on hot reloada

#

Reloads*

mellow flint
#

There we go, published 0.1.10
Pinging @celest magnet and @idle stone so you two can update 🙂

#

@idle stone is this enough to allow to use #[hot] on all functions?

celest magnet
idle stone
mellow flint
#

I'm gonna be AFK for 45 minutes or so, then I'll remove the ugly __HotPatchedSystem::system_ptr_update_id. Pretty sure none of you depend on that

mellow flint
idle stone
#

oh well i haven't checked if they work now

raven valley
#

Lmeow

idle stone
#

i assumed the latest release only added support for saving system state so that Local etc. work?

mellow flint
mellow flint
idle stone
#

ah ok, i'll try it out

mellow flint
#

No changing signatures, no reruns unless you opt in

#

That allows us to pass the system nearly unaltered to Bevy

#

I think the only thing that wouldn't work is destructuring stuff in the params, i.e.

fn foo(In<age>: In<f32>) { }
#

But who would do that????
Just kidding, Yarn Spinner heavily relies on that 😄

raven valley
#

As do i!

mellow flint
#

But Yarn Spinner needs its own integration layer anyways

mellow flint
raven valley
#

I love destructuring

idle stone
#

is there a technical limitation there, or just more macro fu needed

raven valley
#

Leave it for now tho it is rare enough

#

Unless ur really itching

mellow flint
#

I have an idea of how to do that, but I'm too lazy right now 😄

#

(we could just give out variable names automatically for the outer function: a1 for the first param, a2 for the second, etc.)

#

(dunno if rust-analyzer will like that)

#

or error messages for that matter

idle stone
#

i can confirm my systems returning Progress piped via .track_progress() are now hot-patchable

raven valley
#

Hopefully this new pr unfucks rustrover

#

It was unhappy when I pulled last

#

And when I tried to manuallly expand the macros they got upset and said they were unwrapping a none, lol

idle stone
#

can confirm my Locals are working

#

can confirm system with simultaneous &mut World and Local params is hot-patchable

raven valley
#

Lessgoo

elder heart
#

can't wait to see hahaha

idle stone
#

function returning a system is not exactly hot-patchable currently?

#

it compiles, and it says "hot-patching..." when i change it, but the system it already returned to app.add_systems doesn't change

#

is it possible to like.. annotate the inner function?

late stratus
#

damn the new PR arrived at basically the same conclusion i did

#

well

#

new update now, not a PR anymore after its merged is it

#

SystemState::new() is the ticket to it working

late stratus
#

uhh

#

not a PR anymore, as i said

#

the 0.1.10 version

elder heart
#

ok

late stratus
#

Q: can rust-analyzer expand non-recursively? i just want to expand 1 layer of macro

raven valley
#

Rust rover can if u have that!

late stratus
#

nope

#

mostly i'm getting annoyed at all the tracing macros

#

i might just remove those

late stratus
#

oh its just 2 lines

#

commented

mellow flint
#

Remove them for debugging and its much cleaner 🙂

late stratus
#

wait

#

i did and its still there :(

#

probably rust-analyzer didnt refresh the macro

mellow flint
#

Try cargo expand

late stratus
#

i'm now looking into whether this can be done macro-less

elder heart
#

no fking way SystemState has a constructor to build a FunctionSystem. like if someone had said that that would've been gold.

late stratus
#

i feel it can be

elder heart
#

this can be done macroless

late stratus
#

generics hell, but it can be

late stratus
#

huh? i apologize, i didn't mean to imply anything by that beyond "we just arrived at the same conclusion" @elder heart

late stratus
#

expanding after that accepts the modifications

late stratus
#

I GOT IT AHAHAHAHAHAH

raven valley
late stratus
#

need to test stuff first but maaaayyyybee a PR incoming

#

i may or may not have gotten rid of all the events and HotPatchedSystems handling

#

also did not implement/keep rerun-on-hotpatch functionality

raven valley
#

OwO?

#

OWO?

late stratus
#

false alarm: i can only change strings

#

false alarm again

#

it only works properly when i'm not changing the signature

#

sadge

raven valley
#

OwO

#

Speaking of!

#

.... drumroll

#

🥁

mellow flint
#

-# (it's compiling tets)

#

merged!

raven valley
#

WAHOOO

mellow flint
#

I'll quickly yeet system_ptr_update_id and then do a new release

raven valley
#

( you don't have to, just an idea 😄 )

late stratus
#

in case anyone is curious, heres what i did. it doesn't work with signature updates, and probably has some other issues, so i'm gonna just drop this here and be done with it. not worth making a branch IMO, i didn't actually manage any of the "custom System impl" idea i had because turns out thats not neccessary and hindered by tons of private types

mellow flint
#

I see what you were trying to do

mellow flint
late stratus
raven valley
#

Haha

elder heart
#

I guess my main source of confusion, at this point, is understanding the persistence of SystemState...and what happens when someone adds a Local to their params in some hot patchable function. iiuc, the data within systemstate is 1:1 with the systemparams of the fn

#

so how to get that to change on hot reloading...a dyn system param, perhaps? but even that wouldn't work.

#

if someone's already tackled the problem of local data queries, then hell yeah, ill set it all aside

#

but if not

raven valley
#

I have!

elder heart
#

I think this is something that will need figuring

#

you have? :o

#

please put my rabid brain to rest

raven valley
#

Yeah local data works fine in the reloadable section

elder heart
#

was that in ur pr? I'm gonna look for it

raven valley
#

Look at the repo at the add_systems example

elder heart
#

definitely want to see the implementation. that part's killing me.

raven valley
#

Its not what you would expect!

elder heart
#

has me pacing

raven valley
#

Haha

#

The implementation is in the hotpatch_app file

mellow flint
#

I think we could do something similar for Local

#

@amber grotto

raven valley
#

Ah more in terms of, local works at all, we dont migrate from one local to another

#

When u modify a system it still resets the locals

elder heart
#

wait, so essentially a sidestep of SystemState...something that recreates SystemState on every frame before running?

raven valley
#

If i understand what ur asking

elder heart
#

You do, that makes sense

#

simple. genius. so the whole closure is reloaded?

mellow flint
#

Done, version 0.1.11 contains @raven valley's new feature 😄

#

In the meantime, I'm being scammed by anime girls

#

Ah yes, the future is now

vivid ember
#

Hey, you just did a great job in Zombies, team up?

mellow flint
#

sorry to bother u.

vivid ember
#

unfortunately I am not an anime girl

mellow flint
#

ty
but it's nice to meet you, I'm 25 years old, you?

#

Hey, can I invite you to play TWD with me?

vivid ember
#

swapping to slotmaps cleans up so much stuff

mellow flint
elder heart
#

Hey, can I invite you to play TWD with me?

mellow flint
raven valley
#

AHAHAHHAHHA

mellow flint
#

@raven valley when you have time, could you make with_hot_patch desugar to something slim on release and Wasm? 🙂

raven valley
#

Ooo yep

#

Sure

mellow flint
#

Also, something that can rerun OnEnter would be nice

#

I think systems added in the closure are allowed to change their signature, right?

#

If so, I think your feature could be used instead of the #[hot] macro

#

I think keeping the base macro would still be good for usability

mellow flint
#

But we could consider removing the optional "extensions"

vivid ember
#

it appears that running the ci test suite locally crashes my desktop env, so we publishing the pr without testing 😎

raven valley
idle stone
raven valley
#

I've been meaning to learn

idle stone
#

runs once per frame*

#

pretty simple conceptually

raven valley
#

Hmmm

#

Ill have to play with it

#

Maybe I'll do that this jam

mellow flint
#

Now, I have nearly nothing set up in Startup at all; most setup lives in some OnEnter and is StateScoped

elder heart
#

just gotta shout out pyrious' awesome work. pyri state is good once it clicks, but it needs to click. it will be my cup of tea sooner than later

warm thistle
amber grotto
#

I think I found a footgun - if you have a component and one of its fields is another struct, and then you update that inner struct, the component still has the same type id

#[derive(Component)]
struct C(Inner); // <- doesnt change type id

struct Inner {} // <- modify this one
#

@mellow flint so that example you sent is not really an issue with migration

#

When you modify that enum it seems to work because it just updates the string in the Debug impl and both versions of the enum have the same underlying representation

amber grotto
worldly ether
#

debugging TLS issues pushed me to use lld instead of ld and now subsecond properly respects your linker setup - leading to a consistent 130-140ms patch time

quartz whale
#

Sick! What was the patch time with ld?

slender relic
#

@mellow flint #[hot] makes lsp-based code highlight red(like it has error) and autocompletion broke :Inspect also confirms that rust-analyzer thinks the code has "type.unresolvedReference"

#

it latest from crates.io also from git (editor is neovim)

worldly ether
slender relic
worldly ether
#

if you want to provide proper autocomplete you need to do partial expansion.

https://github.com/TheBevyFlock/bevy_simple_subsecond_system/blob/main/macros/src/lib.rs#L56

to properly get autocomplete when doing function parsing in macros you need to fork the stream, output the original token stream regardless if it's actually a function, and then do the code-gen using the forked stream

it's a pain, but we do it here for rsx

https://github.com/DioxusLabs/dioxus/blob/5db8b95c54d1c481d4e4c0525260cc2c827dbc98/packages/rsx/src/raw_expr.rs#L16-L58

https://github.com/DioxusLabs/dioxus/blob/5db8b95c54d1c481d4e4c0525260cc2c827dbc98/packages/rsx/src/partial_closure.rs

quartz whale
quartz whale
amber grotto
#

But the problem is that you need to update TypeId -> ComponentID map in bevy which isn't public

raven valley
#

Make the custom id be a compile time macro based which bases it off of the system time

#

Plus type id hash

mellow flint
worldly ether
mellow flint
#

For context, that was my issue on main ^

quartz whale
#

I haven't heard of wild before, but apparently they're trying to add incremental linking, which would be kinda crazy for the hotpatching usecase. It's not yet implemented though, so who knows whether it'll actually save a significant amount of time or not

amber grotto
raven valley
#

All u have to do is make sure u migrate all the types

#

So everything stays valid

amber grotto
#

Not sure I understand, the systems will still be looking for the old component id/type id (which will be actually the only type id)

quartz whale
#

Has anyone gotten dx on NixOS yet? cargo binstall falls back to building from source (and actually I'm not sure it would even work if it had pulled down the binary), and I can't manage to build dx from source due to not being able to find openssl via pkg-config. I've looked at the flake.nix in the repo, and the nix file in nixpkgs, but regardless of what I add on my system it doesn't work. Strangely the actual error claims to be unable to find the pkg-config executable, but that's nonsense, because Bevy already requires pkg-config, and Bevy builds just fine

raven valley
#

😭 nix

celest magnet
#

small suggested for the example (for setup systems), ideally it would show an ergonomic way to also deal with resources (when using world)

#

(its basically the bevy sample, but hot-reloaded)

mellow flint
mellow flint
late stratus
#

feedback from @karmic current in lifestream: install instructions, especially one command ones, shouldn't be hidden behind a details collapse

raven valley
quartz whale
#

Hm, I just pulled down the source and built it with the flake they provide, which obviously works. I have no idea why my own one didn't work, but whatever 😂

late stratus
mellow flint
#

@karmic current I updated the readme accordingly, refresh the page 😉

amber grotto
#

Every couple of hours dx start throwing the windows paths are too long error, so I'm progressively moving the project folder into shorter and shorter paths XD

mellow flint
elder heart
#

throw that bad boy in root, right next to Program Files

#

it's annoying

#

but like, it's worth if you're getting good stuff out of hot patching

mellow flint
elder heart
#

wait...did it work?

#

I must've forgotten to check, I'm gonna see if this fixes the paths problem

mellow flint
elder heart
#

oh yeah, cuz last I remember it wouldn't compile on windows...checking now to see if the paths problem is fixed on windows on the jk/fix-dyn-link-subsecond branch

mellow flint
#

@amber grotto if you fix the merge conflicts, we can merge it 🎉

#

Just add your observations to the readme

worldly ether
mellow flint
elder heart
#

funny enough, can't find CARGO_TARGET_DIR in this env

#

I'll see if I can squash this for the issue, but yeah..no dice

quartz whale
#

Has anyone run into issues like these? They only show up when switching to Mold (though of course the default linker fails for other reasons):

mold: error: undefined symbol: bevy_asset_loader::loading_state::dynamic_asset_systems::resume_to_loading_asset_collections::__CALLSITE::h4d3a7e634fee5fe9
>>> referenced by 17uoh8fy54ggkrbt22dg9ndib
>>>               /home/ole/workspace/rust/sinhala_training/target/x86_64-unknown-linux-gnu/debug/deps/sinhala_training-26c1043305835bbd.17uoh8fy54ggkrbt22dg9ndib.rcgu.o:(bevy_asset_loader::loading_state::dynamic_asset_systems::resume_to_loading_asset_collections::h8b2737a1acf2d4c6)
>>> referenced by 17uoh8fy54ggkrbt22dg9ndib
>>>               /home/ole/workspace/rust/sinhala_training/target/x86_64-unknown-linux-gnu/debug/deps/sinhala_training-26c1043305835bbd.17uoh8fy54ggkrbt22dg9ndib.rcgu.o:(bevy_asset_loader::loading_state::dynamic_asset_systems::resume_to_loading_asset_collections::h8b2737a1acf2d4c6)
mold: error: undefined symbol: bevy_asset_loader::loading_state::systems::resume_to_finalize::__CALLSITE::h24db4c0b788caf68
>>> referenced by dnnu86e1dngosybtwoodipj59
>>>               /home/ole/workspace/rust/sinhala_training/target/x86_64-unknown-linux-gnu/debug/deps/sinhala_training-26c1043305835bbd.dnnu86e1dngosybtwoodipj59.rcgu.o:(bevy_asset_loader::loading_state::systems::resume_to_finalize::hb58d54b7bacae0e0)
>>> referenced by dnnu86e1dngosybtwoodipj59
>>>               /home/ole/workspace/rust/sinhala_training/target/x86_64-unknown-linux-gnu/debug/deps/sinhala_training-26c1043305835bbd.dnnu86e1dngosybtwoodipj59.rcgu.o:(bevy_asset_loader::loading_state::systems::resume_to_finalize::hb58d54b7bacae0e0)
collect2: error: ld returned 1 exit status
celest magnet
quartz whale
#

(It's not all bevy_asset_loader btw, it seems to be thousands of symbols missing)

mellow flint
# worldly ether debugging TLS issues pushed me to use `lld` instead of `ld` and now subsecond pr...

Could you share your config.toml? I'm using the following, but it's still giving me Build failed: I/O Error: No such file or directory (os error 2)

[target.x86_64-unknown-linux-gnu]
linker = "gcc"
rustflags = [
  "-C",
  "link-arg=-fuse-ld=lld",
  # Nightly
  "-Zshare-generics=y",
  "-Zthreads=0",
]
rustdocflags = [
  "-C",
  "link-arg=-fuse-ld=lld",
  # Nightly
  "-Zshare-generics=y",
  "-Zthreads=0",
]

I believe it's still the same issue as on main

raven valley
#

What is the question

#

Oh you mean adding resources?

#

Doesn't handle it yet

#

I have some ideas im gonna do this weekend

#

I wanna only add when it doesnt already exist

mellow flint
#

New Chris feedback incoming?

late stratus
#

thing i noticed: i think my non-working version from yesterday had it roll back to the previous function on panic yesterday, but for chris it just fully panicked. now, it was like 3am at that point, i might be misremembering, but i wonder if the way the macro works breaks that unwind to last working function

mellow flint
#

What exactly is panicking in this scenario?

#

e.g. if you request a Resource that does not exist, that will panic, nothing we can do about it

late stratus
#

tbh i'm less and less sure about what i observed, but i definitely got previous output at some point yesterday

late stratus
mellow flint
raven valley
#

Can't wait till he sees the beauty of .with_hotpatch 🤞

mellow flint
#
  • hot patching can break down if you change signatures when using #[hot]
  • if you revert your changes to the original code when the app started, subsecond does not pick up on that
late stratus
#

ah but i was using a extension trait and .add_hotpatch_sysyem() yesterday

#

no macro

#

could be a syntax error causes it to roll back instead?

mellow flint
raven valley
#

Syntax error prevents hotpatch

mellow flint
late stratus
raven valley
#

Someone should add the .with_hotpatch to the readme otherwise people are gonna miss it

#

If no one does it I'll do it when I get home, space is too cramped on this flight to use my laptop

quartz whale
#

I can't quite get it working unfortunately 😭 If any of the other NixOS people have a link to their configs I'd love to see it 😌

mellow flint
quartz whale
#

Yeah, and it's working with cargo build, but not via dx for some reason, I tried copying the stuff you have in your .cargo/config and stuff as well (and the nixos mold install), but while it's definitely using mold it just gives weird errors. Now that I think about it I still have dynamic enabled, maybe that's the issue actually, oopsie

#

No it still doesn't work 😂

mellow flint
mellow flint
quartz whale
#

Also @worldly ether it seems like the UI crashes if you don't have any dependencies (reproduce with dx serve right after a cargo new) it looks like it's due to the progress bar being too small for some maths to make sense

#

The closest I can get is this error Failed to generate fat binary: mold: fatal: /home/ole/workspace/rust/hotpatching_test/target/x86_64-unknown-linux-gnu/debug/libfatdependencies-8dbb7bc8-bda9-5670-a51e-7eb48041797c.a: unknown file type

#

That file is just an empty file for the record

mellow flint
#

@amber grotto I merged your PR 🎉

#

If so, I'll do a release after

quartz whale
#

Ah the file was just empty because I forgot to add stuff, when I actually use things I get the missing symbols again

worldly ether
#

I might not be able to get -clinker= override working, but for people who use -fuse-ld= I do have it working

#

getting RUSTFLAGS="-clinker=... might not be possible without dx overriding the rustflags

mellow flint
#

@worldly ether I see you merged your PR, so I checked out main. Unfortunately, it is broken for me on Linux

worldly ether
mellow flint
worldly ether
#

you might need to update both the CLI and dependency

#

that changes the symbol we use for offset detection so now the implicit API is no longer compatible with alpha.0

#

the new api relies on main being present so that shouldn't be an issue again

mellow flint
#

Let me do that quick 🙂

mellow flint
#

Now let me try changing my linker

mellow flint
#

"link-arg=-fuse-ld=lld" also works!

#

Now let's try mold

#

@worldly ether you mentioned that linker is not respected. I suppose I need to set DX_LINKER?

worldly ether
#

that requires rewriting the rustflags

mellow flint
#
[target.x86_64-unknown-linux-gnu]
linker = "gcc"
rustflags = [
  # Use mold
  "-C",
  "link-arg=-fuse-ld=mold",
]

^ this is what I need

worldly ether
#

-fuse-ld should work, and modern compilers can typically respect -ld-path

#

in this case gcc is a driver. we use the cc environment variable (rust also relies on cc in env
cc=gcc dx serve --hotpatch

mellow flint
worldly ether
#

i tested with clang - does cc=clang work?

mellow flint
#

Oh wait, do I need to remove the linker param from my config?

#

then it does stuff

worldly ether
#

Oh hmmm, I've been setting linkers with -clinker but we technically do handle the linker field, but I think that has similar issues to the RUSTFLAGS issue

mellow flint
worldly ether
#

the issue is that unless we rewrite the flags, we don't even see that a different linker was requested

mellow flint
worldly ether
mellow flint
#

wait, why am I even using gcc 😄

worldly ether
#

gcc isn't a linker technically though it can be used as one. even in normal operating mode if all you want is to use mold you don't need gcc as a flag

mellow flint
#

Mold expects clang

#

sorry, my bad maybe

#

let me to clang

worldly ether
#

in practice I think you symlink clang to /usr/bin/cc or you place clang in your path symlinked as cc. But I think cc=clang worked for me with the mold setup. FWIW mold and lld were the same performance

idle stone
#

tried this with and without rev: dioxus-devtools = { git = "https://github.com/DioxusLabs/dioxus.git", rev = "929cab9ecfdc991f478e91b09f9e8a7549421e1f" }

mellow flint
idle stone
#

15:21:05 [dev] Build failed: I/O Error: No such file or directory (os error 2)

worldly ether
#

Just

[target.aarch64-unknown-linux-gnu]
rustflags = [ "-C", "link-arg=-fuse-ld=mold" ]

I believe, and then symlinking clang to cc or setting cc=clang

mellow flint
mellow flint
# worldly ether Just ```toml [target.aarch64-unknown-linux-gnu] rustflags = [ "-C", "link-arg=-f...

Still results in

00:23:05 [dev] Failed to generate patch: /usr/bin/ld: /home/hhh/git/bevy_simple_subsecond_system/target/dx/minimal/debug/linux/app/stub.o: .symtab local symbol at index 20 (>= sh_info of 1)
/usr/bin/ld: /home/hhh/git/bevy_simple_subsecond_system/target/dx/minimal/debug/linux/app/stub.o: error adding symbols: bad value
collect2: error: ld returned 1 exit status
00:23:05 [dev] Build failed: No such file or directory (os error 2)
#

I'll try symlinking now

mellow flint
#

Now let me symlink mold to ld again

worldly ether
#

when I ln -s /usr/bin/clang /usr/bin/cc ... if I already had cc there then it doesn't do anything

#

if you're on x86 then there might be some weird interaction with path since rust-lld is stable

mellow flint
worldly ether
#

My path is very clean, but if you have an interesting enough path then some tools might be taking precedence. Can check with which cc , etc

#

Is mold in your path?

mellow flint
worldly ether
#

one quirk is that rust prepares args for cc using -Wl,-arg but when using linkers directly, it prepares them with -arg, and sometimes it's hard to detect that

mellow flint
#

Let me try again 🙂

worldly ether
#

You generally want to use -fuse-ld and then muck with cc

#

well, at least for now until we get all the quirks shaken out

mellow flint
#

Can you reproduce the crash when the linker is set?

idle stone
#

cc doesn't work with mold, no?

mellow flint
#

@worldly ether same error when I really make sure cc is clang.
It looks like it's still using ld for some reason:

#

The only solution seems to symlink mold to ld

mellow flint
worldly ether
#

but modern clang/gcc do

idle stone
mellow flint
idle stone
#

so symlink mold to ld and symlink gcc to cc?

mellow flint
#

(I prefer clang)

worldly ether
#

all you need to do is override cc to a modern linker and then use -fuse-ld unless you're using a weirder linker

#

or set cc=clang via env

elder heart
worldly ether
#

for now, need to properly handle the linker= thing. that's the same issue as RUSTFLAGS

mellow flint
#

I'll now test the global dir thing 🙂

idle stone
#

oh, can you do cc=clang ld=mold dx serve ... instead of a global symlink? that would be much nicer

mellow flint
elder heart
mellow flint
#

Yesss the global dir + mold setup works now heart_lime

idle stone
worldly ether
elder heart
#

with this value unset it fails at least...which is kinda normal behavior I guess?

worldly ether
#

dx does not disambiguate itself in the target folder, so packages with the same name will collide

elder heart
#

well... 18:33:55 [dev] Build failed: I/O Error: The filename or extension is too long. (os error 206) idk if that's the issue

worldly ether
#

We don't have an issue tracking the long paths thing but the recent merge to main shrunk the name of the archive file we were generating to 18 characters

idle stone
#

well i got hotpatching working now with bevy/dynamic_linking enabled, so i can confirm that's working

elder heart
#

agreed. I think it's something else looking at the full log output. I'll investigate this if I have time tomorrow. honestly the output doesn't give much about what specifically is too long, but I think I'll see if I can update this somehow

idle stone
#

i can also confirm that hotpatching is triggered by reverting a single edit and saving again

mellow flint
idle stone
worldly ether
mellow flint
worldly ether
#

Oh, we don't have timings for thin linking

mellow flint
#

I'll open two bug reports later (crash on linker and required symlinks for mold)
I'm just really happy that dynamic linking works now, good job 😄

#

Let me also check wild real quick

idle stone
mellow flint
mellow flint
elder heart
#

but I need to make this issue concise

#

seems also that incremental will fail after first build on wandows

idle stone
mellow flint
#

I mean, in general, sure

#

For hotpatching, I don't know yet

idle stone
mellow flint
#

nextest too, I believe

#

@idle stone does cargo binstall foo --git bla work?

#

I remember there was an issue with the Bevy CLI alpha

idle stone
idle stone
elder heart
idle stone
#

fixed by hard-coding the correct version in the path instead of having cargo-binstall expand it automatically

elder heart
#

I found the windows command that's causing the problem though

#

for whoever's reference, if someone stumbles upon this conversation: packages/cli/src/build/request.rs line 1839

#

will work on tom

mellow flint
idle stone
mellow flint
#

I'd like to change the readme to point to what we know to work right now

idle stone
mellow flint
#

well, main it is

idle stone
#

although it could use the rev when installing from source as a fallback hypothetically

#

funnily enough, in my system, cc is already a symlink to gcc

#

but i assume it runs in cc compatibillity mode or something if arg0 is cc

#

maybe clang does the same thing ^\_(``/)_/^

#

ok interesting

#
$ /usr/bin/cc --version
cc (GCC) 14.2.1 20250207
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ /usr/bin/gcc --version
gcc (GCC) 14.2.1 20250207
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ file /usr/bin/cc
/usr/bin/cc: symbolic link to gcc
#

and cc=alksjf cc --version still runs cc, so the shell gives priority to PATH ig

#

ok, my new setup on Linux is:

  • linker = "clang" commented out
  • "-Clink-arg=-fuse-ld=/usr/bin/mold" in rustflags no longer commented out
  • cc symlinked to clang
  • ld symlinked to mold (this was already the case)
  • bevy/dynamic_linking no longer disabled
  • dioxus-devtools patched to main
#

hotpatching works and takes ~3.5s, which is ~1s faster than before EDIT: and now it takes 4-8s again 😔

elder heart
#

it's somewhere here

#

I'm wondering if the error is a red herring, and it's actually the command that's too long, not a file

#

the character limit seems to be 32767 for commands

#

yep

#

that's it

worldly ether
#

We were creating command files but then linkers that aren’t link.exe don’t accept it 🤷‍♂️

#

I guess you could turn down your codegen unit number in the interim

elder heart
#

oo ok!

mellow flint
#

I want to include it in the readme

quartz whale
#

Wohooo, with main it works now! I don't know what caused, as it now works both with ld and mold, but at least it works 😄

quartz whale
#

I'm getting hot-patching times of very consistent 550ms, which is not quite as good as some, but that's solidly in the "feels instant"

idle stone
#

still 4-8s for me ferris_sob

mellow flint
#

@idle stone I get /home/hhh/git/bevy_simple_subsecond_system/target/dx/minimal/debug/linux/app/minimal-d6dab9ba: error while loading shared libraries: libbevy_dylib-6209f69d2edbbded.so: cannot open shared object file: No such file or directory hmm

mellow flint
idle stone
#

patched dioxus-devtools to main?

mellow flint
idle stone
#

ive definitely seen that error before in some context

#

what's your rust toolchain version?

mellow flint
#

hmm questioning whether cargo binstall installed the right binary

idle stone
#

i'm using nightly-2025-05-14

#

also i didn't use binstall for dioxus-cli

mellow flint
mellow flint
idle stone
#

yeah that'll take from GitHub releases page

#

which is the latest actual release

mellow flint
#

even when doing --branch main, right

idle stone
#

have to install from source unfortunately 😄

mellow flint
#

Alright, I'll change the readme

quartz whale
#

I built it from source directly, and I had issues with mismatched versions between dx and the dependency (it ran, but didn't hotpatch)

mellow flint
#

that's better anyways, since I want to point to a specific rev

mellow flint
elder heart
#

OR

#

wait

mellow flint
elder heart
mellow flint
elder heart
elder heart
#

I think it would be good to have

#

Something definitely

mellow flint
#

@idle stone for example 🙂

#

(ignore the missing video)

idle stone
#

seeing -> see

#

a -> an

idle stone
#

perf

mellow flint
#

review plz 😄

#

I just linked the rendered version for convenience

idle stone
#

ah those two typos are pre-pr

mellow flint
idle stone
mellow flint
mellow flint
idle stone
#

i haven't actually tested that but it had better work lol

#

i'll test it rq

#

seems fine

mellow flint
#

this is not quite true

idle stone
#

is it not? i'm basing it on the cargo book

#

or am i missing something else

mellow flint
#

incremental is a separate setting

#

The incremental links to the incremental setting in config.toml

#

(or -C incremental)

idle stone
#

hmm ok

#

dev build sets incremental=true and release sets incremental=false, so i guess the codegen-units defaults for the respective profiles come from there

mellow flint
#

hehehehe fair

#

Alright, I've applied all your other suggestions

#

Thanks again 🙂

elder heart
#

it's good

#

however may need to fix the recompilation issue next

#

rerunning with dx serve --hot-patch will fail

#

running after cargo clean will succeed

#

will tackle this later

#

and will do diagnostic on char count for codegen-units

mellow flint
#

Tell them I said hi lol

idle stone
#

you just have to ctrl+C and run dx serve --hot-patch again, no need to cargo clean

mellow flint
elder heart
#

You mean run again, control c and then run again?

idle stone
mellow flint
#

Yeah @idle stone I think the issue is that the already built artifacts are too long

#

So I think for this specific case, cargo clean is necessary

idle stone
#

ah i probably misread

elder heart
idle stone
#

different issue :)

mellow flint
#

It's Windows bavy

elder heart
#

wandows

idle stone
#

i read "rerunning with ..." and thought you meant pressing o or r in the CLI to re-open the app

elder heart
#

No, straight quitting

mellow flint
#

Alright, gonna do a release supporting the newest version of dx 🙂
Will bump this to version 0.2.0 because it requires installing a new version of the CLI

#

FYI @idle stone to make moving subsecond issues easier once it's split off from dx, I added the string "subsecond" to every issue I made

mellow flint
#

I think after this release I should be done for a moment with hot-patching, it works very well now for a prototype 🙂
Will update things again when there's a new dx version or a bug needs fixing or someone needs a review.
Or if there's feedback for the readme.

#

But I won't try to add new features unless someone absolutely needs them

#

(so I can finally enjoy @idle stone pause menu PRs hehe)

#

I think crates io is drunk

idle stone
#

published the macros crate first?

mellow flint
mellow flint
idle stone
#

ah

mellow flint
#

Then confirmed that that worked by publishing it again

idle stone
#

sneaky unicode lookalike characters surely

mellow flint
#

it's also on here hmm

idle stone
#

outdated readme snippet

mellow flint
#

Fixed

#

time for

while true; cargo publish; sleep 60; end
idle stone
#

stop when it succeeds 😄

#

strange issue

mellow flint
#

Oh it worked!

#

but oh heck

#

I can't publish something with a git dependency

#

💀

#

Time to update the readme

elder heart
idle stone
elder heart
#

That’s what we call CI

mellow flint
elder heart
#

ctrl+s -> save + commit + publish workflow

mellow flint
idle stone
#

yes lmao you solved it

mellow flint
#

Correction: we depend on a rev we know to be working

mellow flint
#

now we thinking like a 10x dev

idle stone
#

gotta make it actually continuous, that's still discrete

mellow flint
idle stone
#

deployment streaming

mellow flint
#

Oh hey I just found out #[hot] works for observers

#

neat

mellow flint
#

So I switched to lld, which costs me around 100 ms

#

I think that's fine

elder heart
#

continuous integration only feasible on analog computers

#

that's the conclusion reached

#

we need a crate that works like crater. it depends on every available crate in rust

elder heart
#

no way

mellow flint
#

it was a joke 😄

elder heart
#

trolled

mellow flint
#

@idle stone dynamic builds reduce patch time from 3.5 s to 1.8 s on Foxtrot for me

idle stone
mellow flint
#

So I don't think so

#

But I can check if you want

#

actually, it's a bit misleading since I used the old CLI and dep last time

#

let me check again with the new stuff in place

mellow flint
#

enabling dynamic linking still gives me a patch time of 1.6 - 1.8s

#

so the speedups are coming from somewhere else

#

🤷‍♂️

mellow flint
#

The 3.5 s were last time that I tried it with Foxtrot

quartz whale
#

Ah, I suppose my 550ms patch times are actually pretty good then 😂

#

I had a feeling that dynamic wouldn't make much difference, because I saw something about dx doing "ThinLink" which seemed to me like it was equivalent to dynamic_linking, but instead of being part of the crate configuration it's part of the build tool

#

Still worth having it enabled so that you don't get crazy compile times if you happen to use cargo r instead of dx though