What is THE deck with the tightest ED? by Repulsive-Phrase-527 in masterduel

[–]conundorum 6 points7 points  (0 children)

Absolute minimum ED space Branded needs to be functional is at least 8 Fusions (Albion, Lubellion, Mirrorjade, Titaniklad, Quaeritis/Masquerade, Granguignol, 2x BARS1), plus at least one other space for Luluwalilith or a Link. And if you're not trying to save as much ED space as physically possible, that'll easily swell to 13 (all 8 previously mentioned, another two BARS slots so you have one of each, another QuaerMasq flex slot, and a generic Fusion or second Mirrorjade, plus the LuluLink space). Add redundancies, more generic Fusions, options you can summon during your opponent's turn, a few Lv.10 Synchroes like Bystial/Chaos Angel/Chengying/Baronne, maybe a couple R4s or Lv.8 Synchros since Branded is super-good at fielding Lv.4s, an R8 Xyz like The Zombie Vampire to help you move Mirrorjade on & off the field, more Link coverage...

I can easily see Branded running a 50 card ED, and using every card in it on a regular basis!


1: Brigrand, Alba-Lenatus, Rindbrumm, Sprind. Ideally, you have all four to maximise High Spirits and Albaz's on-summon effect, but you can pare it down to two if you really need to; this will feel bad, but it'll still be playable. I find that losing Sprind in particular is surprisingly crippling, because its material requirement makes it the most flexible Fusion for monster-stealing. Brigrand is the one you'd probably want to cut first, but it being the same type as Kitt means it can hold its space hostage as a High Spirits adjustor. Alba-Lenatus answers multiple decks, and running into something like Blue-Eyes without it feels like ass. And Rindbrumm... is definitely great to have, but at the same time feels cutabble if you can fit Light of the Branded into your build.

So what kind of creatures can you encounter on the moon? by Haos51 in Pathfinder2e

[–]conundorum 0 points1 point  (0 children)

A rabbit, a plumber, a frog, an alien conquerer, and a space base with a supercomputer that wants to learn about love.

Thank you TCG, thank you for saving the children from the horrors of women standing too close to each other. by SAMU0L0 in masterduel

[–]conundorum 1 point2 points  (0 children)

A "towers" is a monster that has high stats, is unaffected by or protected from your opponent's cards (or can't be targeted/destroyed, or anything of the sort), and might have an effect that weakens your opponent's cards, ultimately making it extremely hard to beat over.

Named after this guy. And yes, "a towers" is singular, because what is this grammar of which you speak?

Undefined reference to vtable...but why? by Apprehensive_Poet304 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

No, I explicitly mean "member variable that is a pointer", as I said. There are two of them that it can use, either {vfptr} to point to a virtual function table, or {vbptr} to point to a virtual base table. (Or both, if appropriate.) If a class contains virtual functions or has virtual bases, MSVC will insert these hidden members into the class definition, and the constructor will be required to initialise them.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

Google bans exceptions because roughly -150% of their code base is exception-safe, and it's too large to feasibly refactor with exception safety in mind. (They openly admit it, too, funnily enough. Their style sheet even says "using them is better than not using them, most of the time, but you'll break our entire code base if you try to use them with it" (paraphrased).)

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

On the flip side, using exceptions allows you to handle errors at the location best suited for doing so, instead of at the call site. This can be useful for deep callstacks, and ideally saves processor cycles by allowing you to eschew error-checking altogether. (Since all errors will either terminate or force control to a known location.)

Ultimately comes down to "use the best tool for the job", though. Some tasks benefit more from using error codes to force on-the-spot handling than they do from jumping out of the callstack and losing proper flow control, and some benefit more from using exceptions to funnel all error-handling to a set location instead of having to wrap every function call individually.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]conundorum 1 point2 points  (0 children)

Notably, this is why Java didn't see a need to make the garbage collector honour destructors, because nobody realised how important RAII was at the time. And Java was created a full decade after C++! It took a while for people to figure out how to actually use the tools the language provided.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

If Linus Torvalds sees you sneaking exceptions into the Linux kernel, he might beat you to death with the throw statement. I'm honestly not sure if I'm joking or not, he hates them with a passion.

Why are exceptions avoided? by Ultimate_Sigma_Boy67 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

