Compare commits

...

3 commits

12 changed files with 345 additions and 0 deletions

4
.gitignore vendored Normal file
View file

@ -0,0 +1,4 @@
.config/
.vscode/
src/bin
src/**/obj

4
build.sh Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
echo "Building..."
exec dotnet build

167
plan.md Normal file
View file

@ -0,0 +1,167 @@
### Network Engineering Simulator - Pseudocode Specification
```plaintext
// GLOBAL STATE
world: 3D voxel space (solid/air)
devices: List<Device> = []
connections: List<Connection> = []
credits: int = 0
technicians: List<Bot> = [free_starter_bot]
// DEVICE TYPES
struct Framework:
id: IP_address (A.B.C.D where 0≤A,B,C,D≤3)
packet_gen_rate: float // packets/sec
struct Router:
ports: [Device|null, Device|null]
struct Hub:
ports: [Device|null, Device|null, Device|null]
rotation: enum{ CLOCKWISE, COUNTERCLOCKWISE }
active_port: int (0,1,2)
// ECONOMY
shop_items = {
"cable": {cost:1, qty:20},
"router": {cost:2, qty:1},
"hub": {cost:10, qty:1},
"technician": {cost:10000, qty:1},
"drill_fuel": {cost:20, qty:100}
}
// CONSTRUCTION SYSTEM
function toggle_networking_mode(enabled):
if enabled:
use_technician_bots()
else:
free_instant_build()
function place_device(type, position):
if networking_mode:
assign_to_technician(type, position)
else:
spawn_device(type, position)
function drill_volume(start, end):
blocks = calculate_blocks(start, end)
if networking_mode:
consume_fuel(blocks)
technician.drill(start, end)
else:
instant_clear_volume(start, end)
function create_connection(devA, devB):
distance = distance(devA.pos, devB.pos)
cable_cost = ceil(distance / 3.0)
if credits < cable_cost: return FAIL
// Ray collision check (ignore shared planes)
if has_collision(devA.pos, devB.pos): return FAIL
credits -= cable_cost
connection = new Connection(devA, devB, cable_cost)
connections.add(connection)
// HUB MANAGEMENT
function connect_to_hub(device, hub, port_index):
hub.ports[port_index] = device
create_connection(device, hub)
function rotate_hubs(): // Called every second
for hub in all_hubs:
if hub.rotation == CLOCKWISE:
hub.active_port = (hub.active_port + 1) % 3
else:
hub.active_port = (hub.active_port - 1) % 3
// PACKET SYSTEM
function generate_packets():
for framework in all_frameworks:
dest = random_valid_ip()
spawn_packet(framework, dest)
function route_packets(): // Called every second
for packet in all_packets:
current = packet.current_device
next = get_next_hop(current, packet.dest)
packet.hops += connection_cost(current, next)
packet.move_to(next)
// ECONOMY & UI
function free_money_button():
if credits < 10:
credits += 100
function calculate_earnings():
for packet in delivered_packets:
credits += BASE_REWARD * packet.hops
// MAIN GAME LOOP
every_frame:
handle_player_input()
render_world()
every_second:
generate_packets()
route_packets()
calculate_earnings()
rotate_hubs()
```
### Key Constants
```plaintext
BASE_REWARD = 1.0 // Credit per hop
IP_RANGE = [0,1,2,3] // Valid IP digits
```
### Simplified Device Behavior
```plaintext
Router:
Input → Output (direct passthrough)
Hub:
Always routes to active_port
Port rotation occurs AFTER packet transfer
Connection:
Cost = ceil(distance/3)
Each connection adds 'cost' hops to packets
```
### Input Handling Pseudocode
```plaintext
on_mouse_click:
if in_build_mode:
place_device(selected_type, world_position)
if in_drill_mode:
drill_volume(selection_start, selection_end)
if in_connect_mode:
create_connection(selected_device1, selected_device2)
if ui_element_clicked("free_money"):
free_money_button()
```
### Collision Detection
```plaintext
function has_collision(posA, posB):
// Ignore collisions on shared planes
if same_x_plane(posA, posB): ignore YZ
if same_y_plane(posA, posB): ignore XZ
if same_z_plane(posA, posB): ignore XY
return raycast(posA, posB) hits non-device solid
```
This specification contains all mechanics in condensed pseudocode format, covering:
- IP-based routing (0-3 digits)
- Cable cost/distance formula
- 1-second packet synchronization
- Networking mode toggle
- Collision-aware connections
- Hop-based economy
- Free money condition
- Device placement logic
- Hub rotation system

4
run.sh Executable file
View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
echo "Running..."
exec dotnet run --no-build --project src/

15
src/Content/Content.mgcb Normal file
View file

@ -0,0 +1,15 @@
#----------------------------- Global Properties ----------------------------#
/outputDir:bin/$(Platform)
/intermediateDir:obj/$(Platform)
/platform:DesktopGL
/config:
/profile:Reach
/compress:False
#-------------------------------- References --------------------------------#
#---------------------------------- Content ---------------------------------#

51
src/Game1.cs Normal file
View file

@ -0,0 +1,51 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace tunnet;
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
public Game1()
{
_graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
}
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
_spriteBatch = new SpriteBatch(GraphicsDevice);
// TODO: use this.Content to load your game content here
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}

BIN
src/Icon.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

BIN
src/Icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

2
src/Program.cs Normal file
View file

@ -0,0 +1,2 @@
using var game = new tunnet.Game1();
game.Run();

43
src/app.manifest Normal file
View file

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="tunnet"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of the Windows versions that this application has been tested on and is
is designed to work with. Uncomment the appropriate elements and Windows will
automatically selected the most compatible environment. -->
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
</windowsSettings>
</application>
</assembly>

33
src/tunnet.csproj Normal file
View file

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<RollForward>Major</RollForward>
<PublishReadyToRun>false</PublishReadyToRun>
<TieredCompilation>false</TieredCompilation>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
<ApplicationIcon>Icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<None Remove="Icon.ico" />
<None Remove="Icon.bmp" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Icon.ico">
<LogicalName>Icon.ico</LogicalName>
</EmbeddedResource>
<EmbeddedResource Include="Icon.bmp">
<LogicalName>Icon.bmp</LogicalName>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.*" />
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.*" />
</ItemGroup>
<Target Name="RestoreDotnetTools" BeforeTargets="CollectPackageReferences">
<Message Text="Restoring dotnet tools (this might take a while depending on your internet speed and should only happen upon building your project for the first time, or after upgrading MonoGame, or clearing your nuget cache)" Importance="High" />
<Exec Command="dotnet tool restore" />
</Target>
</Project>

22
tunnet.sln Normal file
View file

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "tunnet", "src/tunnet.csproj", "{728D0B55-232F-4C2B-A31F-04EA4BFF4209}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{728D0B55-232F-4C2B-A31F-04EA4BFF4209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{728D0B55-232F-4C2B-A31F-04EA4BFF4209}.Debug|Any CPU.Build.0 = Debug|Any CPU
{728D0B55-232F-4C2B-A31F-04EA4BFF4209}.Release|Any CPU.ActiveCfg = Release|Any CPU
{728D0B55-232F-4C2B-A31F-04EA4BFF4209}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal