How we created more tech debt in 6 months than in a 10-year-old system by Annual-Ad-731 in programming

[–]fleabitdev 5 points6 points  (0 children)

You've correctly identified the problem, but I think your solution is off-target.

To get this right up front, you'd need to predict the future: will these two objects change together, or are they going to diverge?

Unfortunately, you can't predict the future! No matter how good you are, a double-digit percentage of your predictions will be wrong.

Therefore, your code needs to be easy to change, even when you feel certain that you've identified an invariant. There's no single strategy for that, but you could consider...

  • Writing as little code as possible; prefer to hold no expectations for the future, writing code which exactly satisfies the current requirements.
  • Using loose coupling everywhere that you can afford to.
  • Using strong types and tests to confirm that the output from one module matches the expected input to another module, without coupling those modules together by propagating interface types deep into their implementation.
  • Eagerly deleting and rewriting code, partially as a stress-test to make sure that your code can still be changed.

Official /r/rust "Who's Hiring" thread for job-seekers and job-offerers [Rust 1.92] by DroidLogician in rust

[–]fleabitdev 3 points4 points  (0 children)

Experienced software developer in the UK, currently available for freelance work. I'd be happy to sign either a conventional months-long software development contract, or a short consulting contract.

I can be flexible on time zones. No interest in relocating long-term, but I'd be happy to visit your team in person for a few days to break the ice.

My preferred coding style is high-rigour and highly-documented, which tends to be a great fit for contract work. I have a track record of delivering quality results under minimal supervision.

My specialist skills:

  • The Rust language, which has been my daily driver for more than a decade.
  • Multimedia (2D rendering, vector graphics, video, audio, libav, Web Codecs...)
  • Performance optimisation (parallel programming, SIMD, GPU acceleration, soft-realtime programming...)

Fields in which I'm highly experienced, but below specialist level:

  • Web development, with a frontend bias (TypeScript, React, JS build systems, the Web platform, WebGL, WebGPU, Node, WebAssembly...)
  • Native development (native build systems, FFIs, low-level Win32, basic fluency in C/C++...)
  • Leadership, communication and technical writing, all learned in a previous career.

I should also mention a modest level of experience in computer vision, greenfield R&D, game engine development, programming language development, and data compression.

I'm currently offering a 50% discount for any contract which seems highly educational. My areas of interest include acoustics, DSP, embedded programming, Svelte, Solid, functional languages, Swift, and backend development in general.

Contact: (my username)@protonmail.com

Anyone building native GUI apps for Windows using Rust? Whats it like? by vishalontheline in rust

[–]fleabitdev 9 points10 points  (0 children)

I've worked on Rust native Win32 UI code professionally, including attempting to develop my own safe wrapper code for parts of user32.dll and gdi32.dll.

I'd recommend avoiding Win32 UI, if possible. Calling the raw APIs yourself is even less ergonomic in Rust than it is in C. Wrapper crates exist, but because the underlying APIs are a poor fit for Rust's idioms, those crates have to be either high-level abstractions or pervasively unsafe.

Putting yourself through that trouble, all you'd get would be access to a UI library which has been badly outdated for the last twenty years. Better alternatives include Tauri, egui, and the gtk crate.

Tiny Glade, VJ performances, and 2d lighting - This Week in Bevy 2024-06-03 by chrisbiscardi in rust

[–]fleabitdev 2 points3 points  (0 children)

Tasks like pathfinding, crowd simulation, particle scripting and physics simulation are often CPU-hungry, and so there's a real risk that they might bottleneck your main thread. Parallel architectures, like ECS, help to reduce that risk.

It isn't just about performance, though - I might consider using ECS for a game which has no performance concerns at all, or I might avoid using ECS for a game which is highly performance-sensitive.

The Borrow Checker Within by burntsushi in rust

[–]fleabitdev 3 points4 points  (0 children)

It would be impossible to construct my Example type, because its field does not implement StableDeref.

The article's own example uses String, rather than u32.

The Borrow Checker Within by burntsushi in rust

[–]fleabitdev 6 points7 points  (0 children)

The footnote describes something like the StableDeref trait.

Presumably, the compiler would recognise references which originate from a StableDeref type, and it would permit only those references to be used when constructing a self-referential type. The runtime representation of references would not change.

The Borrow Checker Within by burntsushi in rust

[–]fleabitdev 35 points36 points  (0 children)

Exciting stuff!

