Welcome back to another Logic World Wednesday. After a three week hiatus, we are back!
If you haven’t been keeping up with us on Discord, the break has been because we were reorganizing Logic World’s 50,000 lines of code. That work is finally done, and your regularly scheduled Wednesdays have returned!
I’ve added three new menus to Logic World this week! We now have a pause menu, and buttons and keys have gotten menus for editing those components.
Thanks to the release of Minis by Keijiro Takahashi, Logic World’s extensive input system now supports MIDI input! You can now use your pianos to control the game. MIDI bindings can be used for regular game actions like walking and jumping, but I expect they’ll mostly be used with Keys to make in-game music machines :D
Logic World uses a complex state machine to govern the flow between game states. For example, you’re allowed to transition to the in chair state from the building state, but you’re not allowed to transition to the in chair state from the multi-wire placing stage 2 state.
Previously, we defined the rules of the state machine all in a single file. This week I’ve built a new system and transitioned all our game states to it. Under the new system, the rules of the state machine are distributed throughout many files. The rules for one state are now right next to the code for what actually happens when the game is in that state.
When we’re working on a game state, this makes it easy to see that state’s relationships with other game states. But more importantly, this means that mods can now add their own game states, since they’re not all defined in one master file.
This week I’ve been working on refactoring the server’s codebase, adhering to the Inversion of Control principle. This means that I went through every single class, converted it to non-static, determined the classes that it depends on and injected them on its constructor, while creating an interface for it. This results in highly testable and modular code that’s a lot easier to maintain and extend.
I’ve also been refactoring the networking code: previously each packet type was composed of two methods: one for writing the packet and one for reading it. These methods operated directly on the network stream and they didn’t have an explicit structure, as it was determined by the order and type of read/write calls. After the refactor, each packet is its own class, we have SECCS serialize and deserialize it, so we don’t have to write any code that manipulates the network stream directly. Another benefit is that packets are clearly defined and, again, easier to maintain and extend.
I’ve also been rethinking the existing modding architecture, and this time I’ve decided on a file structure that looks like this (not final): * assets/ * myimage.png * mymesh.obj * my_unityassets.assetbundle * data/ * components.succ * lib/ * MyLibrary.dll * manifest.json * server.dll * client.dll * shared.dll
The mod as a whole is comprised of two parts: the server and the client. As their names suggest, the
server.dll will only be loaded on the server startup and the
client.dll will be loaded on the client startup, while the
shared.dll will be loaded on both and can be used to share code between them. It’s worth mentioning that all of these DLLs are regular .NET Standard 2.0 libraries generated by Visual Studio projects.
A mod can have any combination of these 3 DLL files, that’s to say, a mod can have a
client.dll or both, in which case it can also optionally have a
The assets folder contains different assets that the client-side mod will be able to load at runtime. Right now the supported types are
.mtl will probably come too) and
.assetbundle, and I’d also like to add support for audio files. The asset bundle files must be generated using the same Unity version as the game, which will be made known when the game is released. These asset bundles can contain any complex assets that you may need, like Unity scenes or prefabs.
The data folder currently only contains the SUCC file defining the components that your mod has, whose format you may already have seen in previous LWWs.
lib folder can contain any external libraries your mod uses, and the
manifest.json file defines the mod’s properties, like its name, author, and unique ID used to identify the mod in-game.
Finally, the mod as a whole can be stored in one of two ways: in a
.lwmod file (which is just a renamed
.zip file), or in a plain folder. The former is how mods downloaded from logicworld.net will be stored, while the latter is especially useful when developing mods as you can just copy the files over without any worries.
You will be able to upload and share mods on logicworld.net, but you must upload its source code, which will get compiled for you. This is in order to enforce open source code and transparency. It protects against mods with malicious code, and it helps people learning to make mods, since they can see the sources of existing ones.
For the past few weeks, we’ve been holding biweekly off-topic discussions on the Logic World Discord. This has been a lot of fun and we’ve had some very interesting talks. Some people have lamented that these discussions are not at a good time for them, so we’re experimenting with different times. This week’s Philosophy Phriday willl be 2 hours earlier than usual, at 18:00 UTC&).
See you next Wednesday!