aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKatharina Fey <kookie@spacekookie.de>2020-01-29 06:50:10 +0000
committerKatharina Fey <kookie@spacekookie.de>2020-01-29 06:50:10 +0000
commit12fdd7e0a81e6a079c188df90802ac379bd733b3 (patch)
treefe479652e60b3b989495c06a654eb6538cf1ddc9
parentb38baf21dbe44bbbe464a97529a2e27424339119 (diff)
Initial code dump
-rw-r--r--src/data.rs175
-rw-r--r--src/main.rs9
-rw-r--r--src/map.rs19
-rw-r--r--src/stats.rs80
4 files changed, 283 insertions, 0 deletions
diff --git a/src/data.rs b/src/data.rs
new file mode 100644
index 000000000000..b1c248860b02
--- /dev/null
+++ b/src/data.rs
@@ -0,0 +1,175 @@
+//! Data structures for the game
+
+use async_std::sync::Arc;
+use std::{
+ collections::BTreeMap,
+ sync::atomic::{AtomicBool, AtomicU32, AtomicU16},
+};
+
+/// A node is a computer on the network graph
+///
+/// It's owned by a player, and has some upgrade state, as well as
+/// base stats.
+pub struct Node {
+ /// Each node has a unique ID by which it's addressed
+ id: u16,
+ /// The current health
+ health: AtomicU32,
+ /// The max health
+ max_health: AtomicU32,
+ /// The owner of this node
+ owner: Owner,
+ /// Upgrade state
+ type_: Upgrade,
+ /// Number of links on the map
+ links: u8,
+ /// Active link states
+ link_states: Vec<Arc<Link>>,
+ /// Input buffer
+ buffer: Vec<Packet>,
+}
+
+/// A one-to-one link between two nodes
+pub struct Link {
+ /// This link ID
+ id: u16,
+ /// Node 1
+ a: u16,
+ /// Node 2
+ b: u16,
+ length: u32,
+ /// Packets present on this link
+ pp: Vec<(Packet, AtomicU32)>,
+}
+
+/// A packet going across the network
+pub struct Packet {
+ /// The packet ID
+ id: u16,
+ /// Declare this packet to be removed
+ dead: AtomicBool,
+ /// Each packet is owned by a player
+ owner: Arc<Player>,
+ /// What type of packet this is
+ data_: PacketType,
+}
+
+/// A player who's having fun
+pub struct Player {
+ /// A unique player ID (per match)
+ id: u16,
+ /// The player name
+ name: String,
+ /// Player color
+ color: Color,
+}
+
+/// Optionally, players can create teams
+pub struct Team {
+ /// Name of the team
+ name: String,
+ /// Unified color of the team
+ color: Color,
+ /// All team members by their ID
+ roster: Vec<u16>
+}
+
+/// An RGB color without alpha
+pub struct Color(u8, u8, u8);
+
+/// Describes ownership state
+pub enum Owner {
+ /// Nobody owns this
+ Neutral,
+ /// A player owns this
+ Player(Player),
+}
+
+/// Encodes upgrade level without numbers
+pub enum Level {
+ /// 1
+ One,
+ /// 2
+ Two,
+ /// 3 (wow)
+ Three,
+}
+
+/// Describes upgrade state
+pub enum Upgrade {
+ /// A basic node
+ Base,
+ /// Battle (attack/defence) nodes
+ Guard(Level),
+ /// These nodes make money
+ Compute(Level),
+ /// Good at packet switching
+ Relay(Level),
+}
+
+/// Possible types of packets
+pub enum PacketType {
+ /// A keepalive packet
+ ///
+ /// These are sent by all nodes if their neighbours are either
+ /// friendly or neutral, and used to keep the network alive.
+ /// Sending them costs nothing, and when they are received, they
+ /// yield a small amount of funds, and restoring health of a node.
+ Ping,
+ /// A non exploit capture
+ ///
+ /// This is a packet that can be sent out by any node (except a
+ /// switch) to claim a neutral node on the network. The path to
+ /// the node needs to consist only of friendlies, and if an enemy
+ /// node processes this type, nothing happens.
+ Capture,
+ /// A compute packet
+ ///
+ /// The first value is the target compute value, which each
+ /// compute node adds on to. The second value is the current. If
+ /// a compute packet passes through a compromised or enemy node,
+ /// it might subtract from the second value, before palling it on.
+ Compute {
+ max: u16,
+ curr: AtomicU16,
+ step: u16,
+ },
+ /// A special wrapper packet generated by guards
+ ///
+ /// Sometimes, when a hostily attack packet encounters a guard, it
+ /// manages to capture the attack, and forwards it to a random
+ /// compute node. If the node manages to handle the packet,
+ /// without it getting dropped in the meantime), it yields a
+ /// specified reward, like a computation would.
+ Payload {
+ inner: Box<PacketType>,
+ reward: u16
+ },
+ /// A reset attack packet
+ ///
+ /// When encountering a hostile node, it will make that node drop
+ /// all packets in it's buffers.
+ Reset,
+ /// Cross-node-scripting attack
+ ///
+ /// Decreases the strength of a node, also having a small chance
+ /// of spawning a new packet into a random output buffer. When
+ /// applied to a neutral node, it makes capturing nodes go faster.
+ CNS,
+ /// Node-in-the-middle attack
+ ///
+ /// Infect the routing behaviour of a node to route all traffic to
+ /// a specified enemy node instead
+ Nitm,
+ /// Virus infection attack
+ ///
+ /// Infects a node to capture it's earnings, both active and
+ /// passive, for a short time, without taking on it's costs.
+ Virus,
+ /// A total control exploit
+ ///
+ /// This is very hard to do, and a node will basically always
+ /// resist it, but if successful, transforms the node into a guard
+ /// node and yields control to the attackinng player.
+ TakeOver,
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 000000000000..873a84e684a7
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,9 @@
+#![allow(warnings)]
+
+mod data;
+mod map;
+mod stats;
+
+fn main() {
+ println!("Hello, world!");
+}
diff --git a/src/map.rs b/src/map.rs
new file mode 100644
index 000000000000..31bc9a3dbe38
--- /dev/null
+++ b/src/map.rs
@@ -0,0 +1,19 @@
+//! Implements a map graph and world logic
+
+use crate::data::{Node, Link};
+use std::collections::BTreeMap;
+use async_std::sync::Arc;
+
+
+/// A map that people fight on
+///
+/// A map is defined by it's graph relationships, but also where on
+/// the map nodes are placed, how much spacing there is, etc. All
+/// this information is encoded in the same structs because it's
+/// static, and just more convenient.
+pub struct Map {
+ /// Node IDs mapped to node objects
+ nodes: BTreeMap<u16, Arc<Node>>,
+ /// Link IDs mapped to link objects
+ links: BTreeMap<u16, Arc<Link>>,
+}
diff --git a/src/stats.rs b/src/stats.rs
new file mode 100644
index 000000000000..d679c3e7d38c
--- /dev/null
+++ b/src/stats.rs
@@ -0,0 +1,80 @@
+//! This file contains balancing data
+//!
+//! Each type of node and packet is being balanced for different
+//! factors. The stats are just returned by these functions.
+//! Whenever there is some effect that can happen in the game, it's
+//! value (strength) will be derived from here.
+
+/// The cost of doing business
+pub mod cost {
+ use crate::data::{Level, PacketType, Upgrade};
+
+ /// Takes the current node and desired upgrade level
+ pub fn upgrade(curr: &Upgrade, want: &Upgrade) -> u32 {
+ use self::{Level::*, Upgrade::*};
+ match (curr, want) {
+ // Base upgrades
+ (Base, Guard(One)) => 30,
+ (Base, Compute(One)) => 25,
+ (Base, Relay(One)) => 20,
+
+ // Guards
+ (Guard(One), Guard(Two)) => 50,
+ (Guard(Two), Guard(Three)) => 75,
+
+ // Compute is expensive
+ (Compute(One), Compute(Two)) => 50,
+ (Compute(Two), Compute(Three)) => 95,
+
+ // Relays
+ (Relay(One), Relay(Two)) => 35,
+ (Relay(Two), Relay(Three)) => 55,
+
+ // Can't touch this
+ (_, _) => unreachable!(),
+ }
+ }
+
+ /// Sending certain packets costs money, let's find out how much
+ pub fn packets(node: &Upgrade, packet: &PacketType) -> u32 {
+ use {
+ Level::*,
+ PacketType::*,
+ Upgrade::{Base, Compute as Cc, Guard, Relay},
+ };
+ match (node, packet) {
+ // Sending pings is free forever
+ (_, Ping) => 0,
+ // Capture packets always cost the same
+ (_, Capture) => 15,
+
+ // The cost of compute packets increases with levels
+ // because their efficiency increases more dramatically
+ (Cc(One), Compute { .. }) => 7,
+ (Cc(Two), Compute { .. }) => 14,
+ (Cc(Three), Compute { .. }) => 21,
+
+ // Payloads can only be sent from guards
+ (Guard(_), Payload { .. }) => 12,
+
+ // Resets are relatively cheap
+ (Guard(One), Reset) => 16,
+ (Guard(Two), Reset) => 32,
+ (Guard(Three), Reset) => 48,
+
+ (Guard(One), Nitm) => 28,
+ (Guard(Two), Nitm) => 64,
+ (Guard(Three), Nitm) => 148,
+
+ (Guard(One), Virus) => 18,
+ (Guard(Two), Virus) => 40,
+ (Guard(Three), Virus) => 60,
+
+ // Only level 3 guards can send takeovers
+ (Guard(Three), TakeOver) => 256,
+
+ // Can't touch this
+ (_, _) => unreachable!()
+ }
+ }
+}