half the todo is done

This commit is contained in:
2026-04-28 23:21:34 +03:00
parent 8fb4921e30
commit cd909dbd80
3 changed files with 33 additions and 49 deletions

36
TODO.md
View File

@@ -1,32 +1,3 @@
# Networking
> Pretty important here
## Auto-connect
Rework the auto-connect system of device blocks to be more stable.
Prob re-scan the network continuously
## Synchronization
Move the state logic into the node, as it was meant to be.
Note, addresses on the client are allowed to be complete bullshit at least for a bit of time.
`ComponentItem`s should no longer allow a node on the client (at least for now), it serves no
purpose currently, and also is not designed well.
## Get rid of NodeBlockEntity
It is basically throw-away stitched together garbage.
Replace it with a new abstract class, which allows different nodes on different sides,
handles synchronizing those nodes according to their state changes.
Also implement an equivalent for LivingEntities, like drones or other addon stuff.
## Optimizations
Optimize the networking, both synchronization using smaller encodings,
and emitting messages or adding/removing nodes. The goal is to have as little of
the CPU time on the server thread taken by NC as we can.
# Computation # Computation
> Pretty important for a computer mod > Pretty important for a computer mod
@@ -37,4 +8,9 @@ Also because it is a capable engine and has a good API for architectures, and NC
## Worker threads ## Worker threads
Computers need worker threads for running non-synchronized code, because otherwise we're cooked Computers need worker threads for running non-synchronized code, because otherwise we're cooked
## Entities as machines
Aside from blocks like cases and robots, we should also support entities like drones.
Not only for OC parity, but also as addons would def love that.

View File

@@ -1,8 +1,9 @@
package org.neoflock.neocomputers.network package org.neoflock.neocomputers.network
import net.minecraft.core.BlockPos
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.level.Level
import net.minecraft.world.phys.Vec3
import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.network.Networking.Message import org.neoflock.neocomputers.network.Networking.Message
import org.neoflock.neocomputers.network.Networking.Visibility import org.neoflock.neocomputers.network.Networking.Visibility
@@ -155,10 +156,17 @@ open class DeviceNode(_address: UUID? = null) {
reachableCache = null reachableCache = null
} }
// Returns a subset of connections, for a subset of direct
// meant for things like drives which dont want to accidentally fuse networks
open fun getPreferredFew() = setOf<DeviceNode>()
fun computeReachable(): Set<DeviceNode> { fun computeReachable(): Set<DeviceNode> {
if(reachability == Visibility.NONE) { if(reachability == Visibility.NONE) {
return setOf(); return setOf();
} }
if(reachability == Visibility.SOME) {
return getPreferredFew()
}
if(reachability == Visibility.DIRECT) { if(reachability == Visibility.DIRECT) {
return connections.minus(this); return connections.minus(this);
} }
@@ -235,9 +243,10 @@ interface ConventionalNetworkDevice {
abstract class WirelessEndpoint(address: UUID?) : DeviceNode(address) { abstract class WirelessEndpoint(address: UUID?) : DeviceNode(address) {
abstract fun getRange(): Double abstract fun getEndpointRange(): Double
abstract fun getDimension(): Int abstract fun getEndpointDimension(): Int
abstract fun getPosition(): BlockPos abstract fun getEndpointLevel(): Level
abstract fun getEndpointPosition(): Vec3
// separate from process for simplicity // separate from process for simplicity
abstract fun receiveWireless(message: Message, emitter: WirelessEndpoint) abstract fun receiveWireless(message: Message, emitter: WirelessEndpoint)
} }

View File

@@ -1,6 +1,7 @@
package org.neoflock.neocomputers.network package org.neoflock.neocomputers.network
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
import org.neoflock.neocomputers.entity.MachineEvent import org.neoflock.neocomputers.entity.MachineEvent
import java.util.UUID import java.util.UUID
import kotlin.math.min import kotlin.math.min
@@ -27,6 +28,8 @@ object Networking {
enum class Visibility { enum class Visibility {
// only it can see itself // only it can see itself
NONE, NONE,
// some, as determined by getPreferredFew()
SOME,
// can only see its direct connections // can only see its direct connections
DIRECT, DIRECT,
// Can see everything network-wide // Can see everything network-wide
@@ -54,26 +57,22 @@ object Networking {
deviceNode.getReachable().forEach { if(it !in exclude) it.received(message) } deviceNode.getReachable().forEach { if(it !in exclude) it.received(message) }
} }
fun computeRangeAllowedByHardness(src: BlockPos, dst: BlockPos): Double { fun computeRangeAllowedByHardness(level: Level, src: BlockPos, dst: BlockPos): Double {
return Double.POSITIVE_INFINITY // TODO: math return Double.POSITIVE_INFINITY // TODO: math
} }
fun distanceBetween(a: BlockPos, b: BlockPos): Double {
return sqrt((a.x - b.x + a.y - b.y + a.z - b.z).toDouble().pow(2.0));
}
fun emitWirelessMessage(starter: WirelessEndpoint, range: Double, message: Message) { fun emitWirelessMessage(starter: WirelessEndpoint, range: Double, message: Message) {
val startPos = starter.getPosition(); val startPos = starter.getEndpointPosition()
val startDim = starter.getDimension(); val startDim = starter.getEndpointDimension()
val range = starter.getRange(); val level = starter.getEndpointLevel()
wirelessNodes.get().forEach { wirelessNodes.get().forEach {
if(it.getDimension() != startDim) return; if(it.getEndpointDimension() != startDim) return
val pos = it.getPosition(); val pos = it.getEndpointPosition()
val d = distanceBetween(startPos, pos); val d = startPos.distanceTo(pos)
var trueRange = min(it.getRange(), range); var trueRange = min(it.getEndpointRange(), range)
trueRange = min(trueRange, computeRangeAllowedByHardness(startPos, pos)); trueRange = min(trueRange, computeRangeAllowedByHardness(level, BlockPos.containing(startPos), BlockPos.containing(pos)))
if(d > trueRange) return; if(d > trueRange) return
it.receiveWireless(message, starter); it.receiveWireless(message, starter)
} }
} }