• Welcome to the new COTI server. We've moved the Citizens to a new server. Please let us know in the COTI Website issue forum if you find any problems.

Starship Design using REST Microservices

robject

SOC-14 10K
Admin Award
Marquis
I've created a microservice that creates starship components.

It currently builds sensors, weapons, hulls, and drives. The process is lightly data-driven: a client doesn't need to know much about the data, but it does need to know how to talk to the API, and of course needs to know some things about Traveller.

https://github.com/bobbyjim/acs-builder
 
Last edited:
How about something trivial like Java?

It works on many platforms, is well-supported, and will probably remain well-supported for quite some time.

Unless the purpose is to play with and learn the new hotness, of course.
 
So I have to rewrite my starship design app, from scratch.

What do you think about a container-driven microservice using Go?

* * *

I have the configuration files for reuse, which contains ALL of the data, and even one of the formulas, so there's a starting point.

The hot thing at work is stateless little service endpoints that talk via REST. And since that sounds fun, AND since starship design deals in a bunch of little components, that's probably how I'll do it.

* * *

So I'll open up the discussion for ALL THINGS related to starship design software.

So, what's the plan.

Have all of the state in a single page web app, and use the services for individual calculations?

How do you plan on saving the ships and works in progress?

I can't see much need for an actual back end service for this stuff, but if that floats your boat...err...starship, then yippy kay aye.

If you want to learn Go, learn Go. Language choice has no impact on your end result, particularly in this case -- it's purely a personal choice.

If I were comfortable with the browser environment and javascript, I would do it as a single page, static app. Download the app, run it in the browser, host it on github. No server maintenance, users should be able to save and load their files locally, etc.

But, I'm not, so I don't. I look at the web space and just cower in a dark corner. The complexity of the barrier to entry with all of the variety is simply daunting to me, so I stay away.

I just hang out in my little Java world.

If I were to do such an app, it would be something where you can just add elements with a few back end rules.

You have to select a hull (which kind of sets the baseline for everything). After that, start adding systems. 1 Jump drive, heck 2 jump drives, extra power plant, 3 spinal mounts, etc.

All sorts of obscenities could be created that are not RAW allowed. But the important thing is that you have a core functionality that lets you just add and change stuff.

Spreadsheets are REALLY GOOD at this, but they tend to be rigid. As long as you're in your comfortable box, it's all good. How many spreadsheet builders let you add another power plant, for example?

So, having the not-quite-a-spreadsheet ability to add items that are interrelated is fundamental.

I should be able to drag and drop a brace of 50 dTon cutters in to my ship design, with the design updating mass and cost etc. If I could "double click" on the cutter to see it's design, that's a whoo-hoo right there.

Once you have that fundamental base, then you have a wizard that lets you pick the major components: Select J-Drive, M-Drive, P-Plant, add weapons and screens, it auto computes crew and stateroom requirements. Basically, it pre-fills out the "anything goes" "not-a-spreadsheet" that you already have. Then folks can tweak it.

But I wouldn't back end service any of that personally. Seems like a lot of work for little gain.
 
If it's a microservice language does not matter.

API's with useful documentation however will matter.

To answer a couple of the observations above, a micro-service only does a portion of the job and is designed to be communicated with (ie. data in, make a change, data out) through an API and generate predictable outcomes. Other applications (or microservices) handle the rest, including generating the user web interface.

This allows significant decoupling of the various parts of the application. In particular one person does not need to build the entire thing from scratch. If there are services or microservices that do a good enough job on aspects, use them and spend your creative time on the bits that matter to you. @whartung describes a wizzy front end that I would love to see. It is more likely to come about if the rest of the task is freely available and can be built on.

I had great plans before real life took over again. One of them involved using the Traveller Atlas's really good API's to front end the ability for the user/captain to move starships from system to system.

Being hosted in a container (typically Docker) means the microservice can be scaled to meet demand (more instances created) and is easily portable between hosts (eg. to upgrade to better CPU and memory). It also means instances of a single microservice can be hosted by multiple people, providing redundancy. This is helped by the next person not having to know the contents (its containerised) making the choice of language irelevent. The only important bit is the API and what it does.

Very supportive, and learn Go. I've not used it, but have only heard good things.
 
