Got the trade classification tables and service added. And while it seems to be working, I noticed an interesting issue in my world generator: it created a world of size 0 but an atmosphere of 6. Obviously, that is not right. Two ways of fixing it - just hardcode a check for that (and also cap the hydrographics at 1 if the atmosphere is 0) or figure out how to make that a configurable thing. After all - Larry Niven's The Integral Trees was basically an atmosphere around...err, something. I read it a long time ago. But there was no planet. For the moment I'll hardcode those checks and hopefully figure a way to configure additional setting rules. I am a firm believer in the user should be able to do what they want.


Which is also why I've added TL to the trade classification system: you may want to be able to add trade codes for high-tech or something. And all this will also feed into the to-be-written trade generator. Which years ago, my 1st version of this actually grabbed all systems within the jump range of the ship and gave all the possible cargos. 20+ years ago...yeah, I keep rewriting the wheel so to speak. But the trade rules of course get impacted by the trade classifications. Worry about that later.
Now, the architecture of the system is SOA - Service Oriented Architecture. With dependency injection, which is a bit confusing until you get your head wrapped around it. It can also make for some pretty complicated initializers. The planet controller, that bit of code that sends you to the correct planet view, needs to be able to access a lot of things. So that controller startup looks like this:

I am basically injecting a bunch of repositories and services that this controller needs. It seems like a lot, but each repository is responsible for 1 table, each service does 1 thing (though the utility service is more of a kitchen sink for things used across the application). While it makes some things a bit more complicated, each piece is like a LEGO piece: it only does one thing mostly. It makes maintenance easier as each piece is a lot smaller and easier to get your head wrapped around. Plus things are a lot more independent, so the code is more resilient as it is what they call "loosely couple". Anyway....a view of what goes into the sausage and probably not interesting to anyone other than, well, me. But I am okay with that!
The trade classification service is pretty simple: it takes in a world UWP (not the actual planet model but a simple UWP string like A123456-8). It goes through and makes sure the various attributes all fit. Code is in the repo here for that service. So, in theory I could write a UWP trade API to get the trade classifications from the UWP....which I think I will do. There should also be some validation on the input - think I have that in the previous software I played with. As it will break the application if the UWP is not correct at least in terms of the number of characters. I then inject that trade classification service into the planet controller so it has access to it, and to have the planet's trade classifications show up, I basically add a variable (a list of trade classifications) to pass along to the view:
// GET: TPlanets/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
return NotFound();
var tPlanet = await _repo.GetByID(id.Value);
if (tPlanet == null)
return NotFound();
ViewBag.TradeClassifications = await _tradeClassificationService.FindTradeClassifications(tPlanet.UWP);
if (ViewBag.TradeClassifications == null)
ViewBag.TradeClassifications = new List<TradeClassification>() { new TradeClassification() { Name = "none" } } ;
return View(tPlanet);
}
And then the view just cycles through those (the "tradeClassifications" variable gets set at the top of the view; these are cshtml files, basically HTML with c# added. Stuff with the @ are c# lines of code):
<h5>Trade Classifications</h5>
<div class="row"
<ul>
@if (tradeClassifications != null)
foreach (var t in tradeClassifications)
{
<li>@t.Name</li>
}
</ul>
</div
Also, most things are asynchronous. While not particularly critical in this small system with a local SQLite DB attached, it is what I am used to. It keeps the main thread from getting bogged down. The awaits just say do this, and while the main thread can handle other requests, when the task we're waiting on is done the code starts back up there. I think it is like javascript's promises and a few other languages that handle background tasking as a "first citizen" sort of thing.
I also realize I want to add notes for the planets. I can either add a note field to the table or add a generic notes table and be able to attach to planets, systems, and subsectors. More stuff to think about. And may add associated trade classification records for a system for things like subsector capital. Not sure about that yet. But as it will impact trade rules, it should probably be yet another table (planet ID and trade classification ID, so planets can have many trade classifications beside those we can calculate. Yeah, writing software requires thinking about a lot of things and how they all link together. A lot like running an RPG!)
And had time tonight as gaming got cancelled - GM was sick :( I really should have poked a bit for the Saturday game coming up and start looking at the Brass Rings for part 2. I'm going to run that game for the Monday night group soon. But this was fun, even after a full day of doing basically doing the same thing at work)
https://traveller-ct.blogspot.com/2025/04/traveller-system-generator-part-1-of.html
https://traveller-ct.blogspot.com/2025/04/traveller-system-generator-part-2-of.html
https://traveller-ct.blogspot.com/2025/04/traveller-system-generator-part-3-of.html
https://traveller-ct.blogspot.com/2025/04/traveller-system-generator-part-4-of.html
https://traveller-ct.blogspot.com/2025/04/traveller-system-generator-part-5-and.html
https://traveller-ct.blogspot.com/2025/04/traveller-system-generator-part-6.html
Part 7 towards the bottom here
https://traveller-ct.blogspot.com/2025/05/traveller-system-generator-part-8.html
https://traveller-ct.blogspot.com/2025/05/traveller-system-generator-part-9.html