[–] 4 points 3 months ago (4 children)

Fork zig as a side project, adopt the 6 weeks release cycle, create a roadmap with v1.0 to be released in 60 weeks, which is enough time for 3 alphas, 3 betas, and 3 release candidates.

  • source
  • [–] 1 point 3 months ago

    Yeah what I wrote was just something to get the idea out, about having a list of Allowables.

    I just fully read your code, and I like how you changed the Allowable api to have a deny and allow function instead of it being at the AllowList level. Honestly, I did not know mem::take was a function. I like how you got around cloning too.

    Also, just so you know, you come off pretty rude. Just want to make sure you know that if you're not aware.

  • source
  • parent
  • context
  • [–] 2 points 3 months ago* (1 child)

    I think you're right since a given object interacting with something else is commutative. As long as you iterate through all entities with a given set of components (all mobs against all collision borders) I'm pretty sure it doesn't matter what order you calculate them in even as long as you resolve it all by the next tick in the game world state. You're also only reading values from many places and updating one value with the variable that owns it and can mutate it.

  • source
  • parent
  • context
  • [–] 2 points 3 months ago (1 child)

    Actually, I didn't notice your use of clone() which is even worse.

    Here is what I had in mind. One can put the T: Default bound on the wrappers themselves to simplify, or add potentially expensive transformations for non-Default types.

  • source
  • parent
  • context
  • [–] 2 points 3 months ago (2 children)

    How is it a code smell? I'm pretty sure interior mutability is a well established design pattern. I'm not really familiar with the pattern you're describing using Ref/RefMut wrapping, could you show me what you mean?

    Yeah I didn't want to pour a bunch of time into wrangling borrow checker stuff for a small code snippet.

  • source
  • parent
  • context
  • [–] 2 points 3 months ago (3 children)

    Using cells in your solution is smelly, when you can simply use two transparent wrappers with Ref or RefMut access, so you have actual compile-time checking instead of janky checking at runtime (which is also not zero-cost).

    The allow/deny variants could themselves hold & or &mut references too if we are going with that route. But it all depends on the precise problem OP is having and what is the best workable solution for it looks like.

  • source
  • parent
  • context
  • [–] 2 points 3 months ago* (last edited 3 months ago) (4 children)

    Finally got around to writing the code, here's the link to the Rust playground with it. I was too lazy to do the unsafe stuff, but where I call clone in the deny and accept functions are where you'd rewrite and do unsafe magic to swap out elements without the clone overhead.

    I also tried to implement a take function (like in Option) for the Allowable enum. Transferring ownership like with take would keep you in safe land and get what you want done.

    Keep in mind I am not a game dev. I don't do cache optimizations. I have no idea how this code would function in a game context, but this is just my first idea for implementation of what you asked.

  • source
  • parent
  • context
  • [–] -1 points 3 months ago (2 children)

    I could use two &mut [T] values, built with split_at_mut, but this is unwieldy.

    This is likely to be the best option. You could wrap it in a nice interface that provides normal indexing but panics if you index the forbidden element. AI will be able to easily write that code for you.

  • source
  • [–] 6 points 3 months ago

    Does your function need to accept &mut self? If you can redesign that function just to take the slice of game objects (fn update(objs: &mut [T])) then you don't need to worry about the aliasing at all. You can pass an index as well if you want to operate on them one at a time.

    This is actually closer to the strategy you'd see with ECS. You'd operate not on individual objects, but on all relevant objects at once.

  • source
  • [–] 4 points 3 months ago* (5 children)

    What are the conditions for T to be accessed? You could potentially wrap each instance of T in an enum that has two states, Allow and Deny, where if you encounter a Deny you just don't access that one. If you have a slice of this enum where each enum owns T, you can always just swap out a Deny for an Allow or vice versa depending on how you want to do it. If you go this route, you might want to make a struct that owns the vector mutably, can return an immutable borrow to the slice, and change permissions on the slice. Now that I'm thinking about it, you can also implement a gets function on the struct that would return a Result depending on whether it was an allow or a deny. I don't think you'd need unsafe with this.

    The solution mostly depends on the context surrounding how you're managing what can access T and at what time. I can see the solution I proposed not working if you need more specific permissions than allow or deny, or if the permissions are based on the caller.

    Edit: I'm going to come back in a few hours and write code about what I mean in the first paragraph.

  • source
  • [–] 11 points 3 months ago* (3 children)

    classic. this has been a problem since the language was new.

    the problem is that Rust is designed to not have this as a use case, or rather has machinery to make this marginally safer (mutexes etc) or make it unstable (panic) or just as unsafe as C (unsafe). if this is a pattern you want to maintain, Rust is going to throw friction at you by design, because tbh this pattern is the source of a ton of bugs.

    it’s conceptually more complicated, but game engine devs have been moving to some form of Entity Component System[1] architecture, because it gives you a way to access memory that is both cache efficient and safe.

    all that said i’m not a game dev. i think Bevy[2] was the blessed solution for a while?

    1: https://en.wikipedia.org/wiki/Entity_component_system?wprov=sfti1 2: https://bevy.org/

  • source
  • [–] 2 points 3 months ago

    Can you clarify/expand on what you mean.
    Are the other objects of the same type (so are indeed Self)? Are they in the same Vec or a different Vec or from different Vecs?
    Are all the T's in your post the same?
    ...etc

  • source
  • [–] 2 points 3 months ago* (1 child)

    I will say that using a super efficient cloud model (deepseek for me, v4 flash is very cheap) is probably more efficient than using a local model in most cases, especially if you need strong capabilities. The question is whether your own grid or the provider's grid is more environmentally friendly (hint: china's energy mix is about 50% fossil fuels while the US's mix is around 75% fossil fuels overall)

    Training is of course expensive still, but Chinese labs have all but caught up to US labs despite much lower compute resources being available to them.

  • source
  • parent
  • context
  • [–] [S] 1 point 3 months ago (1 child)

    No, and I do understand that training is the most energy-intensive part of the process. I don't know how exactly it divides up: how much of the work of massive data centres is training and how much is running people's queries on finished models.

  • source
  • parent
  • context
  • [–] 3 points 3 months ago

    The existing local models already exist, and new releases will happen because the companies want to sell you inference. They receive no profit or incentive to release the models as open weights but they do it anyway - There is no coherent ethical delimma against using them locally, as it has no effect on whether the companies will or will not be encouraged to do more training.

  • source
  • parent
  • context
  • view more: ‹ prev next ›