2 September 2025 - Mod Code Safety, Inventories (again), Lore
You're on the latest post!
Development feels like it has both slowed down and sped up simultaneously. That's confusing. Anyway...
Mod Code Safety
One of my oldest concerns with modding the game - and indeed a concern in this very moment - is the possibility for malicious code to crop up. Mods are written in C#, meaning they are basically just tiny programs which just so happen to use game code. If a bad actor up and decided to attack the community, they could very easily spread straight up malware through mods (and moreso, with the Steam Workshop being planned, they would have a perfect place to distribute it). This is absolutely unacceptable. I want you to feel reasonably safe when installing mods. As the developer, I have a duty to at least expend the effort to make mods as safe as I can. It's a thing of courtesy and care.
Prior to this point, I had considered using Luau, a highly advanced fork of Lua with several incredible optimizations, for modding. It's quite powerful and would easily slot into the game's code. It also comes with its own sandboxing features for security. However, coupled with the fact that it would mean I have to actually add in a modding API rather than just letting modders use my code natively, the recent controversies with Roblox Corporation (who are directly involved with, and make use of, the Luau project) have made it significantly less appealing than it was in the past.
Thing is, I got lucky. Yesterday I was pointed towards the work of Douglas Dwyer by community member Kae. This man is working on a voxel-based game engine right now, and to be frank, the guy's a genius. I'd probably use the engine if I weren't already cemented in with Godot. That said, the reason I've mentioned him is because he also created the star of today's post: The CasCore Library.
Enter CasCore
CasCore is an interesting tool. For a small compromise, CasCore implements stringent security checks preventing unauthorized or potentially dangerous access to methods or fields. No more Directory.Delete(@"C:\Windows\System32", true)
for bad actors, basically. The tool protects against a lot of attack vectors: Reflection, delegates, virtual method calls, [UnsafeAccessor]
, the whole shabang. This means that I can provide at least a pretty stout assurance that a virus disguised as a mod won't immediately smear your computer across 7 dimensions.
The Compromise
As I mentioned, its use comes with a bit of a compromise. This won't affect the vast majority of modders, but it's vital to bring up anyway so people know.
- Harmony will now be delegated through my own interface layer. You do not get access to the Harmony, just a dumbed down version that I give you.
- You will have access to prefixes and postfixes.
- Prefixes and postfixes will be checked. You can only inject into vanilla code, and attempting to access certain secure fields will count as a security violation1.
- You can see what you can or can't access based on the presence of the
[NoAccess]
and[NoPatches]
attributes, which prevent general use and/or Harmony patching respectively.
- You will not have access to IL modification and transpilers.
- I plan to substitute these with infixes, which allow the insertion of methods arbitrarily within the target method body.
- Infixes can not currently capture stack variables. This may change as I understand there are use cases for it, and I plan to try to make it work.
- Infixes can read and modify local variables, and can read and modify arguments.
- I plan to substitute these with infixes, which allow the insertion of methods arbitrarily within the target method body.
- Your code will be modified before loading so that security checks are implemented.
- This may affect its performance characteristics, but granted the code is considered secure, it will not affect function. In contrast, insecure code will be rejected1.
- "Insecure code" means code that makes use of unauthorized API, like
File.WriteAllBytes
rather than the more closely managedStarFileExtensions.OpenWrite("user://asdfg")
.
- "Insecure code" means code that makes use of unauthorized API, like
- When benchmarking, you may want do so while the game is running, not in an isolated environment.
- This may affect its performance characteristics, but granted the code is considered secure, it will not affect function. In contrast, insecure code will be rejected1.
- There is a runtime performance cost for the invocation of virtual methods. This is unavoidable.
- This cost is not incurred when you call your own virtual methods in your own assembly.
- This cost is incurred when you call someone else's virtual methods, as well as vanilla virtual methods, and interface methods (where the type being called on is the interface, not the implementing class/struct).
All around, I am confident that CasCore is the best choice to facilitate a safe modding environment.
New Inventories
Inventories have gotten some focus again lately since they are so central to the experience. In particular, I recently got back into Starbound, with Frackin' Universe installed. One of the big drawbacks of this mod is the reliance on crafting components for various machinery. It makes sense and adds a lot of the fulfilling work required to craft advanced desires, but it also floods the inventory really badly to the point where you can't keep everything you need on hand. It's annoying and feels awful.
Originally I planned to solve this a bit too precisely. My intent was to add a "Components" inventory within your main inventory, a basic, list-formatted, high capacity inventory that stored items meant only for crafting and nothing else. This way you can have them on hand all the time without worrying about them taking up space. This has a few problems though:
- Even if useful, it felt kind of overpowered and also complicated the implementation of inventories a lot, because now they need two data structures to store items.
- This was too specific and not generally appliable; what if a modder wanted to add a different special inventory like this? No system existed to facilitate this.
The Inventory Hub System
My new solution was a bit more thought out: The Inventory Hub. This is not something you actually see and touch in gameplay, it's entirely abstract in the code. You just get a normal inventory like you are used to. So what makes the Inventory Hub different?
- The Inventory Hub is extensible. At a minimum it has a "main inventory" and an optional coin purse (this is the object used to track and store currencies).2
- It can have more than one inventory within it. These extra inventories work like Starbound's tab system where an item goes into a specific kind of inventory made for that kind of item.
- Unlike a list inventory, you still have a separate, sortable item grid for each special inventory category. This means you reap the benefits of organization and a grid.
- It facilitates the mounting and dismounting of extra inventories. If you find a backpack, it will become a tab in your inventory just like a category, and you'll access it that way too.
- It allows univeral item searching and presence checks. This means if you want an item to apply an effect while in the inventory, you can do that. Likewise, you can pull from a backpack or the main inventory when using crafting recipes.
This system sounds complicated but it really isn't. It's actually compatible with my existing inventory system immediately because I planned ahead with inventories, especially with the events contained on inventories. The only changes I need to make are:
- The mount/dismount system.
- Item whitelists/blacklists to allow or prevent certain inventories from accepting specific items.
- A new value added to items so they can indicate which inventory category they go into, by ID.
- This is separate from item tags which there can be as many as you want.
Lore
I don't often talk about lore because this early in development, it's not really something I'm focused on. You can't have lore in a game if there is no game, you know? On top of that, it's frequently changing, so 8 times out of 10 I'll say something and then it'll be outdated, which isn't great. But occasionally, bits and pieces of lore get worked on for one reason or another.
As the more astute of you may know, I have been working with RWGryphon on the game's lore since I want to include his story in a significant capacity (as a note, his story is something we have both worked on since we were young children, it started out as a little fantasy and we just kept adding to it). One of the major contentions we faced for a very long time was how to make our two worlds mix. Primarily, I have The Celestine Conservator, the creator of the universe. He has The Radiance, also the creator of the universe. Surely you can see the problem. The thing is, these two beings are distinctly different, and so "just make them the same deity" isn't an option here. We largely ignored this glaring issue for many months, instead choosing to focus on the stuff that matters - lore for the various playable races, other aliens, that sort of stuff.
However, just recently, we finally managed to solve the contention. We found a way to make both work in a believable way, thanks to one design choice I made with The Conservator: It's not omnipotent. This allowed us to effectively shoehorn in The Conservator as the creator of the rest of the universe. The Radiance is still the absolute creator of all things (as He originally was in RWG's story), but we altered His lore so that He focused on only one set of worlds, basically a pet project where the universe was its byproduct. The Conservator was created as a lesser deity for the purpose of putting life into the rest of the infinite expanse that is the universe, hence "the creator of the rest of the universe".
In particular I really love this design because it lets each one keep their role, and explains how they interact with reality. The Radiance is not a character you will see nor interact with. He will only be mentioned in some lorebooks as a recurring background element. The Conservator is a character you can visit (at least, such is the plan right now), but as something that isn't omnipotent, it's oblivious to the happenings of the universe. This is an important detail because it allows The Conservator to be a character in the story. It also helps with compatibility with other lore for various species that I reference, because their universes may or may not have their own religion and deities (or lack thereof).
Despite our satisfying progress of stories within the universe, this contention was always a huge void that was just kind of sitting there menacingly. It did prevent a lot of serious progression from being done with the world story, since we never knew who would be responsible for what aspects of reality, creating ambiguity. It's hard enough having all-powerful beings in a story. It's even worse when the writers don't know how the hell to use them. So that's fixed now. Woohoo.
Closing Thoughts
As far as things look now, development is just kind of "happening". There's no super major progress, but it's not stagnant either. I actually have the new inventory menu sort of made (I say "sort of" because it's outdated now). A picture was going to be shared here but I decided against it because I plan to do some more with the game's interface before anything else.
Another thing of note is that I am considering having special tool slots. Starbound's MM slot feature is especially useful. For context, in Starbound you have a tool called the "Matter Manipulator" which is always present and can't be deleted. It has its own special slot, with its own special keybind to equip it. Mods took this a step further and allowed overwriting the slot with other manipulator variants and related mining tools. I love this behavior to the point where I'd like to implement it myself. This also makes it easy to have the paint tool for blocks without worrying about items.
One of the other ideas I was more playfully considering was thematic menus. In particular I love when menus carry a specific theme for characters or species, like imagine your inventory menu having different aesthetics if you play as a Gaian vs. a Kirivian vs. a Novan, right? The hard part with this is that making it look good and not like reused-asset-slop requires hand-drawing all of the menus, and then superimposing relevant elements (like buttons) onto the menu. As much as I would love to do this, I simply don't have the time to, nor the artistic prowess (my consistency is just a bit lacking right now), and the clutter from all the different graphics is kind of daunting. It's something I'll have to consider probably some time during beta. Still, it seems fun.
-
In this case, the game will crash with
FATAL_CODE_SECURITY_VIOLATION
, caused by aSecurityException
. ↩↩ -
If this hub system works particularly well, I may nix the coin purse concept and just add a "money inventory". The main thing is that the coin purse allows having huge amounts of currency, whereas item stacks are stored in
UInt16
format (65535 is the largest stack size that can be ever created). ↩