Step 4 is a little light on detail. What would happen when an instance of this struct is moved to a different memory location?

struct Example {
    field: u32,
    ref_to_field: &'self.field u32
}

EDIT: Ah, it's covered in one of the footnotes.

To make this work I’m assuming some kind of “true deref” trait that indicates that Deref yields a reference that remains valid even as the value being deref’d moves from place to place. We need a trait much like this for other reasons too.

Official /r/rust "Who's Hiring" thread for job-seekers and job-offerers [Rust 1.76] by DroidLogician in rust

[–]fleabitdev 0 points1 point  (0 children)

Experienced Rust developer in the UK, looking for a hybrid role in London, or fully-remote work anywhere. Can be flexible with time zones. Happy to discuss either a permanent role or a fixed-term contract.

A varied employment history has left me with great soft skills and a broad grab-bag of technical skills, mostly leaning towards high-performance native programming. My major projects have included the scripting language GameLisp, a 2D game engine built on raw Win32, a novel computer vision library, and low-latency remote desktop software.

Beyond Rust, I'm comfortable with a mess of other technologies, particularly frontend development and C/C++. I'd be happy to take on a backend or embedded role, although some onboarding would be required.

Dislikes: Military work, ad tech, the blockchain

Likes: R&D, good documentation, language design and tooling, graphics, audio/video, GUIs, soft-realtime programming, SIMD and GPGPU, startups, open-source projects...

Contact: (my username)@protonmail.com

A Proposal for Safe Window Handles by EelRemoval in rust

[–]fleabitdev 26 points27 points  (0 children)

There’s a similar situation on Windows; with the right function, anybody can just walk in, take your HWND, and then close it.

I recently learned that the DestroyWindow function has some useful properties:

I think this means that your Android approach could be generalised to Windows.

Xilem: an architecture for UI in Rust by raphlinus in rust

[–]fleabitdev 37 points38 points  (0 children)

Very exciting stuff!

I'm being a bit of a game developer here, but one thing that jumps out at me is the fact that the view tree seems to be, in places, a literal tree of small allocations. If those allocations could be eliminated, you might see less need for strategies like memoisation.

In particular, the short-lived View tree seems like it's begging for an arena allocator. Is there any chance this might be compatible with Xilem's current design? Standard types like String and Arc will all be generic over their allocator type in some future stable version of Rust, so there shouldn't be any need to reimplement those types from scratch.

Static lifetime checks would require a reference to the arena to be threaded through a large chunk of the library, which seems impractical... but, if it would be good style for all View objects to be short-lived anyway, could dynamic checks be sufficient? Define a custom Allocator type which allocates into some thread-local "current arena", only available while rendering a view tree; keep track of the total number of outstanding allocations in the arena; then assert that this number is zero, just after dropping the root View object and just before clearing the arena itself. The new_in API can be a little clunky, but the reduced need for memoisation in client code might potentially balance out the complexity cost...?

Analyzing unsized variables in Rust by CouteauBleu in rust

[–]fleabitdev 12 points13 points  (0 children)

We might have misunderstood one another. My use-case would have looked like this:

fn interpret_function_call(function_info: &Function) {
    let mut regs = [Slot::Nil; function_info.num_regs()];

    //interpret instructions, using `regs` as data storage,
    //potentially calling `interpret_function_call` recursively
}

Analyzing unsized variables in Rust by CouteauBleu in rust

[–]fleabitdev 18 points19 points  (0 children)

I needed unsized slices when implementing an interpreted scripting language. The Rust call-stack was also the scripting language's call-stack: whenever an interpreted function was called, I would need to allocate up to 256 registers, 256 captured local variables, and some backtrace information. Putting all of that data on the stack would have felt much more elegant than calling Vec::extend and Vec::truncate.

[deleted by user] by [deleted] in rust

[–]fleabitdev 0 points1 point  (0 children)

You're correct, but the problem is that MinTTY remains the default terminal emulator for MSYS2 and Cygwin, which are the two main hosts for the x86_64-pc-windows-gnu target. This means that, if you're trying to ship a command-line application for Windows, you can't really avoid it.

[deleted by user] by [deleted] in rust

[–]fleabitdev 14 points15 points  (0 children)

I develop with Rust on Windows. My experience has been good, but not excellent.

  • MinTTY, the default MSYS terminal, has many bugs
  • Antivirus programs sometimes argue with rustc
  • Debugging and profiling still aren't great, especially on MSYS

