Logic World Wednesdays: The Grabby Edition

by @MouseHatGamesDeveloper2 years ago

Grabbing Rotations - Jimmy

You can now easily move objects around, and their rotations are all handled properly.

This is part 1 of 2 in my Grand Plan to Make Rotating Boards Less Awful and Difficult. You should be seeing part two next week.

Generalized Packet System - Felipe

To send data between the client and server, we use packets. These are small bits of data that the game uses for communicating things like when a player has placed a component. Previously, these packets were hard-coded, meaning that whenever we wanted to add a new packet type we needed to manually register it.

A big issue with this approach is that mods were not able to add their own packet types. For this reason, I’ve made this system more expandable: instead of packets having their own hard-coded ID they will be assigned an ID when the game starts. This will be very helpful for mods, as they will be able to send and receive their own data, independent from the rest of the game.

Fancy Circuit Optimizations - Felipe

This week I’ve also been working on optimizing the code that does all the circuit simulation, namely the clusters system and the circuit states system. The most interesting one is probably the clusters one, since it involved more thinking rather than coding.

Clusters are an internal structure we have within the simulation. A single cluster represents a group of pegs and wires all connected together. Since everything in the group will turn on and off at the same time, they can be treated as one object rather than several.


Previously the clusters that needed to be updated were stored on a simple list, which stored references to all of those clusters. This worked just fine, however it wasn’t the most efficient approach.

Since we only ever iterate through the clusters one after the other, we do not need the ability to get, for example, the fifth cluster in the list. Instead, we only really need to know which cluster is updating first, and which one is updating after it. This is very similar to the concept of a linked list, since each cluster just has to store a reference to the next cluster. This is much more efficient than using a list, since all the operations we need are O(1) (which basically means it always takes the same amount of time, no matter how many clusters there are) on a linked list.

There’s also a distinction between a doubly linked list and a singly linked list: an item in a singly linked list only stores the reference to the next item, while a doubly linked list’s item also stores a reference to the previous item. In theory we would need a singly linked list since we only ever go forward when updating, however using one would mean that we wouldn’t be able to remove an item that’s not the first or the last one (for example when you remove a component and we need to remove it from the list, it’s very likely it’s in the middle). For this reason, we need to go with a doubly linked list.

We could use C#’s generic LinkedList class, however it could introduce more overhead with unnecessary features and end up actually being slower than our old way of doing it. For this reason, clusters will instead build their own linked list of sorts, manually storing the previous and next clusters that are updating. When we want to update all of them we simply get the first one, update it, then check which cluster is next and repeat until we’ve reached the end.

I was going to make a cool graphic diagram to demonstrate the concept, but unfortunately I’m far from a graphics designer so if you’re interested I’ve made a text document detailing what happens when you add or remove a cluster.

This should also drastically improve the performance of Relays, as those components work by creating and destroying clusters. However, we haven’t been able to get numbers on that yet.

Bugs Fixed This Week

  • Fixed vertical flying controls getting stuck when Lock Flight Y Axis is off
  • Fixed Color Picker often opening by default to a white color
  • Fixed Gridlands worlds by default being created as pure white
  • Fixed boards flying away like a butterfly if you grabbed them at an angle that didn’t immediately provide a reference location
  • Fixed crazy errors next time you load a save if you quit to main menu while placing a component
  • Fixed Edit Label Menu not doing select all when it’s opened
  • Fixed fatal error when spamming the rotation key on buttons and keys


The amazing @Marutzo – whom some of you might know as NITRO – has made a gosh darn plushie of Bobby, Logic World’s beloved protagonist and mascot.


Click here for another photo!

This is pretty much the best thing ever and it has absolutely made our week!

We’ll keep releasing these weekly updates right up until the game comes out. To make sure you don’t miss them, you can sign up for our newsletter. Be sure also to wishlist Logic World on Steam and join the official Discord.

See you next Wednesday!

More Logic World Wednesdays

@Ecconia2 years ago

Logic World Wednesday is something I never experienced - ever.

It was always Thursday or even Friday. Why? Cause our dear dev-team is a deadline chaser, they send the LWW on Wednesday of their time and pretty much at the end of that day.

Well in particular I don’t really mind if its the wrong day, but the time is an issue… Followers living in Europe will get the LWW at a time past midnight, 1am to 4am usually, sometimes even 7am or 11am. I consider 8am+ okay again for everyone with a proper sleeping schedule in Europe. However in these cases the developer-team and all the ‘merican ppl are pretty much alseep again or very tired.

Why am I complaining? Just read it the next morning! Well, one misses the hype of the moment and even the rare voice-chat sessions with Jimmy right after the release, which might be nice for asking question and delivering the thanks to the developers. (Less spammy wall of texts here).

This sounds like a request to release the LWW at your times afternoon or midday - and it pretty much is one… But I know how harsh it is to do something in time, and to miss the thrill of being close to deadline… Maybe just consider LWW to be released the day before, or imagine to be Europeans :P

Well now you know about this well, lets call it issue. Do with it what you want.

*Oh right pipe also has the European timezone, I forgot well… is your sleeping schedule broken or do you deliver your sections in time?