So, my current app is attached. It's for OSX... I probably have the generic installer somewhere... You'll also need the Adobe AIR runtime, and then the app should run.

It's a thing of beauty. Tabs, sliders, drag and drop, single application, configuration files out the wazzoo. The data is all external. ALL of it. Save and load to YAML, XML, JSON. Dump readable format to HTML and Text. Shove it onto a D1541 image too by golly.

Absolutely fantastic.

But it's 10 years old, and Flex is dead, and it reached its service end in 2017 or 2018. After that, I couldn't update and recompile the code.

And some of the formula are not current.

That's what's killing the app.

* * *

The main thing I thought of was: I get this into services, and I don't have to write the UI. Or rather, the UI becomes separated from the service code. Since UI SOTA changes more frequently than anything else, that's the bit I want isolated.

Service code in Go seems pretty easy -- what I've seen at least, and I think the dumber the services, the better. As you mentioned, the UI is where the slickness is. Go is just my preference today. SpringBoot is perfectly fine.

And yeah, I was thinking of a Container as well. We're allowed to upload images to DockerHub. That's first a storage solution, but second a distribution solution. If you need a ship design API, whoomp, there it is.
 

Attachments

  • T5DesktopShipyard.app.zip
    1.3 MB · Views: 1
Let's see if I can attach the Windows version here.
 

Attachments

  • T5DesktopShipyard.zip
    1.3 MB · Views: 2
Have all of the state in a single page web app, and use the services for individual calculations?

The design is loaded into the UI via a JSON design file, worked on by the app, then saved back to a JSON design file when done or at a stopping point.

One file per ship.

If a squadron builder is needed, that's a new application that manipulates several of those files, and creates its own "squadron" metafile. And so on. But the fundamental unit is the ship design file.

Before my compiler stopped working, I was toying with a ship design file that was of a custom structure. It was clever but not that important.

If I were to do such an app, it would be something where you can just add elements with a few back end rules.

Yep. Turns out to require careful thought and is prone to a bit of spaghetti code, but it works to a point.

the important thing is that you have a core functionality that lets you just add and change stuff.

Yes. And the key to that is separation of concerns. It doesn't require breaking into services versus user interface, but that is a logical separation.

I should be able to drag and drop a brace of 50 dTon cutters in to my ship design, with the design updating mass and cost etc. If I could "double click" on the cutter to see it's design, that's a whoo-hoo right there.

Turns out not to be worth the effort - nor as interesting as it sounds.

...then you have a wizard that lets you pick the major components: Select J-Drive, M-Drive, P-Plant, add weapons and screens, it auto computes crew and stateroom requirements.

Yep, did that. Auto compute is helpful, but you can't always trust it. For example, I auto-recompute drive and fuel requirements when you change the hull size, but sometimes that gets in trouble, depending on how you adjust drives by tech level.

Turns out that orchestration is critically important, and fiddly.
 
It's a thing of beauty. ... Absolutely fantastic.

But it's 10 years old, and Flex is dead, and it reached its service end in 2017 or 2018. After that, I couldn't update and recompile the code.

And some of the formula are not current.

That's what's killing the app.

I feel you, I wrote my app 2014/15. To touch it now requires updating from Ruby x to y and no doubt a pile of subsequent bug fixing resulting from the update. That and I'd like to rewrite it in Elixer with greater modularity and publishable APIs.

I was also working on a fleet designer, but as a collection of ship instances that accumulate damage (or passengers/cargo) on the immutable ship design. After that my intent was a combat engine, but didn't quite get there. I tried to put a student team on the combat engine, but they struggled with the concepts :)
 
Last edited:
The main thing I thought of was: I get this into services, and I don't have to write the UI. Or rather, the UI becomes separated from the service code. Since UI SOTA changes more frequently than anything else, that's the bit I want isolated.

Sure, but it still has to be hosted somewhere.

You could ship a "server" and let the folks run it local, but now your "readme" is getting longer as the user has to orchestrate all of this stuff.

Or, you need a permanent online presence.

The issue that you lost your development environment is still quite possible as software ages, as others have mentioned with their code.

Heck, even the java world is in a bit of an upheaval with the speed of the JDK changes, how Oracle is gutting it, the new packaging system, etc. A lot of old stuff struggles on newer JDKs, and bringing them forward may or may not be trivial to do. It's not a complete waste, it's mostly packaging. From a source code POV most of it is quite forward portable, unless you rely on something like XML processing which has been yanked out of the core runtime and must be provided externally.