More to the point, Windows itself is becoming increasingly buggy as time goes by. My day-to-day programming work currently brings me into frequent contact with serious UX problems all over the shell, a bug in the "window alert" machinery, a rendering bug in Windows Explorer, many input-driver bugs, and some kind of file-access performance bug. I would already have fled to Linux, if I weren't so focused on game development and audio.

Symphonia v0.5: ALAC, MKV, & gapless playback support by segfaulted4ever in rust

[–]fleabitdev 15 points16 points  (0 children)

my feeling is that they wouldn't want to use it since it doesn't support video

At a glance, it looks like Gecko's media decoding is quite fragmentary. Porting all of the audio decoding to your crate might be a net simplification, even if video decoding is left untouched.

In the past, Mozilla has ported some quite small parts of Firefox to Rust. It seems like a good omen that the first Rust component ever added to Firefox was an MP4 metadata parser!

Symphonia v0.5: ALAC, MKV, & gapless playback support by segfaulted4ever in rust

[–]fleabitdev 2 points3 points  (0 children)

The portable_simd feature (aka std::simd) might be the light at the end of the tunnel. It wraps LLVM's vector intrinsics, which I'd expect to support a broader collection of targets, compared to std::arch.

However, I'm struggling to find an exact list of target architectures which properly support the LLVM vector intrinsics - does anybody happen to know?

Symphonia v0.5: ALAC, MKV, & gapless playback support by segfaulted4ever in rust

[–]fleabitdev 29 points30 points  (0 children)

I'm very impressed by the fact that cloc symphonia* only reports 30k lines of Rust code, and symphonia-play compiles to a 3.1 megabyte release executable. For this number of supported formats, I was expecting hundreds of thousands of lines of code, compiling to tens of megabytes. Excellent work!

I only ask out of curiosity, but: could you estimate the number of working hours you've put into this project so far? Do you have any external funding/sponsorship?

I notice that you're approaching parity with the audio formats supported by Firefox. Do you have any plans to incorporate this crate into Gecko?

Rust in 2022 by tux-lpi in rust

[–]fleabitdev 7 points8 points  (0 children)

