• 0 Posts
  • 7 Comments
Joined 2 years ago
cake
Cake day: June 16th, 2023

help-circle
  • For your holy-mod-sword example specifically, the better approach is to specify a structured data format (think Excel sheets) that your game loads from a specific directory at startup and inserts the found items, NPCs etc. into the game’s runtime data structures (e.g. loot tables).

    For example, Skyrim (and other Bethesda games) do this with .esp-files, which allow you to import a big variety of different game entities. In a small indie game, the format doesn’t have to be anything special; e.g. Elin modders use plain .xlsx files, where the columns are item name, item weight, item sell value, item damage, etc.

    The above approach works for static data, such as simple items, but you’ll need more to allow modders to write Turing complete scripts. There are two different approaches to this:

    • Expose a language runtime in which the game runs mods. You can design your own language and/or runtime (e.g. Warcraft 3 has JASS), or use existing ones (this is basically what eval is, though you’ll need to hide builtins, globals and such by passing extra parameters). These approaches are theoretically safe thanks to the runtime sandbox, but there are often unintended ways to escape the sandbox and execute arbitrary code.
    • Inject the mod executable directly into the game with tools like BepInEx (Unity) or DLL injection (used by e.g. Skyrim Script Extender). There are no security guard rails, so you’ll need to manually review mods.



  • In applied CS, it’s common to talk about pure and impure functions instead of Turing machines.

    Pure functions are, broadly speaking, equivalent to Turing machines. A pure function may only depend on its inputs (like a Turing machine) and has no outputs besides the return value (like the end state of a Turing machine’s tape).

    Impure functions cover algorithms that aren’t Turing machines. For example, you might have a random number generator rand: 1 → N that outputs different natural numbers on every invocation rand() and is hence impure. Output functions are also impure, e.g., a function write: N → 1 that writes a number into a file can’t be a Turing machine, because Turing machines have no concept of files.

    Computer programs that consist entirely of pure functions aren’t very useful, because they can’t interact with the user or reality. The typical approach to solving this is to put the core program logic inside pure functions that interact with impure parts through a limited interface. That way, you can apply CS concepts to the important parts of the program and neatly separate out the impure parts.

    Edit: Changed ∅ to 1 (singleton set) in function definitions. A function can’t return ∅ and a function taking ∅ can’t be called.



  • As a Finnish speaker, I just can’t see generic localisation systems like Fluent working with agglutinative languages. For instance, consider the Polish example for Firefox Account from Fluent’s front page:

    -sync-brand-name = {$case ->
       *[nominative] Konto Firefox
        [genitive] Konta Firefox
        [accusative] Kontem Firefox
    }
    

    In Finnish, this would be called Firefox-tili. Tili means account and belongs to the Kotus type 5 words, which specifies how the word is inflected with various suffixes. Fluent doesn’t support agglutination, so you’d have to specify every form of the word separately:

    -sync-brand-name = {$case ->
        [nominative] Firefox-tili
        [partitive] Firefox-tiliä
        ... 10ish more inflections
        [nominative first person] Firefox-tilini
        [partitive first person] Firefox-tiliäni
        ... 10ish more inflections
        ... the above inflections but for 2nd and 3rd persons
        [nominative first person plural] Firefox-tilimme
        [partitive first person plural] Firefox-tiliämme
        ... 10ish more inflections
        ... the above inflections but for 2nd and 3rd persons plural
        [nominative first person questioning] Firefox-tilinikö
        [no idea what this is even called] Firefox-tilittömänäkin
        [no idea what this is even called 2] Firefox-tililleensäkään
        ... lots more
    }
    

    Ideally, you’d only specify that Firefox-tili is a type 5 word and the system generates all of that boilerplate.