There's a lot of old code out there that will not trivially rebuild out of the box any more.

So, the point being, whatever you choose will likely not have a trouble free future if it's just set to bitrot and stagnate.

Even your Adobe AIR script should be mechanically portable, at a service level, not at a UI level.

Services without a UI are useful depending on the granularity of the service. "Spreadsheet as a service", which is the closest layman view of a ship builder, to me, seems too fine grained. I guess if you're shoving the entire ship state up, with a delta "Here's the ship right now, add a jump drive, return an updated ship with meta statistics". Seems an excessive way to deal with it, I don't see many folks finagling that by hand using curl or anything. Be odd to send a JSON filled with an entire ship to a service just to change the Jump number, but that's what you'd have to do.

Doable, just odd.
 
...if you're shoving the entire ship state up, with a delta "Here's the ship right now, add a jump drive, return an updated ship with meta statistics". Seems an excessive way to deal with it...

That sounds terrible. And... how can I say it? ... not friendly or portable.

I'll start small, and I suspect I'll quickly find a stateless level of detail that makes sense, or that it's all quite silly.

However, there is "business logic" in my last app that's better off not in the app, as well as some of the configuration data.
 
That sounds terrible. And... how can I say it? ... not friendly or portable.

You could abbreviate things of course. Just send the relevant bits of information.

For a jump drive, is there much more needed than TL and Hull size? And you get back volume and power requirements (if any)?

But some are more complicated.

Crew calcs need to know just...all sorts of things.

But where things get messy is while calculating a jump drive is easy, changing a ship from 800 to 1000 dTon is a real problem. Kind of messy.
 
For a jump drive, is there much more needed than TL and Hull size? And you get back volume and power requirements (if any)?
Hull size + any wings or fins + any pods + any externally carried craft + any other external load + possibly drop tanks (or not, depending on whether the ship intends to jump with the tanks or not). And it will change all the time as pods etc are added or deleted. And if a pod is added the required fuel in the drop tanks will change, so rippling changes throughout the design... And Jump (or Hop or Skip) performance might be constrained by the possible TL of the chosen power system.

And there are two ways to calculate drive potential (table vs. EP), hence needed drives for a given size and potential. They might give different results when stage effects are included. Some drive potentials might not be available for all ship sizes, such as J-1 in a 100 Dt hull. And you should choose an appropriate nexus combination for the current drive potential, stage, and ship size. And allow the user to override all of this if he thinks he knows better...


But where things get messy is while calculating a jump drive is easy, changing a ship from 800 to 1000 dTon is a real problem. Kind of messy.
Ehh, messy? It's basic. Ship size hasn't been constant and limited to hull alone since LBB2.


You have to store components attributes as calculations, not just values. They will potentially change all the time. And you need a dependency map to know what to update when something changes, and another dependency map to know what to update in the presentation layer. And a way to resolve circular dependencies.

Congratulations, you have volunteered to design and implement a spreadsheet app with a fancy presentation layer!


For messy try changing TL of the ship in T5. You will have to re-evaluate possible chosen stage and range effects, and perhaps chosen sensor types (e.g. Radar to EMS or v.v.). And then change the TL back and go back to the exact same state as before the TL change...



The T5 ship design system isn't LBB2 style simple, or even LBB5 style simple, it is much, much more complicated mostly because of stage effects. Once you accept the circular dependencies FF&S looks comparatively trivial.

We also have long dependency chains such as: add a drive, the drive needs control panels, the panels needs consoles, the consoles needs engineers, the engineers might need supervisors, the crew needs staterooms, the staterooms needs freshers and common areas and life support (of the correct type) and possibly life boat capacity. To make it easy for the user, and give it a chance to be reasonably correct, this has to be automated, otherwise some of it will be forgotten half the time.
 
We also have long dependency chains such as: add a drive, the drive needs control panels, the panels needs consoles, the consoles needs engineers, the engineers might need supervisors, the crew needs staterooms, the staterooms needs freshers and common areas and life support (of the correct type) and possibly life boat capacity. To make it easy for the user, and give it a chance to be reasonably correct, this has to be automated, otherwise some of it will be forgotten half the time.