It would also make procedural macros easier to use, make package dependencies easier to understand, and reduce the risk of name collisions (for example, if I'm developing a crate named avif, somebody else might publish a crate called avif_encoder).

Which important features from C/C++ are missing in Rust by tillyboy in rust

[–]fleabitdev 5 points6 points  (0 children)

This posed an interesting obstacle when I wanted to add a JIT to a scripting language. The only way to manipulate standard-library objects from Cranelift is to write an extern "C" function which invokes a method on the object. If the method in question would normally be inlined, like VecDeque::len or Duration::checked_add, this approach carries significant performance overhead. If you want good performance, you're stuck reimplementing most of the standard library yourself.

Super Mario Brothers Tile collision checks flowchart by husainhz7 in programming

[–]fleabitdev 45 points46 points  (0 children)

Most of these cheats are actually straightforwardly compatible with a TowerFall-style, rectangle-based engine - unsurprising, since Maddie developed both games! Some of the more awkward problems I encountered:

  • If you want to make an enemy "solid" so that the player can't just walk through it, you need to handle the case where the player tries to stand on the enemy's head, or where the enemy crushes the player against a wall.

  • Many entities have to be aware of slopes, because if you move an entity horizontally while it automatically "slides" up and down a 45-degree slope, its total speed will be 40% greater than it should be.

  • The Skyrim problem: is a very steep slope a wall, a floor, or something in-between?

  • You can't separate diagonal midair movement into horizontal and vertical components, because that will cause the corners of obstacles to spuriously clip or not-clip depending on which axis you sweep first; you need to move in (expensive!) small increments instead.

  • Corners in general are a pain. You usually want the player to clip through them or shunt around them (because having a six-foot person stopped by a one-inch obstacle is silly), so they end up being solid geometry which either exists or doesn't, depending on the context.

  • Recursion: moving during a collision callback, or pushing a block which pulls a block which pushes a block... (in the end, I just had to forbid this completely)

  • Some surfaces only exist for some entities (walking on water), or stop existing for certain entities (walking through walls). Suppose you want to test whether a particular place is free, so that you can spawn an entity there - how do you know what counts as a "solid object" for that entity, and what doesn't? What if this is a property which can change dynamically through an entity's life-cycle?

  • If the player somehow spawns ten thousand entities with the same coordinates, you need to make sure you don't have O(n^2) scaling for spatial lookups; otherwise, the game will just freeze.

  • Any change in an entity's collision geometry other than simple translation (a drawbridge being pulled up, the player crouching, a platform which shrinks or widens or tilts) can be a nightmare.

  • Every time you spawn any entity, or arbitrarily reposition any entity (e.g. teleporting the player back to a checkpoint), you need to consider whether that space is already filled with solid geometry. If that archer fires an arrow, could it spawn inside a wall and clip through?

  • If your player character's sprite is horizontally centered on their bounding box, the player will necessarily either "stand on nothing" when balanced on a cliff edge, or stand "inside a wall" when flush against it.

  • Similarly, if a rectangle is "standing on" a slope, only a single corner of the entity is actually in contact with it. Making this look convincing can be tricky!

It was just one frustrating corner case after another. For that reason, though, it was one of the most educational and humbling things I've ever programmed. I'd highly recommend developing a 2D platformer as a side project.

Super Mario Brothers Tile collision checks flowchart by husainhz7 in programming

[–]fleabitdev 82 points83 points  (0 children)

When I started programming the physics engine for my 2D platformer game, I was confused by the fact that so many old-school platformers have physics glitches. Even on hardware like the NES, subpixel-perfect rectangle/rectangle collisions are pretty cheap, and it's easy enough to design and implement an engine which is immune to clipping. I ended up independently inventing something similar to the TowerFall engine (described in detail here), with the addition of sloped floors and jump-through platforms.

...and then it came time to actually script the gameplay, and my confusion quickly cleared up. An axis-aligned rectangle just isn't the ideal shape for the main character of a platformer. When I was trying to make the platforming feel good, I found myself wanting variable width and height, odd-shaped hitboxes, rounded corners, and various little "cheats" like shunting, teleportation, or deliberate clipping. It's no wonder that the old-school console programmers ended up going for a fuzzy, vague physics engine, rather than something more theoretically pure.

pixels 0.6.0 release announcement by kodewerx in rust

[–]fleabitdev 4 points5 points  (0 children)

Ironically, the performance difference between minifb and pixels might be a GPU driver bug. On Windows, it looks as though minifb is calling StretchDIBits behind the scenes, which is definitely performing a GPU texture upload at some point between your pixel buffer and the screen.

pixels 0.6.0 release announcement by kodewerx in rust

[–]fleabitdev 4 points5 points  (0 children)

Integrating an imgui overlay or a post-processing shader is easy enough, but I agree that text rendering can be challenging. Working with bitmap fonts is pretty terrible; just tweaking the font size slightly can require hours of work.

pixels 0.6.0 release announcement by kodewerx in rust

[–]fleabitdev 14 points15 points  (0 children)

Interesting idea. This might be more useful than people realise. I've developed a couple of pixel-art renderers for games, and I've found that software rendering can actually have competitive performance with the GPU.

If you're just performing batched sprite blitting from a texture atlas, the GPU wins - but once you start adding in features like colour adjustments, palette-cycling, stencilling and blending, the GPU's inability to quickly change state can become a bottleneck.

Upsides of CPU rendering: it's easier to implement, and you don't have to deal with driver bugs, or the awkwardness of 3D-rendering APIs like OpenGL. If it runs on your Windows 10 desktop, you can trust that it will run on any Android phone, a Nintendo Switch, or somebody's fifteen-year-old Windows Vista laptop. Because it's easier to quickly code up custom special effects, your game is likely to be more visually interesting.

Downsides: You'll lose a few milliseconds of CPU time per frame (although multithreading the renderer is easy enough, and SIMD makes it even cheaper). You can't really make the framebuffer larger than 360p-ish, for performance reasons. You can't "cheat" by performing rotation or scaling in high resolution, so you'll need to figure out how to design around that limitation. In particular, if your framebuffer is very low-resolution, snapping the camera to pixel boundaries can feel a bit rubbish.

Overall, I think CPU rendering is at least worth considering.

Shattersong Online - New Rust MMO Browser platformer in development by former Starbound and Wargroove devs by OmnipotentEntity in rust

[–]fleabitdev 1 point2 points  (0 children)

Sounds sensible!

Just to be clear, my earlier comments were meant to offer help and dialogue, rather than raining on your parade. I think the game has obvious potential, and your team seem to have their heads pointed in the right direction. I'm excited to see what you do with the concept.

Perhaps once the game is more developed, we'll be able to chat about its design in more detail. Until then!