Skip to content

Instantly share code, notes, and snippets.

@pjmagee
Created December 28, 2023 11:44
Show Gist options
  • Select an option

  • Save pjmagee/ab5bb8185f838ac13d474ca066015318 to your computer and use it in GitHub Desktop.

Select an option

Save pjmagee/ab5bb8185f838ac13d474ca066015318 to your computer and use it in GitHub Desktop.
My scrappy nodes generator for a text based space rpg
void Main()
{
Galaxy galaxyNode = new Galaxy() { Name = "The galaxy", NodeType = NodeType.Galaxy };
foreach(var regionName in Enumerable.Range(0, 5).Select(x => $"Region {x}"))
{
SpaceRegion spaceNode = new SpaceRegion { Name = regionName, NodeType = NodeType.SpaceRegion };
foreach (var sectorName in Enumerable.Range(0, 3).Select(x => $"Sector : {x}"))
{
SpaceSector spaceSectorNode = new SpaceSector { Name = sectorName, Parent = spaceNode, NodeType = NodeType.SpaceSector };
foreach (var starSystemName in Enumerable.Range(0, 3).Select(x => $"System: {x}"))
{
StarSystem starSystemNode = new StarSystem { Name = starSystemName, Parent = spaceSectorNode, NodeType = NodeType.StarSystem };
foreach(var planetName in Enumerable.Range(0, Random.Shared.Next(10)).Select(x => $"Planet: {x}"))
{
Planet planetNode = new Planet { Name = planetName, Parent = starSystemNode, NodeType = NodeType.Planet };
foreach(var planetRegionName in Enumerable.Range(0, Random.Shared.Next(10)).Select((i, x) => $"Region: {i}"))
{
PlanetRegion planetRegionNode = new PlanetRegion { Name = planetRegionName, Parent = planetNode, NodeType = NodeType.PlanetRegion };
foreach (var planetAreaName in Enumerable.Range(0, Random.Shared.Next(10)).Select(x => $"Area: {x}"))
{
NodeType[] areaTypes = [NodeType.Settlement, NodeType.Desert, NodeType.Wasteland, NodeType.Canyon, NodeType.Plains, NodeType.Oasis, NodeType.Graveyard, NodeType.Jungle, NodeType.Savanna, NodeType.Crater];
var nodeType = areaTypes.OrderBy(x => Random.Shared.Next()).First();
PlanetArea planetAreaNode = new PlanetArea { Name = nodeType.ToString(), Parent = planetRegionNode, NodeType = NodeType.PlanetArea };
if (nodeType == NodeType.Settlement)
{
var settlementType = Settlements.OrderBy(x => Random.Shared.Next()).First();
var settlement = new Settlement { Name = "Settlement Name", Parent = planetAreaNode, NodeType = settlementType };
if (settlementType == NodeType.City)
{
settlement.AddChild(new Node { Name = "Hospital", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Market", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Cantina", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Starport", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Government Offices", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Clone Center", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "City Hall", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Garage", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Library", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Jedi Temple", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = FactoryNameGenerator.GenerateFactoryName(), NodeType = NodeType.POI });
}
else if (settlementType == NodeType.Outpost)
{
settlement.AddChild(new Node { Name = "Small Apartment Block", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Small Shack", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Clone Center", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Labratory", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = FarmNameGenerator.GenerateFarmName(), NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = FarmNameGenerator.GenerateFarmersMarketName(), NodeType = NodeType.POI });
}
else if (settlementType == NodeType.Town)
{
settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Town Hall", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Clone Center", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Small Market", NodeType = NodeType.POI });
}
else if (settlementType == NodeType.Village)
{
settlement.AddChild(new Node { Name = FarmNameGenerator.GenerateFarmersMarketName(), NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Village hall", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = JunkyardNameGenerator.GenerateJunkyard(), NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Green Houses", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Village Hall", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Low-rise Apartment Block", NodeType = NodeType.POI });
}
else if (settlementType == NodeType.Settlement)
{
settlement.AddChild(new Node { Name = "Shuttle", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = "Small Market", NodeType = NodeType.POI });
settlement.AddChild(new Node { Name = FactoryNameGenerator.GenerateFactoryName(), NodeType = NodeType.POI });
}
planetAreaNode.AddChild(settlement);
}
else if (planetAreaNode.NodeType == NodeType.Desert)
{
planetAreaNode.AddChild(new Node { Name = "Large Cave System", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Sand dunes", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Sand storm", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Wasteland)
{
planetAreaNode.AddChild(new Node { Name = "Icy Cavern", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Canyon)
{
planetAreaNode.AddChild(new Node { Name = "Camp", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Plains)
{
planetAreaNode.AddChild(new Node { Name = "Abandoned Ranch", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Homestead", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Temple", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Oasis)
{
planetAreaNode.AddChild(new Node { Name = "Homestead", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Lavish Temple", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Graveyard)
{
planetAreaNode.AddChild(new Node { Name = "Shack", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Cryogen Capsules", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Underground Crypts", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Jungle)
{
planetAreaNode.AddChild(new Node { Name = "Lively ave", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Savanna)
{
planetAreaNode.AddChild(new Node { Name = "Calm Herbivors", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Crater)
{
planetAreaNode.AddChild(new Node { Name = "Mining Droids", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Excavation", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Flats)
{
planetAreaNode.AddChild(new Node { Name = "Homestead", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Mining Post", NodeType = NodeType.POI });
}
else if (planetAreaNode.NodeType == NodeType.Forest)
{
planetAreaNode.AddChild(new Node { Name = "Cave", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Hidden Cabin", NodeType = NodeType.POI });
planetAreaNode.AddChild(new Node { Name = "Abandoned Cabin", NodeType = NodeType.POI });
}
planetRegionNode.AddChild(planetAreaNode);
}
planetNode.AddChild(planetRegionNode);
}
starSystemNode.AddChild(planetNode);
}
spaceSectorNode.AddChild(starSystemNode);
}
spaceNode.AddChild(spaceSectorNode);
}
galaxyNode.AddChild(spaceNode);
}
galaxyNode.GetAllNodes().Where(x => x.NodeType >= NodeType.Planet).Dump(1);
}
public class HasSomething
{
public void Test()
{
var hasHospital = Random.Shared.Next(2) > 0;
var hasTownHall = Random.Shared.Next(2) > 0;
var hasCantina = Random.Shared.Next(2) > 0;
var hasShuttle = Random.Shared.Next(2) > 0;
var hasSchool = Random.Shared.Next(2) > 0;
var hasLibrary = Random.Shared.Next(2) > 0;
var hasShop = Random.Shared.Next(2) > 0;
var hasMarket = Random.Shared.Next(2) > 0;
var hasSpacePort = Random.Shared.Next(2) > 0;
var hasGarage = Random.Shared.Next(2) > 0;
var hasJediTemple = Random.Shared.Next(2) > 0;
var hasArmory = Random.Shared.Next(2) > 0;
var hasGovernmentOffice = Random.Shared.Next(2) > 0;
var hasTrainingFacility = Random.Shared.Next(2) > 0;
var hasAnimalPens = Random.Shared.Next(2) > 0;
var hasResidential = Random.Shared.Next(2) > 0;
var hasMilitary = Random.Shared.Next(2) > 0;
var hasTransportation = Random.Shared.Next(2) > 0;
var hasAgricultural = Random.Shared.Next(2) > 0;
var hasIndustrial = Random.Shared.Next(2) > 0;
}
}
public class WaterNameGenerator
{
private static string[] Adjectives = { "Aquatic", "Blue", "Clear", "Deep", "Fresh", "Glistening", "Hydroelectric", "Hydrophilic", "Hydrophobic", "Hydrothermal", "Icy", "Liquid", "Misty", "Oceanic", "Pristine", "Reflective", "Refreshing", "Saline", "Seabed", "Seaweed", "Shiny", "Stormy", "Tidal", "Turbulent", "Underwater", "Whirlwind", "Wavy" };
public static string GenerateRiverName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " River";
public static string GenerateLakeName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Lake";
}
public class FactoryNameGenerator
{
private static string[] Adjectives = { "Automated", "Busy", "Chemical", "Clean", "Efficient", "Electrical", "Heavy", "Industrial", "Massive", "Mechanical", "Noisy", "Oil", "Powerful", "Robotic", "Smelly", "Smokey", "Steel", "Technological", "Toxic", "Vast" };
public static string GenerateFactoryName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Factory";
}
public class JunkyardNameGenerator
{
public static string[] Adjectives = { "Abandoned", "Busted", "Crumbling", "Decrepit", "Derelict", "Dilapidated", "Disheveled", "Dismantled", "Fallen", "Grimy", "Grotty", "Neglected", "Old", "Overgrown", "Rundown", "Scrappy", "Shabby", "Tattered", "Torn", "Trashed", "Weathered" };
public static string GenerateJunkyard() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Junkyard";
}
public class FarmNameGenerator
{
private static string[] Adjectives = { "Agricultural", "Blossoming", "Bountiful", "Country", "Fertile", "Flourishing", "Green", "Lively", "Lush", "Natural", "Organic", "Plentiful", "Productive", "Rich", "Rustic", "Scenic", "Secluded", "Spring", "Thriving", "Vibrant", "Wooded" };
public static string GenerateFarmName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Farm";
public static string GenerateFarmersMarketName() => Adjectives[Random.Shared.Next(Adjectives.Length)] + " Farmers Market";
}
public enum NodeType
{
// Space
Galaxy,
Space,
SpaceRegion,
SpaceSector,
StarSystem,
SpaceStation,
// Planetary
Planet,
PlanetRegion,
PlanetArea,
// Points of Interest (POI)
POI,
// Landscapes
Desert,
Jungle,
MountainRange,
Crater,
Reefs,
Flats,
Plains,
Oasis,
Canyon,
Forest,
Graveyard,
Wasteland,
Savanna,
// Settlements
Homestead,
Settlement,
City,
Town,
Village,
Outpost,
// Agriculture
Farm,
Fields,
Marsh,
Lagoon,
// Natural Features
Spires,
Ridge,
Rainforest,
Plateau,
Water,
Rural,
Wilderness,
// Ruins and Water Bodies
Ruins,
River,
Lake,
// Default
None
}
public List<NodeType> Settlements = [NodeType.Homestead, NodeType.Settlement, NodeType.City, NodeType.Town, NodeType.Village, NodeType.Outpost];
public class NPC : IVisitor, IEquatable<NPC>
{
public string Name { get; set; }
public bool Equals(NPC? other) => Name.Equals(other?.Name);
}
public interface IVisitor { }
public interface ITangible { }
public interface INode
{
Guid Id { get; }
string Name { get; }
INode Parent { get; }
HashSet<INode> Siblings { get; }
HashSet<INode> Children { get; }
HashSet<INode> Ancestors { get; }
NodeType NodeType { get; }
}
public class Node : IEquatable<Node>, INode
{
public Guid Id { get; set; }
public string Name { get; set; }
public INode Parent { get; set; }
public HashSet<Node> Siblings { get; set; }
public HashSet<Node> Children { get; set; }
public HashSet<Node> Ancestors { get; set; }
public virtual string[] Adjectives { get; }
public List<IVisitor> Visitors { get; } = new();
public List<ITangible> Tangibles { get; } = new();
public virtual bool CanVisit => false;
public string Path
{
get
{
List<string> names = new List<string>() { Name };
INode current = this.Parent;
while(current != null)
{
names.Add(current.Name);
current = current.Parent;
}
return string.Join(" > ", names.AsEnumerable().Reverse());
}
}
HashSet<INode> INode.Siblings { get => Siblings.ToHashSet<INode>(); }
HashSet<INode> INode.Children { get => Children.ToHashSet<INode>(); }
HashSet<INode> INode.Ancestors { get => Ancestors.ToHashSet<INode>();}
public NodeType NodeType { get; set; } = NodeType.None;
public Node()
{
Id = Guid.NewGuid();
Siblings = new HashSet<Node>();
Children = new HashSet<Node>();
Ancestors = new HashSet<Node>();
}
public override string ToString() => Name;
public void AddChild(Node child)
{
child.Parent = this;
Children.Add(child);
UpdateHierarchy(child);
UpdateHierarchy(this);
}
public bool IsNeighbor(Node other) => Ancestors.Intersect(other.Ancestors).Any();
private void UpdateHierarchy(Node child)
{
child.Siblings = Children.Where(c => c != child).ToHashSet();
child.Ancestors = Ancestors.Concat(new[] { this }).ToHashSet();
foreach (var grandchild in child.Children)
{
grandchild.Ancestors = child.Ancestors.Concat(new[] { child }).ToHashSet();
UpdateHierarchy(grandchild);
}
}
public bool Equals(Node? other) => Id.Equals(other?.Id);
public List<Node> GetAllNodes()
{
var nodes = new List<Node> { this };
foreach (var child in Children)
{
nodes.AddRange(child.GetAllNodes());
}
return nodes;
}
}
public class Galaxy : Node { }
public class SpaceRegion : Node {}
public class SpaceSector : Node{ }
public class StarSystem : Node { }
public class Structure : Node { }
public class Planet : Node { }
public class PlanetRegion : Node { }
public class PlanetArea : Node { }
public class Settlement : PlanetArea { }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment