Last active
May 29, 2024 20:20
Revisions
-
CyberShadow revised this gist
May 29, 2024 . 1 changed file with 46 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -53,7 +53,9 @@ void buildThing(ref SaveGame game, Config config) enum numInputIngesters = 5; enum inputIngesterSize = hubLength; enum inputPortLinkSize = numInputIngesters * inputIngesterSize; enum numAvalancheCells = 0; // Optional "avalanche" feature for getting throughput high scores enum avalancheCellSize = 0.75; enum outputPortLinkSize = numAvalancheCells * avalancheCellSize; enum portLaneSize = 0.25; enum minPortFilterSize = 4; @@ -420,7 +422,9 @@ void buildThing(ref SaveGame game, Config config) addr: Filter.Config.Addr.Src, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Differ, collision: numAvalancheCells == 0 ? Filter.Config.Collision.SendBackOutbound : Filter.Config.Collision.DropInbound, ), ); auto filterOutputHub = addHub( @@ -527,6 +531,46 @@ void buildThing(ref SaveGame game, Config config) inputIngesters[host] = NodePort(loopFilter, 0); } // Avalanche cells if (numAvalancheCells) foreach (HostIndex host; 0 .. numHosts) { auto port = cellPorts[Side.target][host]; foreach (i; 0 .. numAvalancheCells) { auto filter = addFilter( pos: [ startWorld[0] + terminatorSize + numHosts * cellSize + i * avalancheCellSize + avalancheCellSize * 0.5, objectY, startWorld[2] + terminatorSize + host * cellSize + cellSize * 1/8, ], angle: 0, config: i + 1 == numAvalancheCells ? Filter.Config( // The "go" switch port: 0, mask: wildcardAddress(Address.Type.UnrestrictedFilter), addr: Filter.Config.Addr.Dst, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Match, collision: Filter.Config.Collision.DropInbound, ) : Filter.Config( // Avalanche cell - trap the packet port: 1, mask: wildcardAddress(Address.Type.UnrestrictedFilter), addr: Filter.Config.Addr.Dst, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Match, collision: Filter.Config.Collision.SendBackOutbound, ), ); addRelays(port, NodePort(filter, 0)); port = NodePort(filter, 1); } cellPorts[Side.target][host] = port; } // Input / output / bus integration foreach (HostIndex host; 0 .. numHosts) { -
CyberShadow revised this gist
May 29, 2024 . 1 changed file with 2 additions and 7 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -53,7 +53,7 @@ void buildThing(ref SaveGame game, Config config) enum numInputIngesters = 5; enum inputIngesterSize = hubLength; enum inputPortLinkSize = numInputIngesters * inputIngesterSize; enum outputPortLinkSize = 0; enum portLaneSize = 0.25; enum minPortFilterSize = 4; @@ -552,10 +552,6 @@ void buildThing(ref SaveGame game, Config config) collision: Filter.Config.Collision.DropInbound, ), ); auto outputToCornerRelay = addRelay( pos: [outputX0 + outputPortLinkSize + host * portLaneSize, objectY, outputZ0 + cellSize * 1/8], angle: 0, @@ -569,8 +565,7 @@ void buildThing(ref SaveGame game, Config config) addRelays(NodePort(inputOutputSplitHub, 1), inputIngesters[host]); addRelays(cellPorts[Side.target][host], NodePort(outputToCornerRelay, 0)); addRelays(NodePort(outputToCornerRelay, 1), NodePort(cornerRelay, 0)); addRelays(NodePort(cornerRelay, 1), NodePort(inputOutputSplitHub, 2)); -
CyberShadow revised this gist
May 29, 2024 . 1 changed file with 24 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -52,7 +52,8 @@ void buildThing(ref SaveGame game, Config config) enum cellSize = 2.0; enum numInputIngesters = 5; enum inputIngesterSize = hubLength; enum inputPortLinkSize = numInputIngesters * inputIngesterSize; enum outputPortLinkSize = cellSize; enum portLaneSize = 0.25; enum minPortFilterSize = 4; @@ -62,14 +63,21 @@ void buildThing(ref SaveGame game, Config config) enum ChunkCoord startChunk = {x: 11, y: 0, z: -2}; auto totalWorldXSize = terminatorSize + cellSize * numHosts + outputPortLinkSize + portLaneSize * numHosts; auto totalChunkXSize = cast(int)ceil(totalWorldXSize / chunkSize); auto totalWorldZSize = terminatorSize + cellSize * numHosts + inputPortLinkSize + portLaneSize * numHosts + minPortFilterSize; auto totalChunkZSize = cast(int)ceil(totalWorldZSize / chunkSize); totalWorldZSize = totalChunkZSize * chunkSize; auto startWorld = startChunk.toWorld; auto objectY = startWorld[1] + 5.5; // We will place all objects at this height. @@ -88,14 +96,14 @@ void buildThing(ref SaveGame game, Config config) struct ChunkPlan { ChunkGeometry geometry; bool firstRunOnly; } ChunkPlan[ChunkCoord] chunkPlan; // Switch foreach (z; startChunk.z .. startChunk.z + totalChunkZSize) foreach (x; startChunk.x .. startChunk.x + totalChunkXSize) chunkPlan[ChunkCoord(x, startChunk.y, z)] = ChunkPlan(ChunkGeometry.flat, false); foreach (x; startChunk.x .. startChunk.x + totalChunkXSize) chunkPlan[ChunkCoord(x, startChunk.y, startChunk.z + totalChunkZSize)] = ChunkPlan(ChunkGeometry.flat, true); // Bus auto busChunkZ = startChunk.z + totalChunkZSize + 1; foreach (x; startChunk.x .. startChunk.x + totalChunkXSize) chunkPlan[ChunkCoord(x, startChunk.y, busChunkZ)] = ChunkPlan(ChunkGeometry.flat, false); foreach (i, target; busTargets) { @@ -528,11 +536,11 @@ void buildThing(ref SaveGame game, Config config) auto outputZ0 = startWorld[2] + terminatorSize + host * cellSize; auto inputOutputSplitHub = addHub( pos: [inputX0 + cellSize * 1/8, objectY, inputZ0 + inputPortLinkSize + host * portLaneSize], angle: 0, ); auto inputFilter = addFilter( pos: [inputX0 + cellSize * 1/8, objectY, startWorld[2] + totalWorldZSize - 0.3], angle: 0, config: Filter.Config( // Sends back packets not from the intended peer. Mainly for identification. @@ -545,15 +553,15 @@ void buildThing(ref SaveGame game, Config config) ), ); auto outputRelay = addRelay( pos: [outputX0 + outputPortLinkSize * 0.5, objectY, outputZ0 + cellSize * 1/8], angle: 0, ); auto outputToCornerRelay = addRelay( pos: [outputX0 + outputPortLinkSize + host * portLaneSize, objectY, outputZ0 + cellSize * 1/8], angle: 0, ); auto cornerRelay = addRelay( pos: [outputX0 + outputPortLinkSize + host * portLaneSize, objectY, inputZ0 + inputPortLinkSize + host * portLaneSize], angle: 0, ); -
CyberShadow revised this gist
May 29, 2024 . 1 changed file with 14 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -625,15 +625,15 @@ void buildThing(ref SaveGame game, Config config) stderr.writef("Dangle"); else { auto peerNodeIndex = peer.get().port[0]; auto obj = game.getGameObject(peerNodeIndex); if (obj.isNull()) stderr.writef("Unknown"); else obj.get.match!( (ref const Endpoint endpoint) { if (endpoint.address == host.toAddress(Address.Type.Endpoint)) stderr.writef("OK (%d)", peer.get().numHops); else stderr.writef(endpoint.address.elements.toString()); }, @@ -679,25 +679,33 @@ Nullable!NodePort getNodePortPeer(ref const SaveGame game, NodePort port) return typeof(return)(); } struct FinalPeer { NodePort port; size_t numHops; } Nullable!FinalPeer getFinalNodePortPeer(ref const SaveGame game, NodePort port) { size_t numHops; while (true) { auto peer = game.getNodePortPeer(port); if (peer.isNull) return typeof(return)(); auto peerNode = peer.get()[0]; auto peerPort = peer.get()[1]; auto obj = game.getGameObject(peerNode); if (obj.isNull) return typeof(return)(FinalPeer(peer.get(), numHops)); bool done; obj.get().match!( (ref const Relay relay) { done = false; port = NodePort(peerNode, cast(PortIndex)(1 - peerPort)); }, (_ ) { done = true; }, ); if (done) return typeof(return)(FinalPeer(peer.get(), numHops)); numHops++; } } -
CyberShadow revised this gist
May 29, 2024 . 1 changed file with 49 additions and 38 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,9 +50,9 @@ void buildThing(ref SaveGame game, Config config) enum numHosts = 4 ^^ 3; enum terminatorSize = 4.0; enum cellSize = 2.0; enum numInputIngesters = 5; enum inputIngesterSize = hubLength; enum portLinkSize = numInputIngesters * inputIngesterSize; enum portLaneSize = 0.25; enum minPortFilterSize = 4; @@ -441,23 +441,15 @@ void buildThing(ref SaveGame game, Config config) auto inputX0 = startWorld[0] + terminatorSize + host * cellSize; auto inputZ0 = startWorld[2] + terminatorSize + numHosts * cellSize; Nullable!NodePort lastInnerPort = cellPorts[Side.source][host]; Nullable!NodePort lastOuterPort; // will be created on the first iteration assert(numInputIngesters > 0); // Must have at least one. One ingester is just one filter, no hubs. foreach (i; 0 .. numInputIngesters) { auto z = inputZ0 + inputIngesterSize * i + inputIngesterSize * 0.5; auto filter = addFilter( pos: [inputX0 + cellSize * 1/8 + 0.65, objectY, z], angle: -PI/2, @@ -467,45 +459,64 @@ void buildThing(ref SaveGame game, Config config) addr: Filter.Config.Addr.Dst, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Match, collision: Filter.Config.Collision.SendBackOutbound, ), ); if (i + 1 == numInputIngesters) { // Wire directly to filter addEdge(lastInnerPort.get(), NodePort(filter, 1)); lastInnerPort = Nullable!NodePort(); } else { auto innerHub = addHub( pos: [inputX0 + cellSize * 1/8, objectY, z], angle: -PI/2, ); addEdge(lastInnerPort.get(), NodePort(innerHub, 0)); addEdge(NodePort(innerHub, 1), NodePort(filter, 1)); lastInnerPort = NodePort(innerHub, 2); } if (i == 0) { // Wire directly from filter lastOuterPort = NodePort(filter, 0); } else { auto outerHub = addHub( pos: [inputX0 + cellSize * 1/8 + 1.3, objectY, z], angle: -PI/2, ); addEdge(lastOuterPort.get(), NodePort(outerHub, 2)); addEdge(NodePort(outerHub, 1), NodePort(filter, 0)); lastOuterPort = NodePort(outerHub, 0); } } // One final filter to 1) allow things to line up 2) trap packets to keep retrying auto loopFilter = addFilter( pos: [ // The position where the last hub would be inputX0 + cellSize * 1/8, objectY, inputZ0 + inputIngesterSize * (numInputIngesters - 1) + inputIngesterSize * 0.5 ], angle: 0, config: Filter.Config( port: 1, mask: wildcardAddress(Address.Type.UnrestrictedFilter), addr: Filter.Config.Addr.Dst, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Match, collision: Filter.Config.Collision.DropInbound, ), ); addEdge(lastOuterPort.get(), NodePort(loopFilter, 1)); inputIngesters[host] = NodePort(loopFilter, 0); } // Input / output / bus integration -
CyberShadow revised this gist
May 29, 2024 . 2 changed files with 92 additions and 19 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -50,7 +50,9 @@ void buildThing(ref SaveGame game, Config config) enum numHosts = 4 ^^ 3; enum terminatorSize = 4.0; enum cellSize = 2.0; enum numInputIngesters = 3; enum inputIngesterSize = hubLength; enum portLinkSize = numInputIngesters * inputIngesterSize + 0.5; enum portLaneSize = 0.25; enum minPortFilterSize = 4; @@ -430,25 +432,90 @@ void buildThing(ref SaveGame game, Config config) } } // Input ingesters // (This mechanism attempts to solve the problem of packet drops due to unfortunate timing. // It works by giving packets more than one attempt to enter the input loop.) NodePort[numHosts] inputIngesters; foreach (HostIndex host; 0 .. numHosts) { auto inputX0 = startWorld[0] + terminatorSize + host * cellSize; auto inputZ0 = startWorld[2] + terminatorSize + numHosts * cellSize; NodePort lastInnerPort = cellPorts[Side.source][host]; NodePort lastOuterPort; // will be created on the first iteration assert(numInputIngesters > 0); // Must have at least one. One ingester is just one filter, no hubs. foreach (i; 0 .. numInputIngesters) { auto z = inputZ0 + inputIngesterSize * i + inputIngesterSize * 0.5; auto innerHub = i + 1 != numInputIngesters ? addHub( pos: [inputX0 + cellSize * 1/8, objectY, z], angle: -PI/2, ) : addRelay( pos: [inputX0 + cellSize * 1/8, objectY, z], ); auto filter = addFilter( pos: [inputX0 + cellSize * 1/8 + 0.65, objectY, z], angle: -PI/2, config: Filter.Config( port: 1, mask: wildcardAddress(Address.Type.UnrestrictedFilter), addr: Filter.Config.Addr.Dst, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Match, collision: i == 0 // Sends back all packets. On collision, drop the inbound (old) packet. ? Filter.Config.Collision.DropInbound // The additional filters will buffer. : Filter.Config.Collision.SendBackOutbound, ), ); auto outerHub = i != 0 ? addHub( pos: [inputX0 + cellSize * 1/8 + 1.3, objectY, z], angle: -PI/2, ) : addRelay( pos: [inputX0 + cellSize * 1/8 + 1.3, objectY, z], ); if (i != 0) addEdge(lastOuterPort, NodePort(outerHub, 2)); addEdge(NodePort(outerHub, 1), NodePort(filter, 0)); lastOuterPort = NodePort(outerHub, 0); addEdge(lastInnerPort, NodePort(innerHub, 0)); addEdge(NodePort(innerHub, 1), NodePort(filter, 1)); if (i + 1 == numInputIngesters) lastInnerPort = NodePort.init; else lastInnerPort = NodePort(innerHub, 2); } // One final relay to allow things to line up auto finalRelay = addRelay( pos: [ inputX0 + cellSize * 1/8, objectY, inputZ0 + inputIngesterSize * numInputIngesters + 0.25 ], ); addEdge(lastOuterPort, NodePort(finalRelay, 1)); inputIngesters[host] = NodePort(finalRelay, 0); } // Input / output / bus integration foreach (HostIndex host; 0 .. numHosts) { auto inputX0 = startWorld[0] + terminatorSize + host * cellSize; auto inputZ0 = startWorld[2] + terminatorSize + numHosts * cellSize; auto outputX0 = startWorld[0] + terminatorSize + numHosts * cellSize; auto outputZ0 = startWorld[2] + terminatorSize + host * cellSize; auto inputOutputSplitHub = addHub( pos: [inputX0 + cellSize * 1/8, objectY, inputZ0 + portLinkSize + host * portLaneSize], angle: 0, @@ -480,15 +547,14 @@ void buildThing(ref SaveGame game, Config config) ); addRelays(NodePort(inputFilter, 1), NodePort(inputOutputSplitHub, 0)); addRelays(NodePort(inputOutputSplitHub, 1), inputIngesters[host]); addRelays(cellPorts[Side.target][host], NodePort(outputRelay, 0)); addRelays(NodePort(outputRelay, 1), NodePort(outputToCornerRelay, 0)); addRelays(NodePort(outputToCornerRelay, 1), NodePort(cornerRelay, 0)); addRelays(NodePort(cornerRelay, 1), NodePort(inputOutputSplitHub, 2)); peerPorts[host] = NodePort(inputFilter, 0); } @@ -543,7 +609,7 @@ void buildThing(ref SaveGame game, Config config) foreach (port; [peerPorts[host], busOuterPorts[host]]) { stderr.write("\t"); auto peer = game.getFinalNodePortPeer(port); if (peer.isNull()) stderr.writef("Dangle"); else This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -250,6 +250,13 @@ ChunkCoord toChunk(WorldCoord c) /////////////////////////////////////////////////////////////////////////////// enum relaySize = 0.4; enum hubLength = 1.0; enum hubWidth = 0.5; enum filterSize = 0.6; /////////////////////////////////////////////////////////////////////////////// Address.Element[4] parseAddress(string str) { Address.Element[4] result; -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -222,7 +222,7 @@ void buildThing(ref SaveGame game, Config config) return index; } NodeIndex addRelay(WorldCoord pos, WorldCoord up = upVector, double angle = 0, bool fixed = false, bool light = true) { auto index = addNode(pos, up, angle); game.relays ~= Relay(index, fixed: fixed, light: light); @@ -280,7 +280,7 @@ void buildThing(ref SaveGame game, Config config) vec[] /= vecLength; auto relayCoord = sourceCoord; relayCoord[] += vec[] * maxWireLength; auto relay = addRelay(relayCoord, light: false); addEdge(source, NodePort(relay, 0), color); source = NodePort(relay, 1); -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -406,10 +406,10 @@ void buildThing(ref SaveGame game, Config config) // collision: Filter.Config.Collision.SendBackOutbound, // This variant (which should always match) allows identification of the source: mask: Address((){ auto a = sourceHost.toAddressElements(); a[0] = Address.Element.Three; return a; }(), Address.Type.UnrestrictedFilter), addr: Filter.Config.Addr.Src, action: Filter.Config.Action.SendBackPacket, op: Filter.Config.Op.Differ, collision: Filter.Config.Collision.SendBackOutbound, ), ); -
CyberShadow revised this gist
May 28, 2024 . 2 changed files with 105 additions and 4 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,9 +10,12 @@ import std.format; import std.math.algebraic; import std.math.constants; import std.math.rounding; import std.meta : AliasSeq; import std.path; import std.range; import std.stdio : stderr; import std.sumtype; import std.traits; import std.typecons; import ae.sys.file; @@ -304,6 +307,9 @@ void buildThing(ref SaveGame game, Config config) assert(numAddedEdges <= 1, "Ambiguous reconnect"); } // Switch edge port to bus / endpoint NodePort[numHosts] peerPorts; // Create the switch { enum Side @@ -424,9 +430,6 @@ void buildThing(ref SaveGame game, Config config) } } foreach (HostIndex host; 0 .. numHosts) { auto inputX0 = startWorld[0] + terminatorSize + host * cellSize; @@ -496,6 +499,7 @@ void buildThing(ref SaveGame game, Config config) // The bus NodePort[numHosts] busInnerPorts, busOuterPorts; foreach (HostIndex host; 0 .. numHosts) { enum hostsPerBusArm = 16; @@ -525,6 +529,98 @@ void buildThing(ref SaveGame game, Config config) addRelays(NodePort(busStart, 1), NodePort(busFinish, 0)); addRelays(NodePort(busFinish, 1), NodePort(busExit, 0)); reconnect(NodePort(busExit, 1)); busOuterPorts[host] = NodePort(busEnter, 0); busInnerPorts[host] = NodePort(busExit, 1); } // Check connectivity stderr.writefln("Host\tSwitch\tBus"); foreach (HostIndex host; 0 .. numHosts) { stderr.writef(host.toAddressElements().toString()); foreach (port; [peerPorts[host], busOuterPorts[host]]) { stderr.write("\t"); auto peer = game.getFinalNodePortPeer(peerPorts[host]); if (peer.isNull()) stderr.writef("Dangle"); else { auto peerNodeIndex = peer.get()[0]; auto obj = game.getGameObject(peerNodeIndex); if (obj.isNull()) stderr.writef("Unknown"); else obj.get.match!( (ref const Endpoint endpoint) { if (endpoint.address == host.toAddress(Address.Type.Endpoint)) stderr.writef("OK"); else stderr.writef(endpoint.address.elements.toString()); }, (ref const other) { stderr.writef(Unqual!(typeof(other)).stringof); } ); } } stderr.writeln(); } } alias GameObject = SumType!( Endpoint, Relay, Filter, Hub, Bridge, ); Nullable!GameObject getGameObject(ref const SaveGame game, NodeIndex node) { static foreach (getObjectsOfType; AliasSeq!( () => game.endpoints, () => game.relays, () => game.filters, () => game.hubs, () => game.bridges, )) foreach (obj; getObjectsOfType()) if (obj.node == node) return typeof(return)(GameObject(obj)); return typeof(return)(); } Nullable!NodePort getNodePortPeer(ref const SaveGame game, NodePort port) { foreach (edge; game.edges) if (edge[0] == port) return typeof(return)(edge[1]); else if (edge[1] == port) return typeof(return)(edge[0]); return typeof(return)(); } Nullable!NodePort getFinalNodePortPeer(ref const SaveGame game, NodePort port) { while (true) { auto peer = game.getNodePortPeer(port); if (peer.isNull) return peer; auto peerNode = peer.get()[0]; auto peerPort = peer.get()[1]; auto obj = game.getGameObject(peerNode); if (obj.isNull) return peer; bool done; obj.get().match!( (ref const Relay relay) { done = false; port = NodePort(peerNode, cast(PortIndex)(1 - peerPort)); }, (_ ) { done = true; }, ); if (done) return peer; } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -121,6 +121,11 @@ struct Hub bool dir; } struct Bridge { NodeIndex node; } struct ChunkCoord { int x, y, z; } alias ChunkRunLength = ushort; enum Material : ubyte @@ -177,7 +182,7 @@ struct SaveGame JSONFragment testers; Hub[] hubs; JSONFragment antennas; Bridge[] bridges; JSONFragment chunk_types; Chunk[] chunks; JSONFragment toolboxes; -
CyberShadow revised this gist
May 28, 2024 . 3 changed files with 100 additions and 53 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,33 +25,6 @@ import game; /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /// Returns a range of coordinates of chunks which fully contain or @@ -393,7 +366,7 @@ void buildThing(ref SaveGame game, Config config) { auto x0 = startWorld[0] + terminatorSize + sourceHost * cellSize; auto z0 = startWorld[2] + terminatorSize + targetHost * cellSize; auto active = config.canSend[sourceHost][targetHost]; if (active) { auto filterInputHub = addHub( This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,41 +6,60 @@ import game; struct Config { bool[4^^4][4^^4] canSend; } Config readConfig() { Address.Element[4][] replierMasks; Config config; foreach (line; readText("rules.txt").splitLines) { if (!line.length || line[0] == '#') continue; auto parts = line.findSplit("\t"); switch (parts[2]) { case "reply": auto sourceMask = parseAddress(parts[0]); replierMasks ~= sourceMask; break; default: // expand letters void handle(string sourceStr, string targetStr) { auto sourceMask = parseAddress(sourceStr); auto targetMask = parseAddress(targetStr); foreach (source; hostsMatching(sourceMask)) foreach (target; hostsMatching(targetMask)) config.canSend[source][target] = true; } void expand(string sourceStr, string targetStr) { foreach (letter; "abcd") if (sourceStr.canFind(letter)) { foreach (replacement; "0123") expand( sourceStr.replace(letter, replacement), targetStr.replace(letter, replacement), ); return; } handle(sourceStr, targetStr); } expand(parts[0], parts[2]); break; } } foreach (replierMask; replierMasks) foreach (replier; hostsMatching(replierMask)) foreach (peer; allHosts) if (config.canSend[peer][replier]) config.canSend[replier][peer] = true; return config; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,7 @@ import std.algorithm.iteration; import std.array; import std.math.rounding; import std.range; import std.traits; import std.typecons; @@ -264,3 +265,57 @@ Address.Element[4] parseAddress(string str) string toString(Address.Element element) { return "0123*"[element .. element+1]; } string toString(Address.Element[4] address) { return address[].map!toString.join("."); } /////////////////////////////////////////////////////////////////////////////// alias HostIndex = ubyte; Address.Element[4] toAddressElements(HostIndex index) { return [ cast(Address.Element)((index >> (3 * 2)) & 3), cast(Address.Element)((index >> (2 * 2)) & 3), cast(Address.Element)((index >> (1 * 2)) & 3), cast(Address.Element)((index >> (0 * 2)) & 3), ]; } Address toAddress(HostIndex index, Address.Type type) { return Address(toAddressElements(index), type); } Address wildcardAddress(Address.Type type) { return Address([ Address.Element.Wildcard, Address.Element.Wildcard, Address.Element.Wildcard, Address.Element.Wildcard, ], type); } /////////////////////////////////////////////////////////////////////////////// bool matches(Address.Element[4] address, Address.Element[4] pattern) { foreach (i, elem; pattern) { assert(address[i] != Address.Element.Wildcard, "Wildcard not allowed in address"); if (elem != Address.Element.Wildcard && elem != address[i]) return false; } return true; } auto allHosts() { return (4^^4) .iota .map!(hostIndex => cast(HostIndex)hostIndex); } auto hostsMatching(Address.Element[4] mask) { return allHosts.filter!(hostIndex => hostIndex.toAddressElements.matches(mask)); } -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 18 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -2,6 +2,7 @@ import std.algorithm.comparison; import std.algorithm.iteration; import std.algorithm.mutation; import std.algorithm.searching; import std.algorithm.setops; import std.algorithm.sorting; import std.array; import std.file; @@ -10,6 +11,7 @@ import std.math.algebraic; import std.math.constants; import std.math.rounding; import std.path; import std.range; import std.stdio : stderr; import std.typecons; @@ -52,6 +54,18 @@ Address wildcardAddress(Address.Type type) /////////////////////////////////////////////////////////////////////////////// /// Returns a range of coordinates of chunks which fully contain or /// touch (on a face, edge, or corner) the given world coordinate. auto chunksTouching(WorldCoord pos) { auto chunkPos = pos.toChunk; return cartesianProduct( iota(chunkPos.x - (pos[0] % chunkSize == 0 ? 1 : 0), chunkPos.x + 1), iota(chunkPos.y - (pos[1] % chunkSize == 0 ? 1 : 0), chunkPos.y + 1), iota(chunkPos.z - (pos[2] % chunkSize == 0 ? 1 : 0), chunkPos.z + 1), ).map!(t => ChunkCoord(t.expand)); } void buildThing(ref SaveGame game, Config config) { const origGame = game; @@ -146,8 +160,10 @@ void buildThing(ref SaveGame game, Config config) game.nodes = game.nodes.dup; foreach (NodeIndex i, ref node; game.nodes) if (node.pos[1] == objectY && chunksTouching(node.pos).any!(chunkPos => chunkPos in chunkPlan && chunkPlan[chunkPos].firstRunOnly == false )) { node = nullNode; nodeFreeList ~= i; -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -179,12 +179,12 @@ void buildThing(ref SaveGame game, Config config) Material.crackedStone, ]; foreach (chunk; game.chunks) if (chunk[0] in chunkRunPlan) foreach (r; chunk[1]) if (!unimportantMaterials.canFind(cast(Material)r[1])) throw new Exception("Refusing to overwrite chunk at %s with important material %s".format(chunk[0], cast(Material)r[1])); foreach (node; game.nodes) if (node.pos[1] != objectY && node.pos.toChunk in chunkRunPlan) throw new Exception("Refusing to overwrite chunk at %s with user-placed node at %s".format(node.pos.toChunk, node.pos)); game.chunks = game.chunks -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 12 additions and 3 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -509,13 +509,22 @@ void buildThing(ref SaveGame game, Config config) foreach (HostIndex host; 0 .. numHosts) { enum hostsPerBusArm = 16; auto exitX = startWorld[0] + terminatorSize + host * cellSize + cellSize * 1/8; // Same as inputFilter auto busLaneWidth = double(chunkSize) / numHosts; auto busExitZ = busChunkZ * chunkSize; auto busZ = busExitZ + host * busLaneWidth + busLaneWidth / 2; auto busEnterArmWidth = double(chunkSize) / 4 * 3; auto busEnterLaneWidth = busEnterArmWidth / hostsPerBusArm; // 0.75 (edges are too close to dig areas and might even be effectively buried) auto enterX = busTargets[host / hostsPerBusArm].x * chunkSize // bus arm position + (chunkSize - busEnterArmWidth) / 2 // centering within bus arm + (host % hostsPerBusArm) * busEnterLaneWidth // per-host offset + busEnterLaneWidth / 2; // centering within bus lane auto enterZ = busTargets[host / hostsPerBusArm].z * chunkSize + (busTargets[host / hostsPerBusArm].z > busChunkZ ? 0 : 1) * chunkSize; auto busExit = addRelay([exitX, objectY, busExitZ]); auto busFinish = addRelay([exitX, objectY, busZ]); -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 3 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -183,6 +183,9 @@ void buildThing(ref SaveGame game, Config config) foreach (r; chunk[1]) if (!unimportantMaterials.canFind(cast(Material)r[1])) throw new Exception("Refusing to overwrite chunk at %s with important material %s".format(chunk[0], cast(Material)r[1])); foreach (node; game.nodes) if (node.pos[1] != objectY && node.pos.toChunk in chunkPlan) throw new Exception("Refusing to overwrite chunk at %s with user-placed node at %s".format(node.pos.toChunk, node.pos)); game.chunks = game.chunks .filter!(c => c[0] !in chunkRunPlan) -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 13 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -171,6 +171,19 @@ void buildThing(ref SaveGame game, Config config) // Make chunks { static immutable Material[] unimportantMaterials = [ Material.empty, Material.dirt, Material.drillGoo, Material.stone, Material.crackedStone, ]; foreach (chunk; game.chunks) if (chunk[0] in chunkPlan) foreach (r; chunk[1]) if (!unimportantMaterials.canFind(cast(Material)r[1])) throw new Exception("Refusing to overwrite chunk at %s with important material %s".format(chunk[0], cast(Material)r[1])); game.chunks = game.chunks .filter!(c => c[0] !in chunkRunPlan) .array; -
CyberShadow revised this gist
May 28, 2024 . 2 changed files with 36 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -186,10 +186,10 @@ void buildThing(ref SaveGame game, Config config) { case ChunkGeometry.flat: return y >= 12 && y < 30 ? Material.empty : Material.dirt; case ChunkGeometry.empty: return Material.empty; } }(); This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,6 +1,7 @@ import std.algorithm.iteration; import std.array; import std.math.rounding; import std.traits; import std.typecons; import ae.utils.json; @@ -121,10 +122,39 @@ struct Hub struct ChunkCoord { int x, y, z; } alias ChunkRunLength = ushort; enum Material : ubyte { empty, dirt, // diggable packedDirt, softGrass, // diggable; with trees grass, indestructibleStone, steelPlates, ceramicTiles, flatSteelPlates, stoneBricks, // looks like cobblestone from above drillGoo, // diggable; user-placed cobblestone, mosaic, // looks like cobblestone from above; black on red carpet, // looks like cobblestone from above; brown on red woodPlanks, crackedCeramicTiles, leakingSteelPlates, empty2, lava, empty3, water, // invisible; makes splashing sounds and screen warp effect when submerged water2, // ditto empty4, // ... lots of water variations go here ... // ... TODO ... stone = 43, crackedStone = 44, } alias ChunkRun = Tuple!( ChunkRunLength, OriginalType!Material, ); alias ChunkCompressedContents = ChunkRun[]; @@ -169,7 +199,7 @@ ChunkContents decompress(const ChunkCompressedContents compressed) auto v = r[1]; foreach (i; 0 .. count) { cube[p / 32 / 32][p / 32 % 32][p % 32] = cast(Material)v; p++; } } -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 61 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,6 @@ import std.algorithm.comparison; import std.algorithm.iteration; import std.algorithm.mutation; import std.algorithm.searching; import std.algorithm.sorting; import std.array; @@ -81,6 +82,14 @@ void buildThing(ref SaveGame game, Config config) auto startWorld = startChunk.toWorld; auto objectY = startWorld[1] + 5.5; // We will place all objects at this height. // Note: these target the landing pad (a chunk that we will clear on the first run only, and not populate) static immutable ChunkCoord[4] busTargets = [ { 5, 0, 5}, { 8, -1, 16}, {19, -1, 11}, {35, -1, 7}, ]; // Lay out the chunk geometry enum ChunkGeometry { flat, empty } @@ -92,6 +101,34 @@ void buildThing(ref SaveGame game, Config config) chunkPlan[ChunkCoord(x, startChunk.y, z)] = ChunkPlan(ChunkGeometry.flat, false); foreach (x; startChunk.x .. startChunk.x + totalChunks) chunkPlan[ChunkCoord(x, startChunk.y, startChunk.z + totalChunks)] = ChunkPlan(ChunkGeometry.flat, true); // Bus auto busChunkZ = startChunk.z + totalChunks + 1; foreach (x; startChunk.x .. startChunk.x + totalChunks) chunkPlan[ChunkCoord(x, startChunk.y, busChunkZ)] = ChunkPlan(ChunkGeometry.flat, false); foreach (i, target; busTargets) { { int x0 = target.x; int x1 = startChunk.x; if (x0 > x1) swap(x0, x1); foreach (x; x0 .. x1 + 1) chunkPlan[ChunkCoord(x, startChunk.y, busChunkZ)] = ChunkPlan(ChunkGeometry.flat, false); } { int z0 = target.z; int z1 = busChunkZ; if (z0 > z1) z0--; else z0++; if (z0 > z1) swap(z0, z1); foreach (z; z0 .. z1 + 1) chunkPlan[ChunkCoord(target.x, startChunk.y, z)] = ChunkPlan(ChunkGeometry.flat, false); } { auto padGeom = target.y >= startChunk.y ? ChunkGeometry.flat : ChunkGeometry.empty; chunkPlan[ChunkCoord(target.x, startChunk.y, target.z)] = ChunkPlan(padGeom, true); } } bool firstRun = !game.nodes.canFind!(node => node.pos.toChunk in chunkPlan && node.pos[1] == objectY); auto chunkRunPlan = chunkPlan @@ -451,6 +488,30 @@ void buildThing(ref SaveGame game, Config config) foreach (HostIndex host; 0 .. numHosts) reconnect(peerPorts[host]); } // The bus foreach (HostIndex host; 0 .. numHosts) { auto exitX = startWorld[0] + terminatorSize + host * cellSize + cellSize * 1/8; // Same as inputFilter auto busLaneWidth = double(chunkSize) / numHosts; auto busExitZ = busChunkZ * chunkSize; auto busZ = busExitZ + host * busLaneWidth + busLaneWidth / 2; auto busEnterLaneWidth = double(chunkSize) / 16; // 1 auto enterX = busTargets[host / 16].x * chunkSize + (host % 16) * busEnterLaneWidth + busEnterLaneWidth / 2; auto enterZ = busTargets[host / 16].z * chunkSize + (busTargets[host / 16].z > busChunkZ ? 0 : 1) * chunkSize; auto busExit = addRelay([exitX, objectY, busExitZ]); auto busFinish = addRelay([exitX, objectY, busZ]); auto busStart = addRelay([enterX, objectY, busZ]); auto busEnter = addRelay([enterX, objectY, enterZ]); reconnect(NodePort(busEnter, 0)); addRelays(NodePort(busEnter, 1), NodePort(busStart, 0)); addRelays(NodePort(busStart, 1), NodePort(busFinish, 0)); addRelays(NodePort(busFinish, 1), NodePort(busExit, 0)); reconnect(NodePort(busExit, 1)); } } void main() -
CyberShadow revised this gist
May 28, 2024 . 1 changed file with 44 additions and 27 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -10,6 +10,7 @@ import std.math.constants; import std.math.rounding; import std.path; import std.stdio : stderr; import std.typecons; import ae.sys.file; import ae.utils.array; @@ -80,6 +81,25 @@ void buildThing(ref SaveGame game, Config config) auto startWorld = startChunk.toWorld; auto objectY = startWorld[1] + 5.5; // We will place all objects at this height. // Lay out the chunk geometry enum ChunkGeometry { flat, empty } struct ChunkPlan { ChunkGeometry geometry; bool firstRunOnly; } ChunkPlan[ChunkCoord] chunkPlan; // Switch foreach (z; startChunk.z .. startChunk.z + totalChunks) foreach (x; startChunk.x .. startChunk.x + totalChunks) chunkPlan[ChunkCoord(x, startChunk.y, z)] = ChunkPlan(ChunkGeometry.flat, false); foreach (x; startChunk.x .. startChunk.x + totalChunks) chunkPlan[ChunkCoord(x, startChunk.y, startChunk.z + totalChunks)] = ChunkPlan(ChunkGeometry.flat, true); bool firstRun = !game.nodes.canFind!(node => node.pos.toChunk in chunkPlan && node.pos[1] == objectY); auto chunkRunPlan = chunkPlan .byKeyValue .filter!(kv => !kv.value.firstRunOnly || firstRun) .map!(kv => tuple(kv.key, kv.value.geometry)) .assocArray; static immutable nullNode = Node([0, 0, 0], [0, 0, 0], 0); // Delete nodes, edges, and objects in the build zone @@ -88,9 +108,9 @@ void buildThing(ref SaveGame game, Config config) { game.nodes = game.nodes.dup; foreach (NodeIndex i, ref node; game.nodes) if (node.pos[1] == objectY && node.pos.toChunk in chunkPlan && chunkPlan[node.pos.toChunk].firstRunOnly == false) { node = nullNode; nodeFreeList ~= i; @@ -112,35 +132,32 @@ void buildThing(ref SaveGame game, Config config) } // scope(success) enforce(nodeFreeList.length == 0, "Still have deleted nodes"); // Make chunks { game.chunks = game.chunks .filter!(c => c[0] !in chunkRunPlan) .array; foreach (chunkPos, geometry; chunkRunPlan) { ChunkContents c; foreach (z, ref plane; c) foreach (y, ref row; plane) foreach (x, ref cell; row) cell = delegate Material { final switch (geometry) { case ChunkGeometry.flat: return y >= 12 && y < 30 ? 0 : 1; case ChunkGeometry.empty: return 0; } }(); game.chunks ~= Chunk(chunkPos, compress(c)); } } static immutable WorldCoord upVector = [0, 1, 0]; -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -66,7 +66,7 @@ void buildThing(ref SaveGame game, Config config) // Cheat to save FPS. Wires start to visually disappear at around 40. enum maxWireLength = 32; enum ChunkCoord startChunk = {x: 11, y: 0, z: -2}; auto totalSize = terminatorSize + -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 1 addition and 15 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -327,19 +327,6 @@ void buildThing(ref SaveGame game, Config config) collision: Filter.Config.Collision.SendBackOutbound, ), ); auto oneWayOutputFilter = addFilter( pos: [x0 + cellSize * 0.725, objectY, z0 + cellSize * 0.4125], angle: PI/2, @@ -366,8 +353,7 @@ void buildThing(ref SaveGame game, Config config) angle: PI, ); addEdge(NodePort(filterInputHub, 1), NodePort(targetCheckFilter, 0)); addEdge(NodePort(targetCheckFilter, 1), NodePort(oneWayOutputFilter, 0)); addEdge(NodePort(oneWayOutputFilter, 1), NodePort(filterOutputHub, 1)); // Link with top/right neighbor -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -74,7 +74,7 @@ void buildThing(ref SaveGame game, Config config) portLinkSize + portLaneSize * numHosts + minPortFilterSize; auto totalChunks = cast(int)ceil(totalSize / chunkSize); totalSize = totalChunks * chunkSize; auto startWorld = startChunk.toWorld; -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 22 additions and 28 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -62,7 +62,10 @@ void buildThing(ref SaveGame game, Config config) enum portLaneSize = 0.25; enum minPortFilterSize = 4; // enum maxWireLength = 4.0; // Cheat to save FPS. Wires start to visually disappear at around 40. enum maxWireLength = 32; enum ChunkCoord startChunk = {x: 5, y: 0, z: 8}; auto totalSize = @@ -200,34 +203,25 @@ void buildThing(ref SaveGame game, Config config) void addRelays(NodePort source, NodePort target, CableColor color = 0) { while (true) { auto sourceCoord = game.nodes[source[0]].pos; auto targetCoord = game.nodes[target[0]].pos; WorldCoord vec = [ targetCoord[0] - sourceCoord[0], targetCoord[1] - sourceCoord[1], targetCoord[2] - sourceCoord[2], ]; auto vecLength = sqrt(vec[0] ^^ 2 + vec[1] ^^ 2 + vec[2] ^^ 2); if (vecLength <= maxWireLength) return addEdge(source, target, color); vec[] /= vecLength; auto relayCoord = sourceCoord; relayCoord[] += vec[] * maxWireLength; auto relay = addRelay(relayCoord); addEdge(source, NodePort(relay, 0), color); source = NodePort(relay, 1); } } -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 19 additions and 83 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -251,21 +251,17 @@ void buildThing(ref SaveGame game, Config config) assert(numAddedEdges <= 1, "Ambiguous reconnect"); } // Create the switch { enum Side { source, target, } NodePort[numHosts][enumLength!Side] cellPorts; // Terminators foreach (side; Side.init .. enumLength!Side) { WorldCoord sidePos(WorldCoord pos) @@ -306,19 +302,12 @@ void buildThing(ref SaveGame game, Config config) addEdge(NodePort(hub, 1), NodePort(relay0, 0)); addEdge(NodePort(relay0, 1), NodePort(relay1, 0)); addEdge(NodePort(relay1, 1), NodePort(hub, 2)); cellPorts[side][host] = NodePort(hub, 0); } } // NxN router cells foreach (HostIndex sourceHost; 0 .. numHosts) foreach (HostIndex targetHost; 0 .. numHosts) { @@ -386,38 +375,18 @@ void buildThing(ref SaveGame game, Config config) addEdge(NodePort(targetCheckFilter, 1), NodePort(killSwitchFilter, 0)); addEdge(NodePort(killSwitchFilter, 1), NodePort(oneWayOutputFilter, 0)); addEdge(NodePort(oneWayOutputFilter, 1), NodePort(filterOutputHub, 1)); // Link with top/right neighbor addRelays(cellPorts[Side.source][sourceHost], NodePort(filterInputHub, 2)); cellPorts[Side.source][sourceHost] = NodePort(filterInputHub, 0); addRelays(cellPorts[Side.target][targetHost], NodePort(filterOutputHub, 0)); cellPorts[Side.target][targetHost] = NodePort(filterOutputHub, 2); } } // Switch edge port to endpoint NodePort[numHosts] peerPorts; foreach (HostIndex host; 0 .. numHosts) { @@ -475,48 +444,15 @@ void buildThing(ref SaveGame game, Config config) addRelays(NodePort(outputToCornerRelay, 1), NodePort(cornerRelay, 0)); addRelays(NodePort(cornerRelay, 1), NodePort(inputOutputSplitHub, 2)); addRelays(cellPorts[Side.source][host], NodePort(inputLoopFilter, 1)); addRelays(cellPorts[Side.target][host], NodePort(outputRelay, 0)); peerPorts[host] = NodePort(inputFilter, 0); } // Reconnect peers foreach (HostIndex host; 0 .. numHosts) reconnect(peerPorts[host]); } } -
CyberShadow revised this gist
May 27, 2024 . 3 changed files with 86 additions and 61 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,13 +1,15 @@ import std.algorithm.comparison; import std.algorithm.iteration; import std.algorithm.searching; import std.algorithm.sorting; import std.array; import std.file; import std.format; import std.math.algebraic; import std.math.constants; import std.math.rounding; import std.path; import std.stdio : stderr; import ae.sys.file; import ae.utils.array; @@ -17,6 +19,37 @@ import ae.utils.meta; import config; import game; /////////////////////////////////////////////////////////////////////////////// alias HostIndex = ubyte; Address.Element[4] toAddressElements(HostIndex index) { return [ cast(Address.Element)((index >> (3 * 2)) & 3), cast(Address.Element)((index >> (2 * 2)) & 3), cast(Address.Element)((index >> (1 * 2)) & 3), cast(Address.Element)((index >> (0 * 2)) & 3), ]; } Address toAddress(HostIndex index, Address.Type type) { return Address(toAddressElements(index), type); } Address wildcardAddress(Address.Type type) { return Address([ Address.Element.Wildcard, Address.Element.Wildcard, Address.Element.Wildcard, Address.Element.Wildcard, ], type); } /////////////////////////////////////////////////////////////////////////////// void buildThing(ref SaveGame game, Config config) { const origGame = game; @@ -466,7 +499,6 @@ void buildThing(ref SaveGame game, Config config) addEdge(ports[sourceHost].inputChain, cells[sourceHost][targetHost].inputDown); } // Output chain foreach (HostIndex sourceHost; 0 .. numHosts) foreach (HostIndex targetHost; 0 .. numHosts) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -34,24 +34,6 @@ Config.Rule parseRule(string line) return Config.Rule(source, target); } bool matches(Address.Element[4] address, Address.Element[4] pattern) { foreach (i, elem; pattern) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,5 @@ import std.algorithm.iteration; import std.array; import std.math.rounding; import std.typecons; @@ -33,24 +35,6 @@ alias CableColor = ubyte; alias PortIndex = ubyte; alias NodeIndex = size_t; struct Address { enum Element @@ -71,6 +55,39 @@ struct Address Type address_type; } alias NodePort = Tuple!( NodeIndex, PortIndex, ); alias Edge = Tuple!( NodePort, NodePort, CableColor, ); enum Infection { Bio, StrongBio, Hack, } struct Endpoint { NodeIndex node; Address address; Nullable!Infection infection; bool disinfection; } struct Relay { NodeIndex node; bool fixed; bool light; } struct Filter { NodeIndex node; @@ -123,7 +140,7 @@ struct SaveGame JSONFragment story; Node[] nodes; Edge[] edges; Endpoint[] endpoints; Relay[] relays; Filter[] filters; JSONFragment testers; @@ -197,29 +214,23 @@ ChunkCoord toChunk(WorldCoord c) /////////////////////////////////////////////////////////////////////////////// Address.Element[4] parseAddress(string str) { Address.Element[4] result; foreach (i, part; str.split(".")) result[i] = { switch (part) { case "*": return Address.Element.Wildcard; case "0": return Address.Element.Zero; case "1": return Address.Element.One; case "2": return Address.Element.Two; case "3": return Address.Element.Three; default: throw new Exception("Invalid address element: " ~ part); } }(); return result; } string toString(Address.Element element) { return "0123*"[element .. element+1]; } string toString(Address.Element[4] address) { return address[].map!toString.join("."); } -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 26 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -19,6 +19,8 @@ import game; void buildThing(ref SaveGame game, Config config) { const origGame = game; // Configuration enum numHosts = 4 ^^ 3; enum terminatorSize = 4.0; @@ -196,6 +198,26 @@ void buildThing(ref SaveGame game, Config config) } } void reconnect(NodePort newPort) { auto prevNumEdges = game.edges.length; auto newNodeIndex = newPort[0]; auto newNode = game.nodes[newNodeIndex]; foreach (oldNodeIndex, oldNode; origGame.nodes) if (oldNode.pos == newNode.pos) { auto oldPort = NodePort(oldNodeIndex, newPort[1]); foreach (oldEdge; origGame.edges) if (oldEdge[0] == oldPort && !nodeDeleted[oldEdge[1][0]]) addEdge(newPort, oldEdge[1]); else if (oldEdge[1] == oldPort && !nodeDeleted[oldEdge[0][0]]) addEdge(oldEdge[0], newPort); } auto numAddedEdges = game.edges.length - prevNumEdges; assert(numAddedEdges <= 1, "Ambiguous reconnect"); } // Create the router { enum Side @@ -459,6 +481,10 @@ void buildThing(ref SaveGame game, Config config) if (sourceHost + 1 == numHosts) addEdge(cells[sourceHost][targetHost].outputRight, ports[targetHost].outputChain); } // Reconnect peers foreach (HostIndex host; 0 .. numHosts) reconnect(ports[host].peer); } } -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 29 additions and 12 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,6 +3,7 @@ import std.algorithm.iteration; import std.algorithm.searching; import std.array; import std.file; import std.format; import std.math.algebraic; import std.math.constants; import std.math.rounding; @@ -41,25 +42,30 @@ void buildThing(ref SaveGame game, Config config) auto startWorld = startChunk.toWorld; auto objectY = startWorld[1] + 5.5; // We will place all objects at this height. static immutable nullNode = Node([0, 0, 0], [0, 0, 0], 0); // Delete nodes, edges, and objects in the build zone // 1. Delete the nodes themselves NodeIndex[] nodeFreeList; { game.nodes = game.nodes.dup; foreach (NodeIndex i, ref node; game.nodes) if (node.pos[0] >= startWorld[0] && node.pos[0] < startWorld[0] + totalSize && node.pos[1] == objectY && node.pos[2] >= startWorld[2] && node.pos[2] < startWorld[2] + totalSize) { node = nullNode; nodeFreeList ~= i; } } // 2. Map deleted nodes auto nodeDeleted = new bool[game.nodes.length]; foreach (NodeIndex i; nodeFreeList) nodeDeleted[i] = true; // 3. Delete affected objects { game.edges = game.edges .filter!(edge => !(nodeDeleted[edge[0][0]] || nodeDeleted[edge[1][0]])).array; game.relays = game.relays .filter!(o => !nodeDeleted[o.node]).array; @@ -68,6 +74,10 @@ void buildThing(ref SaveGame game, Config config) } // scope(success) enforce(nodeFreeList.length == 0, "Still have deleted nodes"); bool firstRun = true; if (nodeFreeList.length) firstRun = false; // Make chunks { enum chunkX0 = startChunk.x; @@ -133,17 +143,24 @@ void buildThing(ref SaveGame game, Config config) return index; } size_t[NodePort] portUsed; size_t numUsedPorts; void usePort(NodePort port) { // if (numUsedPorts == 2248) assert(false, "Here"); assert(port !in portUsed, "Port used: %d".format(portUsed[port])); portUsed[port] = numUsedPorts++; } foreach (edge; game.edges) static foreach (i; 0 .. 2) usePort(edge[i]); void addEdge(NodePort source, NodePort target, CableColor color = 0) { usePort(source); usePort(target); game.edges ~= Edge(source, target, color); } void addRelays(NodePort source, NodePort target, CableColor color = 0) -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 21 additions and 18 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -43,24 +43,30 @@ void buildThing(ref SaveGame game, Config config) bool firstRun = true; static immutable nullNode = Node([0, 0, 0], [0, 0, 0], 0); // Delete nodes, edges, and objects in the build zone NodeIndex[] nodeFreeList; { auto nodeDeleted = new bool[game.nodes.length]; foreach (i, ref node; game.nodes) if (node.pos[0] >= startWorld[0] && node.pos[0] < startWorld[0] + totalSize && node.pos[1] == objectY && node.pos[2] >= startWorld[2] && node.pos[2] < startWorld[2] + totalSize) { node = nullNode; nodeDeleted[i] = true; nodeFreeList ~= i; firstRun = false; } game.edges = game.edges .filter!(edge => !(nodeDeleted[edge[0][0]] || nodeDeleted[edge[1][0]])).array; game.relays = game.relays .filter!(o => !nodeDeleted[o.node]).array; game.filters = game.filters.filter!(o => !nodeDeleted[o.node]).array; game.hubs = game.hubs .filter!(o => !nodeDeleted[o.node]).array; } // scope(success) enforce(nodeFreeList.length == 0, "Still have deleted nodes"); // Make chunks { @@ -93,20 +99,17 @@ void buildThing(ref SaveGame game, Config config) NodeIndex addNode(WorldCoord pos, WorldCoord up = upVector, double angle = 0) { foreach (NodeIndex oldNodeIndex, ref oldNode; game.nodes) if (oldNode.pos == pos) assert(false, "Trying to create node on top of existing node"); NodeIndex index; if (nodeFreeList.length) index = nodeFreeList.shift; else index = game.nodes.length++; game.nodes[index] = Node(pos, up, angle); return index; } NodeIndex addRelay(WorldCoord pos, WorldCoord up = upVector, double angle = 0, bool fixed = false, bool light = false) -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 5 additions and 5 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,8 +1,3 @@ import std.algorithm.comparison; import std.algorithm.iteration; import std.algorithm.searching; @@ -13,6 +8,11 @@ import std.math.constants; import std.math.rounding; import std.path; import ae.sys.file; import ae.utils.array; import ae.utils.json; import ae.utils.meta; import config; import game; -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 5 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,3 +1,4 @@ import ae.sys.file; import ae.utils.array; import ae.utils.json; import ae.utils.meta; @@ -11,7 +12,6 @@ import std.math.algebraic; import std.math.constants; import std.math.rounding; import std.path; import config; import game; @@ -453,10 +453,9 @@ void main() buildThing(game, config); "~/steam/.local/share/tunnet/slot_1.json" .expandTilde .atomicWrite( game.toJson ); } -
CyberShadow revised this gist
May 27, 2024 . 1 changed file with 8 additions and 6 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -130,15 +130,17 @@ void buildThing(ref SaveGame game, Config config) return index; } HashSet!NodePort portUsed; foreach (edge; game.edges) static foreach (i; 0 .. 2) portUsed.add(edge[i]); void addEdge(NodePort source, NodePort target, CableColor color = 0) { assert(source !in portUsed && target !in portUsed, "Port reused"); game.edges ~= Edge(source, target, color); portUsed.add(source); portUsed.add(target); } void addRelays(NodePort source, NodePort target, CableColor color = 0)
NewerOlder