uzerfcwn
Joined 3 years ago
Joined 3 years ago
I ended up using a divide-and-conquer style approach, where I 1) pruned items that weren't on the Pareto frontier individually for each slot, 2) took the two slots X and Y that had the least items after pruning and grouped them by calculating Z:={x+y|x∈X,y∈Y}, 3) pruned items that weren't on the Pareto frontier in Z, and 4) repeated steps 2-3 until there was only one group remaining, comprised of the full Pareto-optimal item builds.
This ran in a couple of seconds, as opposed to the other solutions I tried that took somewhere between minutes and years. The downside was that including set bonuses into the model took extra work.
To my understanding, reverse engineering algorithms and interfaces is not a copyright violation since those cannot be copyrighted (i.e. fair use is not relevant). However, a WoW server also distributes e.g. quest texts, which most certainly are copyrightable, since the collective of all quests is comparable to a fantasy novel.
In backend terms (which isn't really relevant in court but helps illustrate the division), every WoW server is said to have a "core" that contains the gameplay logic (netcode, movement, hit rolls, object interactions, etc.) and a "world database" (item names and stats, NPC names and stats, quests, etc.). The core might be considered a collection of clean room reverse engineered algorithms, which aren't copyrightable. However, the world database is full of copyrighted material, and a server distributing that data to clients will violate Blizzard's copyrights. You could avoid this by deleting all of Blizzard's stuff from the world database and writing your own content, but it's not relevant here since Turtle WoW didn't do that.
Nonetheless, vbezhenar's point stands because there are open source server implementations that host both the core and the database on Github, see e.g. https://github.com/cmangos/mangos-tbc and https://github.com/cmangos/tbc-db.
The ideal error handling is inferred algebraic effects like in Koka[1]. This allows you to add a call to an error-throwing function 15 layers down the stack and it's automatically propagated into the type signatures of all functions up the stack (and you can see the inferred effects with a language server or other tooling, similar to Rust's inferred types).
Consider the following Rust functions:
fn f1() -> Result<(), E1> {...}
fn f2() -> Result<(), E2> {...}
fn f3() -> Result<(), E3> {...}
fn f4() -> Result<(), E4> {f1()?; f2()?;}
fn f5() -> Result<(), E5> {f1()?; f3()?;}
fn f6() -> Result<(), E6> {f4()?; f5()?;}
Now, how do you define E4, E5 and E6? The "correct" way is to use sum types, i.e., `enum E4 {E1(E1), E2(E2)}`, `enum E5 {E1(E1), E3(E3)}` and `enum E6 {E1(E1), E2(E2), E3(E3)}` with the appropriate From traits. The problem is that this involves a ton of boilerplate even with thiserror handling some stuff like the From traits.Since this is such a massive pain, Rust programs tend to instead either define a single error enum type that has all possible errors in the crate, or just use opaque errors like the anyhow crate. The downside is that these approaches lose type information: you no longer know that a function can't return some specific error (unless it returns no errors at all, which is rare), which is ultimately not so different from those languages where you have to guard against bizarre runtime errors.
Worse yet, if f1 has to be changed such that it returns 2 new errors, then you need to go through all error types in the call stack and flatten the new errors manually into E4, E5 and E6. If you don't flatten errors, then you end up rebuilding the call stack in error types, which is a whole different can of worms.
Algebraic effects just handle all of this more conveniently. That said, an effect system like Koka's isn't viable in a systems programming language like Rust, because optimizing user-defined effects is difficult. But you could have a special compiler-blessed effect for exceptions; algebraic checked exceptions, so to speak. Rust already does this with async.
If you include practical applications inside computers and not just the physical reality, then Galois theory is the most often cited example. Galois himself was long dead when people figured out that his mathematical framework was useful for cryptography.
[1] https://hsm.stackexchange.com/questions/170/how-did-group-th...
What happens if the user presses ^O, expecting a file open dialog that could navigate to other directories? Would the dialog be somehow integrated to the OS and run with higher permissions, and then notepad is given permissions to the other directory that the user selects?
On the flip side, changing keybinds in Firefox requires forking, but the defaults aren't too bad.
I also found this 6ish years ago, when I wanted to build a table of some 100k rows from locally cached data. It was an order of magnitude faster to serialize and set innerHTML directly, rather than doing anything related to HTMLElement. The rendering time went from around 30-60 seconds with the naive createElement solution to 2-5 seconds with innerHTML.
Would be cool to see a framework doing that under the hood. Then again, I haven't needed that kind of HTML rendering performance since, so maybe the problem isn't big enough for anyone to care. Haven't tested if the performance numbers even hold up anymore.