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
> 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
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
import net.minecraft.core.BlockPos
import net.minecraft.network.FriendlyByteBuf
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.network.Networking.Message
import org.neoflock.neocomputers.network.Networking.Visibility
@@ -155,10 +156,17 @@ open class DeviceNode(_address: UUID? = 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> {
if(reachability == Visibility.NONE) {
return setOf();
}
if(reachability == Visibility.SOME) {
return getPreferredFew()
}
if(reachability == Visibility.DIRECT) {
return connections.minus(this);
}
@@ -235,9 +243,10 @@ interface ConventionalNetworkDevice {
abstract class WirelessEndpoint(address: UUID?) : DeviceNode(address) {
abstract fun getRange(): Double
abstract fun getDimension(): Int
abstract fun getPosition(): BlockPos
abstract fun getEndpointRange(): Double
abstract fun getEndpointDimension(): Int
abstract fun getEndpointLevel(): Level
abstract fun getEndpointPosition(): Vec3
// separate from process for simplicity
abstract fun receiveWireless(message: Message, emitter: WirelessEndpoint)
}

View File

@@ -1,6 +1,7 @@
package org.neoflock.neocomputers.network
import net.minecraft.core.BlockPos
import net.minecraft.world.level.Level
import org.neoflock.neocomputers.entity.MachineEvent
import java.util.UUID
import kotlin.math.min
@@ -27,6 +28,8 @@ object Networking {
enum class Visibility {
// only it can see itself
NONE,
// some, as determined by getPreferredFew()
SOME,
// can only see its direct connections
DIRECT,
// Can see everything network-wide
@@ -54,26 +57,22 @@ object Networking {
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
}
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) {
val startPos = starter.getPosition();
val startDim = starter.getDimension();
val range = starter.getRange();
val startPos = starter.getEndpointPosition()
val startDim = starter.getEndpointDimension()
val level = starter.getEndpointLevel()
wirelessNodes.get().forEach {
if(it.getDimension() != startDim) return;
val pos = it.getPosition();
val d = distanceBetween(startPos, pos);
var trueRange = min(it.getRange(), range);
trueRange = min(trueRange, computeRangeAllowedByHardness(startPos, pos));
if(d > trueRange) return;
it.receiveWireless(message, starter);
if(it.getEndpointDimension() != startDim) return
val pos = it.getEndpointPosition()
val d = startPos.distanceTo(pos)
var trueRange = min(it.getEndpointRange(), range)
trueRange = min(trueRange, computeRangeAllowedByHardness(level, BlockPos.containing(startPos), BlockPos.containing(pos)))
if(d > trueRange) return
it.receiveWireless(message, starter)
}
}