@JimmyDeveloper2 years ago

Wednesday is a state of mind. Open your heart and be at peace.

@JimmyDeveloper2 years ago

More seriously, we do want to try to get these out earlier. They’re just a lot of work, we’re not terribly organized, and development of the game takes priority over making blogs about it.

I’ll try to be more proactive in releasing LWWs earlier. Thanks for letting me know it was bothering you.

@Ecconia2 years ago

like a butterfly ‘Fly board flyyyyy~~~~’ :D (I believe I saw that in some stream how they just flew away quite far… Awesome to hear that this issue is DED.

Regards the board movement, I assume its this difficult since it internally works with relative locations and rotations? Cause if it stores an absolute rotation, how could it even rotate when grabbing?

[OpenTUNG facts: Due to them being simple and I don’t yet need editing the boards, I have the lucky case of using absolute positions and rotations everywhere, ofc later on I will have to switch - imagine move an huge whole board or rotating it, heck no.]

@pipe01 Regards clusters I have two questions:

  • First: Previously and from what I could read just now, you are recreating a cluster whenever a connection to it gets changed, in particular when a relay changes its toggle state you also do that.

Did you ever think about changing to not recreating the affected clusters, but instead to have some specific data structure, which knows that these clusters are not hard-connected? (Its still an iteration, but one would not have to regenerate everything…) Except regenerating everything is much cheaper. However I cannot imagine that to be the case if you have like 128 big clusters chained. One relay change will cause the recreation of all of them…

Is that how you do it right now, and do you have ideas for further improvements?

  • Second: In TUNG/LW components are in charge of storing the simulations state. Means each tick, the outputs of the components cause the clusters to be calcuated and this gets applied via the inputs to the components again.

The system itself is fine and very good, however in TUNG there was the mistake of each input of a component displaying its past instead of its future state -> The inputs read the components state instead of the soon-to-be state of their connected clusters. This lead to weird visuals. In your screenshot you however included the inputs to the clusters, does that mean in LW you fixed this issues and let inputs show the soon-to-be state of the component? I recall not too long ago Jimmy saying he doesn’t know an easy solution to this, so I am quite curious. Especially since this is something I would love to be applied to LW.

(If you don’t know what i am talking about, in this video you can see, that each Inverter always has a valid state, but the cluster connected to the input has a different state: https://discordapp.com/channels/401255675264761866/588822987331993602/703480146283200514 <- Link to a video in your discord server.)

@JimmyDeveloper2 years ago

Regards the board movement, I assume its this difficult since it internally works with relative locations and rotations?

This is correct. I plan to do a video next week that describes the board placement system in more detail, and you should be able to see how it works in that.

however in TUNG there was the mistake of each input of a component displaying its past instead of its future state -> The inputs read the components state instead of the soon-to-be state of their connected clusters. This lead to weird visuals.

It’s not a mistake, and they’re not displaying their future states. The circuit behavior is just unintuitive. Presently, within each tick, the clusters update first and then the components/inputs update. This is perfectly logically consistent, but it means that between ticks you can get these confusing visuals. It’s especially noticeable if you slow the simulation speed down to 10 ticks per second or less.

I experimented a little while ago with reversing that order and making components update before clusters. This fixed the confusing visuals, but it caused all sorts of crazy bugs that I didn’t have the time to track down. I would like to revisit this experiment at some point.

In your screenshot you however included the inputs to the clusters

I think you misunderstand what a cluster is in our codebase. A cluster is a group of inputs and wires that are all connected. It represents a group of circuit objects that will always have the same state.

To the simulation code, inputs don’t exist as distinct objects, only clusters do. This is why we’ve labeled single inputs as their own clusters: they’re clusters with one input in them.

@Ecconia2 years ago

It’s not a mistake, and they’re not displaying their future states

I know, we had a big discussion about it. I label it a mistake, thus the . And I also said, they should display their future state and not that they do.

This is perfectly logically consistent

I also remember your explanation about how your ticks work internally, and that is perfectly okay and good! And NO you should not change the tick update, since it will mess stuff up.

What I am referring to is to change the visuals only. Such as allowing an Inserter to have a visual invalid state, to know its currently in a pinch and it will try to quickly (next tick) get out of it -> become valid again.

I think you misunderstand what a cluster is in our codebase

Maybe, but even if your inputs are linked with the cluster, the optical representation of that Input, should also use the same state as its cluster. And not like in TUNG use the state of the component its attached to.

I was basically asking, if you are doing that in LW now, or if you still do it the old TUNG way.

Since you already have the cluster state, why not just let the input use the same state?

I am sorry that my language is kind of complicated :(

@Stenodyon2 years ago

I like circuit simulation optimizations :D

@Vykori2 years ago

Grand Plan to Make Rotating Boards Less Awful and Difficult Ahh yes. The GPMRBLAD. The beta testers have been longing for this! I bet they’re G~~pmrb~~LAD

I’m very happy you’re nearing the end of the Shit We Need To Finish Before The Game Can Release (SWNTFBTGCR) list!

@JimmyDeveloper2 years ago

Indeed – the end of that list is in sight, and it’s a great feeling 😄