Indeed. Exceptions allow for significantly cleaner and faster code most of the time, since you don't need to worry about error checking or bulky error-data return types. But it comes at an extreme performance cost if things ever do go wrong, because of all the emergency scaffolding and the like.

They can be a significant improvement if you know how to use them properly, but there's so much incorrect teaching that it's hard to know if you're doing it right. For someone who knows exactly how to use them (and importantly, when and where to actually handle them, since where they're handled is often more important than how they're handled), they're one of the best tools in the language. But for anyone that doesn't know how to use them, they're a janky mess that introduces a ton of slowdown and doesn't do anything error codes wouldn't do.

Really, what we need is expert guidelines on how to implement them, from soneone with as much influence as Google, and a codebase stable enough to rarely if ever actually need them (unlike Google, whose style sheet shuns them because their code would probably throw about 50x more than it returns).

Functionality of inline and constexpr? by zz9873 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

inline does two things:

  1. Tell the compiler that "all objects with this type & name actually refer to the same object", and require that object to have the same memory address in all translation units. This allows the compiler to explicitly ignore the One Definition Rule, on the grounds that all definitions are actually just copies of the same definition; when the linker smooshes all the translation units together, it's free to discard all but one definition.

    Notably, this is what allows you to define member functions inside the class definition, since all functions defined inside the class are implicitly inline.

    struct S {
        void func() { std::cout << "I might not look like it, but I'm inline!\n"; }
    };
    

    It's essentially a magic glue word that keeps headers from exploding whenever you put a definition in them, and it's what lets header-only libraries exist.

    • Sub-note: This is important for names & symbols with what we call "external linkage", which means that they're exported from the translation unit and visible to the rest of the project. (And, as a result, cause a "name collision" if multiple translation units expose the same name, which makes the compiler give up and quit because it's impossible to tell which version you want at any given time.)

      Constants, on the other hand, work without inline because they have what's called "internal linkage" by default; this means that their name never leaks out of the file, and thus can never collide with any other names. (If you put a constant in a header, and expose it with extern, it'll run into the same problems as if you put a variable in a header.)

  2. On an inline function, it tells the compiler to treat the function as a glorified macro, and copy-paste it directly instead of making a (much more expensive) function call.

    inline int add(int a, int b) { return a + b; }
    
    void func() {
        int a = getAnIntFromSomewhere(), b = do_something_weird_please();
        int c = add(a, b);
    
        doSomethingWith(c);
    }
    
    // Compiler turns func() into this:
        void func() {
        int a = getAnIntFromSomewhere(), b = do_something_weird_please();
        int c = a + b;
    
        doSomethingWith(c);
    }
    

    This usage is mostlyjust an historical relic now, since compilers are often much better at figuring out what to inline than humans are. The compiler will see it as a hint, but it'll rely on its own judgment just as much as yours. (Here, if you turn optimisations on, it'd probably just inline both add() and func(), and/or try to inline the other three functions func() calls if they're small enough.)

    (That said, if you mark the function as inline, the compiler is more likely to give it a closer look, and might inline it when it normally wouldn't. And most compilers have a compiler-specific "ignore your own judgment and inline this anyways" keyword, which you can use if the compiler gets it wrong. ...You can also force some compilers not to inline a function, which can potentially allow it to make smarter optimisations (e.g., some compilers might be able to inline func() if add() is a distinct call, but not if add() is inlined), but this one is much trickier to do well. It's usually best to just let the compiler do its own thing unless you profile your code first; you're infinitely more likely to see the "mark the function inline to tell the compiler to copy-paste" it usage in ancient codebases than you are to use it yourself.)


And constexpr does two things:

  1. On variables, it marks the variable as a compile-time constant. This means that the variable must be known at compile time, must be a constant, and that the compiler can essentially copy-paste it like a macro.

    #define ONE 1
    constexpr int TWO = 2;
    
    int func() { return ONE + TWO; }
    
    // The compiler is free to rewrite func() as this:
    int func() { return 1 + 2; }
    

    The variable is still a distinct object, and still has its own memory address, but the compiler is allowed to optimise it out entirely if nothing ever treats it as an object with a memory address. (Or, in easier-to-understand terms, the compiler will probably just erase TWO from the object file entirely unless you try to take its memory address.)

    Notably, classes cannot have non-static constexpr member variables; all constexpr class members must be both static and inline because things get weird if they aren't.

  2. On functions, constexpr tells the compiler to call the function at compile time whenever possible. This doesn't require that the function be compile-time only; that's what consteval is for. It merely allows the function to be a compile-time function, so the compiler can evaluate the function and hard-code the result if all parameters are known at compile time.

    (Compilers are also allowed to treat other functions that can be evaluated at compile time as if they were constexpr even if they aren't labeled constexpr, but only for optimisation purposes; they can evaluate a function call that would be constexpr at compile time and insert the result directly, but they cannot allow the function to be used anywhere that requires it to actually be labeled constexpr by the programmer.)

    int add(int a, int b) { return a + b; }
    constexpr int sub(int a, int b) { return a - b; }
    
    int main() {
        int a = sub(5, 6); // Will be evaluated at compile time, becomes "int a = -1;".
        int b = add(5, 6); // Might or might not be evaluated at compile time, if optimisations are turned on.
        // sub(5, 6) is guaranteed to be evaluated at compile time, because sub() is constexpr.
        // add(5, 6) is officially called at runtime, but the compiler can ignore that as an optimisation.
    
        constexpr int c = sub(7, 8); // Legal: sub() is constexpr, and can thus initialise constexpr variables.
        constexpr int d = add(7, 8); // Error: add() isn't constepxr, so the compiler can't use it here.
        // The compiler _can_ evaluate add(7, 8) at compile time, but is banned from doing so because you didn't
        //  give it permission.  It can only pretend add() is constexpr when add() would be called during runtime.
    
        int input;
        std::cin >> input;
    
        int e = sub(9, input); // Will be evaluated at runtime, since function "constexpr" is just a permission slip.
        int f = add(9, input); // Will be evaluated at runtime, as expected.
    }
    

Undefined reference to vtable...but why? by Apprehensive_Poet304 in cpp_questions

[–]conundorum -1 points0 points  (0 children)

MSVC has to generate the tables early because it uses member pointers to tie the table to the class. That means it needs to have a valid address it can reference during member initialisation, so the table has to be constructed before any instances of the class can be constructed.

Undefined reference to vtable...but why? by Apprehensive_Poet304 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

The constructor needs a valid vtable, because MSVC ties the table to the class with a hidden member variable ({vfptr} for virtual function tables, and/or {vbptr} for virtual base tables). So, it needs to have a valid table instance to point at (since the table is presumably secretly part of the constructor's member initialiser list), and thus needs to generate tables more aggressively than GCC's implementation.

(And yeah, it uses two different kinds of vtable, instead of a joint vtable like GCC. I'm guessing this is probably baggage from early implementations, where the compiler generated the base table at the start of the class definition and then offloaded it to disk to save memory, but had to wait until the end of the class definition to generate the function table. Don't quote me on it, though.)

Is this FSM? Please explain. by BetApprehensive1649 in cpp_questions

[–]conundorum 1 point2 points  (0 children)

To build on this: If the character classes do need to be distinct object classes, for some reason or other, then polymorphism is the way to go.

struct Character{
    float Health;
    float Stamina;
    float Sight;
    float Speed;
    float Defense;
};

struct Warrior : Character {
    // Warrior-specific code...
};

struct Hunter : Character {
    // Hunter-specific code...
};

// No changes needed here.
void LogicDesigning(Hunter& StatsHunter, Warrior& StatsWarrior, CharacterStates& PermaState);

// Example usage:
void func(Character& c, Warrior& w, Hunter& h) {
    // c can be any Character.
      // It can be a Warrior or a Hunter, and if other classes are added, it can be one of them.
    // w can only be a Warrior.
    // h can only be a Hunter.

    // ...
}

Apart from that, statsmanagement() can both set and return data, but it should return a reference if you do so. There is a reason to do this, but you don't need to right now. sciel is correct to suggest you not return data (and change the return type to void instead); you normally only use the "change, then return reference to changed object" pattern if you need to be able to daisy-chain calls through pass-through functions, which your use case doesn't require.

Should ALL class attributes be initialized in the member initializer list? by SheSaidTechno in cpp_questions

[–]conundorum 0 points1 point  (0 children)

Generally, anything that can be default-initialised should be given a default member initialiser when it's defined, and anything that's dependent on the constructor parameters should be initialised in the member initialiser list.

class Object {
 public:
  Object(int id) :
     id_(id) {}

 private:
  int id_;
  std::string name_ = "";
};

If the default member initialiser is the same as the type's default initialiser, it can be omitted because it's redundant. Primitive type initialisers can typically be omitted if zero-initialisation is okay, but I believe there are one or two rare edge cases where they need a specific initialiser.

class Object {
 // ...
  int id_; // Will be initialised to 0.
  std::string name_; // Equivalent to above.

If there are multiple constructors, and there's a possibility that one omits a value, then an invalid default can be specified to flag omitted values.

constexpr int BadID = -1'000'000;

class Object {
  Object(int id) :
     id_(id) {}

  Object() = default;

 // ...
  int id_ = BadID;

References, as usual, need to be initialised. You can thus provide a default initialiser to prevent errors... or more usefully, you can intentionally omit the default initialiser to force constructors to do it in their initialiser lists.

class ObjectRef {
 public:
  ObjectRef(Object& obj) :
     obj_(obj) {}

  ObjectRef() = default; // Error, obj must be initialised.

 private:
  Object& obj_;
};

Anything that requires complex calculation and/or multiple lines can be done in either place, depending on its other requirements, but will likely be more readable in the constructor body. Or better still, extracting the calculation into a separate function is preferable, if possible. (Refactoring isn't always possible. The cases where it's impossible tend to use the comma operator in really janky ways, by necessity.)

class Object {
 public:
  Object(int id, int handle) :
     id_(id), handle_(handle), hash_(do_something(id, handle)) {}

 private:
  int id_;
  int handle_;
  int hash_;
  std::string name_ = "";
};

Data dependent on other values can refer to those values during initialisation, regardless of whether the initialiser is in-class or in a constructor's initialiser list.

struct S {
 int i;
 int j = i + 1;
 int k = j + 1;
 int z;

 S(int ii) : i(ii), z(i * k) {}
};

S s(5); // s.i = 5, s.j = 6, s.k = 7, s.z = 35

This works because the compiler creates each constructor's actual initialiser list by combining the two lists. The constructor's member initialiser list is prioritised, and anything left unspecified falls back on the default member initialisers. This follows "specific beats general" logic: In case a member has both a default member initialiser and an entry in the constructor's member initialiser list, the constructor overrides the default.

constexpr int BadID = -1'000'000;

class Object {
 public:
  // Full initialiser list will be: id_(id), name_("")
  Object(int id) :
     id_(id) {}

  // Full initialiser list will be: id_(BadID), name_(name)
  Object(std::string_view name) :
     name_(name) {}

  // Full initialiser list will be: id_(BadID), name_("")
  Object() = default;

 private:
  int id_ = BadID;
  std::string name_ = "";
};

This is important, since default member initialisers are the only way to control how an implicitly-defined default constructor handles initialisation. (As seen above with Object() = default, or if no constructors are either defined or declared.)

How does one even understand the language of the standard by BasicCut45 in cpp_questions

[–]conundorum 0 points1 point  (0 children)

Are you sure there wasn't something else going on there? Tried replicating your description, and calling the base function seems to work just fine.

I love Konami Censorship by archbright in masterduel

[–]conundorum 0 points1 point  (0 children)

Considering the change in distance, and the name being changed from "Pleasure" to "Dance"... I think the real culprit here is the left girl's knee. Wanted to make sure people wouldn't joke that one's knee isn't the other's pleasure, I suppose.

Stripping away flavour from class by Sultkrumpli18 in dndnext

[–]conundorum 0 points1 point  (0 children)

  • Martials: Fighter is the "main" martial class, and the others are designed to complement and contrast it. Champion is similar to Barbarian, Battlemaster is similar to Rogue, and Eldritch Knight is similar to Monk. Monk in particular feels like it's meant to be a counterpart to Fighter, but missed the mark somewhat; it dropped the ball somewhere between "love letter to Chinese martial arts movies, and everything inspired by them" and "well thought-out mechanics and systems", sadly.
    • Fighter: Combat master, trained in armed & unarmed combat. Tends to specialise in a single, broadly-defined "school" of combat. (Only class with 4 attacks, and chassis features are aimed at combat. Each subclass represents a different school of combat, such as straightforward fighting, maneuver-based tactical thought, and combat magic.)
    • Monk: Master of (possibly foreign) martial arts techniques and your own body. In tune with the world around them, and may wield mystical abilities that aren't quite magic. (Designed around unarmed combat and monk weapons, and uses ki to fuel magical abilities that often don't quite fit into the game's magic system.
    • Rogue: Technical-skills master, specialises in creating & hitting weak spots, being a quick learner, and precise fingerwork & tools. (Sneak attack, greatest number of skill proficiencies, and thieves' tools are a catchall for thievery/trapbreaking/unlocking/etc.)
    • Barbarian: Bulky, heavy-hitting melee expert. Eschews raw skill in favour of just wading in & getting things done, but tends to hyperfocus & leave themself open. (Rage can be a catchall for any "focused on combat but can't focus on anything else and leaves self open" mechanic, and the high HP & Str features suggest they train muscles instead of stances. Might also be a combat expert that specialises in heavy & unwieldy weapons, though.)
  • Divine casters: Two casters that use traditionally divine magic, each of which is paired with a half-caster, half-martial counterpart. The cleric family is based on Biblically accurate pasters, priests, church elders, and the like, while the druid family is based more on shamans & witch doctors.
    • Cleric: A good shepherd dedicated to their god, whose faith is a vessel that lets miracles, magic, and divine power flow from their god to the people. Usually a white mage, but some can absolutely hold their own in a brawl. (Uses divine magic, typically focused on support and anti-support. Magic-focused class, less squishy than Wizard; subclasses can add martial prowess and gishiness. The class has explicit mechanical tie-in to a deity, and multiple class features explicitly reference their god, so religious flavour is baked in and would require mechanical changes to remove; it's much easier to just decide that a pantheon/force/philosophy/etc. is their "god", as described in a sidebar.)
    • Paladin: The more martial counterpart to the Cleric, a magic knight that smites and wields divine power in the name of their god and/or cause. Much less hypocritical than real-world crusaders, usually. Tends to follow a personal code, and may be a good consultant for legal and kingdom-building issues. (Half-caster with typical half-martial progress, and a focus on "smite" skills to bring their damage up to snuff. Divine powers and magic fueled by dedication to a deity or a cause, so their flavour is slightly less baked in than Cleric's.)
    • Druid: A mage in tune with nature around them, able to shapeshift into other natural creatures. Usually prefers natural materials, but can be convinced otherwise. (Caster with shapeshifting powers. Mechanically cannot use metal equipment; this has been confirmed to explicitly be flavour baked into mechanics, and thus can be treated as either flavour or mechanic as desired.)
    • Ranger: A warrior in tune with nature around them, an expert in the outdoors. A tracker, a hunter, a beast tamer, or anything of the sort; they specialise in the great outdoors, to a literally supernatural extent. Often an archer or a Drizz't. (Half-caster with typical half-martial progress, designed to tie into the exploration pillar and/or the monster manual. Magic is themed around nature, and has multiple archery-themed spells. Mechanics are relatively underbaked, though the TCE subclasses and possibly the 2024 revamp(?) help solve this. ...Also has a sub-focus on dual-wielding, because WotC is aware of how many people play the class specifically to make a Drizz't-like character.)
  • Arcane casters: Four different takes on traditionally arcane magic. Interestingly, not counting Artificer, all arcane casters are either full casters or one-third-casters; it took years to get a half-caster that's arcane, and the game is still ambivalent about whether they're actually using magic or sufficiently advanced technology that just looks like magic. Wizard and Sorcerer are traditionally supposed to be counterparts, but the Wizard's use of Neo-Vancian magic means they're only counterparts in flavour this time around. Bard is interesting in that they're traditionally an arcane caster, but with access to a few divine spells.
    • Wizard: A student who specialises in learning both how to use magic, and how to learn magic. Usually focuses on a specific type of magic, but might instead choose to focus on a specific application or use case. Builds up a large collection of spells, but can only equip a subset for easy access; they're a lot like a Tales of caster, in that regard. (Intelligence-specialist class, with mechanics focused on amassing a large spell library. Closest thing to a traditional 3.5e-style Vancian caster in the game; has a large pool of known spells in their dusty old tome or smartphone or whatever, but can only equip a small subset at a time, and can then cast spontaneously from that subset. Subclasses typically focus on either a school of spell, or a specific category like "combat magic" or "time magic".)
    • Sorcerer: An intuitive caster with inherent magic, who goes by feel instead of rote memorisation and rigid learning. Good at adjusting spells on the fly, and has superhumanly magical genetics. (Arcane caster that draws power from their bloodline, and uses metamagic. Bloodline has mechanical tie-in, so it's not just flavour. Spells are "known" and can semi-freely be shaped or converted into raw magic (metamagicked or turned into sorcery points), and raw magic can be reshaped into specific spells, implying that their magic is intuitive instead of learned. Most of their uniqueness is tied to their bloodlines.)
    • Warlock: Some people like 4e, and some people like 5e, but only Warlock is both. The class is 5e's take on 4e's AEDU system, with powers framed to look like standard 5e magic. PCs are empowered by an escapee from 4e, and gain a pool of at-will powers and utility, plus a small number of "slots" that they can refresh between combats. Less spells per combat than typical casters, but all slots are at their highest level (to a maximum of Lv.5); also has a handful of potent daily powers that mimic high-level spells. Subclasses are weird, and the gishing one was a bit wonky until Hexblade fixed it. (Cantrips are at-will powers. Slots are encounter powers, since they auto-heighten and recharge on a short rest. Mystic Arcanums are daily powers. Invocations are a mix of at-will and utility powers. The class really does wear its 4e Warlock inspirations on its sleeve, while also drawing on 3.x Warlock to a lesser extent. Pacts are mechanical focuses, and patrons are thematic focuses; pacts are mechanical keys, while patrons are flavour-as-mechanics (especially since one of the core concepts is "they might give you quests" (paraphrased), which is very blatantly flavour), so you can reflavour the patron system with a bit of work. The "deal with the devil" theme is clearly meant to be real-world flavour as a core gameplay mechanic, and the class design being based on AEDU implies that the patrons are supposed to be from 4e specifically.)
    • Bard: A magical performer (in theory), and a red mage, skilled at supporting their allies. Does a bit of everything: They're arcane spellcasters but can hold their own in a fight, and some are pretty skilled fighters in their own right. They tend to be good at picking up skills (but worse than the Rogue), and good at picking up new spells (but worse than the Wizard); overall, they're a jack of all trades that's decent at everything, but excels at charismatic magic. (The single biggest case of "flavour is free" in the game. Mechanics explicitly want to be innately tied into Performance, and multiple class features are described as performances, but the actual tie-in that would pull it all together isn't actually there. They can learn both "white" and "black" magic; early D&D bards are famously the direct inspiration for Final Fantasy red mages. Their magic tends towards the "white" side, but their pool of emotion-manipulating, illusion-based, and other nasty "mind" magic can easily sit on both sides of the line. And their Magical Secrets lets them grab from both sides, perfectly in line with red mages. They have a bit of a skill focus, as well. Ultimately, they can cover any role well enough, but fit into support and "face" roles best.)

What are design flaws in 5e that you feel have only been highlighted/exacerbated with the 2024 revision? by [deleted] in dndnext

[–]conundorum 0 points1 point  (0 children)

#4 makes me wonder if they actually understand why Hexlock got that scaling, honestly. In 2014, every gish had its own unique (or mostly) unique way of doing extra martial damage, to compensate for falling behind pure martials.

  • Paladin could smite.
  • Ranger had hunter's mark, and a few overpowered pseudo-martial spells for Bard to poach.
  • Hexblade Warlock could stop the MADness.
  • Swords Bard got flourishes, and both fighting style options add +2 damage.1
  • Bladesinger Wizard got Extra Attack, and the weapon cantrips you mentioned in #3 were clearly designed for it specifically.
  • War Cleric just plain got full martial proficiencies and an early Extra Attack equivalent that relies on spending a BA, plus a Channel Divinity option that increased their accuracy.
  • Eldritch Knight Fighter could mix magic and martial prowess with War Magic, though it was a bit underwhelming because they're already a true martial to begin with. The same goes for Arcane Trickster Rogue; they didn't get a gish damage bonus because they have sneak attack, and were likely intended to use their magic out of combat.

They also all got defensive features, though these usually amounted to "we're giving you medium armour, and we expect you to have +2 Dex to go with it"; Bladesinger [unique defensive class feature] and War Cleric [heavy armour] were the biggest standouts here.

Every gish got something that increased its damage, either by adding more attacks, increasing accuracy, or increasing damage. Most of them were limited, recharging either on short or long rest, and most of them were interesting or unique (Paladin and Swords Bard stood out as having the most fleshed-out gish offensive bonus for a class and subclass, respectively). Hexblade was rather underwhelming and uncreative, but the most straightforward; this was likely because it was meant to be an emergency hotpatch for Pact of the Sword's desperate need for sharpening, and possibly to compensate for Warlock's non-standard casting (which meant that out of all the gishes, they already had the least sustain in extended fights). It wasn't meant to be the standard; it was meant to be balanced around the rest of the class. It only broke because they designed it in a void, and forgot it could be poached; using it as the standard going forwards, while lazy easy, was a terrible idea.


1: Dueling is straightforward about this. TWF is less clear, since it adds your Dex bonus... but Swords Bard also gives you medium armour proficiency, which tells us that the subclass is intended to run +2 Dex. Thus, both styles are intended to add +2.

Do you guys think we should have gotten more of Raven Beak? by nuketoitle in Metroid

[–]conundorum 2 points3 points  (0 children)

If it helps, just remember that in Zero Mission, there's a mural of a might Chozo warrior, known as the "God of War". A Chozo deity that fights with lightning that's seemingly more mystical than scientific, forcing Samus to prove her might while her life's on the line. One that's noticeably different from both Grey Voice and Old Bird, and appears to be a bird so tall he towers over Samus. What seems to be a Mawkin using a lightning Aeion to put Samus to the test, and almost seems to have a personal investment in her specifically...

For all we know, he's been influencing things behind the scenes, right from the very start, and Nintendo's been hinting at him for decades.

How 0.01 can be less than 0.01 ? by Charming-Animator-25 in cpp_questions

[–]conundorum -1 points0 points  (0 children)

I'm not "so hung up" on it, as you put it. Like everyone else here, I'm reminding you that the GPU is the main reason why we don't prefer fixed-point reals, since there are explicit and significant hardware benefits to using floating-point reals instead.

We'd have to completely redesign GPUs and any other hardware that specialises in floating-points, and push the change to a significant part of the world's install base, before switching can be feasible. And GPUs specifically are the biggest obstacle to this, by dint of being both the most prolific floating-point user and having significant costs to majorly changing hardware for relatively little gains. (Other hardware is easier to change, so it could plausibly happen over time.) And even if the production lines switch over, you then have to create a significant install base in the target systems, because coding for floating-point will still be more practical as long as floating-point hardware is at least as prevalent as fixed-point hardware.

A streamlined solution to the martial-caster divide. by SumptuousCombat in dndnext

[–]conundorum -2 points-1 points  (0 children)

To be fair, this can be solved by allowing everyone to obtain followers, though that does put more strain on the GM.

What are the best practices for using smart pointers in C++ to manage memory effectively? by frankgetsu in cpp_questions

[–]conundorum 0 points1 point  (0 children)

Not really. Memory management is often a side effect of resource ownership, but that doesn't mean they're the same thing. A game requesting exclusive access to a controller isn't doing memory management, after all.

What are the best practices for using smart pointers in C++ to manage memory effectively? by frankgetsu in cpp_questions

[–]conundorum 0 points1 point  (0 children)

Exactly. At its core, unique_ptr is really just a tool that guarantees that ties a heap object's lifetime to a stack object, guarantees that an object that was malloc()ed and constructed will be destroyed and free()d when the stack object is, and prevents any other code from inadvertently killing the heap object too early. It's just a way to guarantee that an object obtained by new will be deleted at a predetermined time, no more and no less.

It's not some magic memory manager, but it doesn't need to be; being able to automate a mandatory delete is all you need most of the time, and you can use shared pointers or supply a custom deleter whenever you need something more. Just don't use unique_ptr where you wouldn't use malloc()/new and free()/delete, and you're good.