Earn that naval architect pay, make sure there are enough bathrooms!
 
The design is loaded into the UI via a JSON design file, worked on by the app, then saved back to a JSON design file when done or at a stopping point.

One file per ship.
My Adventure Class Ships app for iOS uses JSON as well to save the ship designs incrementally as you design. If the app actually ever restarts (not often in the iOS world) then the app reloads the saved JSON data. I only save the stuff that the app can't recalculate but it's still a complicated thing, what with possible multiple hulls, drives, power plants, etc.
 
The T5 ship design system isn't LBB2 style simple, or even LBB5 style simple, it is much, much more complicated mostly because of stage effects.

I would go with an AI for such an app. Then you can drag the TL slider and the app does the rest when it comes to retconning ship designs already laid out.
 
Spreadsheets are REALLY GOOD at this, but they tend to be rigid. As long as you're in your comfortable box, it's all good. How many spreadsheet builders let you add another power plant, for example?

Why would that not be possible?

From my spreadsheets: The power of Copy-Paste:
CT:
Code:
QN-13224R1-000000-00000-0        MCr 111         100 Dton
Single Occupancy                                   -4       111,2
                                     USP    #     Dton       Cost
Hull, Part Streaml  Custom             1          100            
                                                                 
Jump Drive                             2    1       3        12  
Manoeuvre D         A                  2    1       1         4  
Power Plant                            1    1       3         9  
Power Plant         A                  2    1       4         8  
Power Plant                            3    1       9        27  
Power Plant                            4    1      12        36  
Fuel, #J, #weeks    J-2, 4 weeks            2      40            
Purifier                                    1       6         0,0

T5:
Code:
TL-12  F-BU22                        Ergo 2   Comfort 4    Demand 0        Agility -1
       Freighter                     Total:         0          94,1        Stability 0
SYSTEM                                    #       DTON         COST      
                                                                         
Hull                                              200                    
                                                                         
Jump Field: Jump Bubble                                                    D=278 m, Flash 7
J Drive B      J-2, 200 EP                1        15          15        
M Drive B      2 G, 200 EP                1         3           6        
P Plant D      P 4, 400 EP                1        13          13        
P Plant C      P 3, 300 EP                1        10          10        
P Plant B      P 2, 200 EP                1         7           7        
U Plant A      U 1, 100 EP                1        15          22,5      
                                                                         
Fuel, Jump   J-2                                   40                    
Fuel, Power  4 weeks                                8
 
Sure, but it still has to be hosted somewhere.

You are missing some of the point of micro-services. Each part of the app is hosted separately, potentially by different providers. Micro-services are typically small, easily hosted on free host services (at small scales like for Traveller use).

This allows other developers to pick and chose which micro-service they wish to use. The only requirement being a useable URL/API.

To flesh this out a little, say Rob creates his micro-service based ship designer and publishes the APIs and URLs (possibly requiring an account for security).

His structure might be:

  1. HTML form to collect data
  2. Process data
  3. Iteration solutions (eg: hull size changes)
  4. HTML output
If Rob creates these four (albeit large) micro-services, each hosted in their own container (meaning they can be hosted separately, in volume and anywhere) and publishes the APIs and URLs, other devs can use them over the web in the traditional data-in -> container does processing -> data out.

So I come along and I think my design style is better than Rob's (dubious claim!). So I use the first three micro-services because they are free to use and Rob has kindly shared the URL and APIs (see TravellerMap for examples), saving me a heck of a lot of time so I can create an improved kick-ass HTML output with lots of js functionality.

Being able to improve or build on micro-services is one of the key points.

When I host my microservice, I host new copies of Rob's first three services to ensure that if Rob's free hosting accounts ever get shut down, my app is all good. In addition I set up hooks so that if Rob updates his apps, my copies are auto-updated. Finally, I publish the URLs and API's for the microservices I host, so others can add them to their lists of services, increasing their reliability as well.

Soo... increases complexity in some ways, but means you don't have to reinvent the wheel if a good wheel already exists.
 
Sure, but it still has to be hosted somewhere.

Doable, just odd.

The first is only partly true.

The second is true.

* * *

It only has to be pushed on a container up to DockerHub. Then, anyone can fetch it and run it on their home network.
 
Back
Top