~sforman/game

A simple chill 4X space game
If we are NOT in Idle call mainloop().
Make start_me.py into an executable script.

refs

trunk
browse  log 

clone

read-only
https://git.sr.ht/~sforman/game
read/write
git@git.sr.ht:~sforman/game

You can also use your local clone with git send-email.

This is a space explore and colonization kind of game. There is a star cluster inhabited by multiple species and civilizations (eventually multiplayer, for now the user controls one species.)

Just the first two X's:

the 4X game (eXplore, eXpand, eXploit and eXterminate) model

4X game

#Design

The basic design is turn-based and client-server.

The venerable VGA Planets game is an inspiration for this.

At the beginning of a turn the user gets a DB file that contains everything they know about the game universe. This is loaded into a client program which displays the data and lets the user queue up "order codes" (move people and resources around, launch ships, etc.) to be sent to the server. The server checks and applies the order codes and updates the game universe, then sends the next DB file to the user for the next turn.

I hope to have multiple clients. I'm writing a simple Tkinter client to begin with, but it would be cool to have a "gamey" UI written with Godot or something.

#Tkinter Client

Tkinter is the Python wrapper for the TCL/Tk GUI system and it's the default GUI system for Python (some distros like Ubuntu require you to install it separately from the Python interpreter package but it's part of the official Standard Library.)

It's simple, easy, fun, and fairly flexible and feature-complete.

The game client so far consists of a canvas that is larger than the window and that you can scroll, and there are some stars that vary in size and color. There's also a tab that has a crude stellar system display. And that's about it.

#Server

The "server" isn't a server at all yet in the sense that it doesn't do any networking or anything like that. It reads a local SQLite file and applies some changes.

#Database File

The DB file is a SQLite file, straight up, nothing fancy. That means you can use any SQLite-compatible software with it, e.g. Datasette or sqlite3 (the command line program.)

#Files in the Project

SpaceGame
|-- COPYING
|-- README.md
|-- game.sqlite
|-- tables.sql
|-- treeview_experiment.py
|-- widget_experiment.py
|-- widget_experiment_too.py
|-- SpaceGame
|   |-- __init__.py
|   |-- Tk_client
|   |   |-- __init__.py
|   |   |-- icons.py
|   |   |-- reticule.py
|   |   `-- ui.py
|   |-- data
|   |   |-- __init__.py
|   |   |-- __main__.py
|   |   `-- data.py
|   |-- game
|   |   |-- __init__.py
|   |   |-- population.py
|   |   |-- server.py
|   |   |-- stars.py
|   |   `-- vivifiers.py
|   `-- util
|       |-- __init__.py
|       |-- ease.py
|       |-- poisson.py
|       `-- wordlist.py
|-- docs+notes
|   |-- doc.txt
|   `-- selectable-stars.md
|-- images
|   |-- lil_planet_icon.png
|   |-- lil_planet_icon.xcf
|   |-- lil_sun_icon.png
|   `-- lil_sun_icon.xcf
`-- misc
    `-- terrain_automaton
        |-- space.gz
        `-- terrain_automaton.py

So from the game dir you should be able to start the Tkinter client like so:

game$ python -i start_me.py
>>> app
<SpaceGame.Tk_client.ui.App object at 0x7e673da7bbb0>
>>>
  • COPYING - The GNU GPL license
  • data.py - module and script. As script it uses tables.sql and some of the other modules to generate the initial game.sqlite DB file.
  • doc.txt - a start on in-game docs. (Like when the user press F1 or something.)
  • ease.py - eventually when we scroll the Star Map we will want easing for the animation.
  • game.sqlite - The SQLite DB file. Even though it's a binary format I like to have it in the repo as it makes me feel more confident about messing around with it without breaking things.
  • icons.py - The icons from the images directory encoded as base64 data strings in Python code that get converted to Tkinter PhotoImage objects. I like to put data into Python modules so I can use import statements to load it. It's a work-around for the difficulty of installing and locating data files in Python packaging. One day they will sort these things out.
  • images/ - directory for images, so far just a couple of in-game icons.
  • misc/ - Miscellaneous stuff.
  • poisson.py - Code for laying out points on a 2D plane randomly with a minimum distance between them in an efficient manner.
  • population.py - Game module for populations.
  • reticule.py - GUI code for the system indicator on the Star Map.
  • server.py - Implement a turn of the game. Eventually this will maybe also handle network connections?
  • stars.py - Game module for stars and planets.
  • tables.sql - The DB schema, CREATE TABLES statements, etc.
  • tasks/ - I started this as a kind of local task list but I haven't really been using it. Hmm...
  • treeview_experiment.py - I wanted to see if a Treeview could handle all ~2000 stars and 12300 planets. It can. It takes a moment to load but then the Treeview seems responsive.
  • ui.py - The main GUI script. Start this to see the game client. Be sure to either uncomment the call to mainloop() or run python with the '-i' switch to keep it running after the GUI is built. That way you can play with the widgets "live", which is nice.
  • vivifiers.py - Game module for vivifiers (drones that seed life on barren worlds.)
  • widget_experiment.py - An experiment with some widgets.
  • widget_experiment_too.py - Another experiment, nested LabelFrames.
  • wordlist.py - EFF wordlist for making passphrases, here used to make silly names for star systems. (see: https://www.eff.org/deeplinks/2016/07/new-wordlists-random-passphrases https://www.eff.org/dice )

#Notes (cont.)

Aesthetics: maybe have a sprinkling of background stars behind the "real" stars (that are part of the game.)

Toggle fullscreen.

Controls? Tabs? HUD/OSD (heads up display/on screen display)

What format for the order codes?

Thun code?

THe db tables and game data types should be compatible with Prolog?

I don't want to have a bunch of Python objects modelling the game entities if possible, what I mean is, it would be neat if the db rows (tuples of Python ints & strings) and the Tk widgets (canvas items, etc.) could be the bulk of the internal game, uh, stuff. Not everything needs to be a class?

Sat Apr 13 13:10:19 PDT 2024

I took a look at the real Milky Way and man is it ever big. Thouands of star clusters with thousands of stars each...

There's a tension between versimilitude (fidelity to the real data) and making something easy to write and fun to play. It would be simple enough to generate crude cartoon worlds, and a detailed realistic galaxy might be kinda boring (to play.) If you want to (virtually) explore the real galaxy there are resources for that.

In any event, I think the way forward is to generate something nice now and upgrade it later. I don't want to get side-tracked, I want to stay mostly on the critical path.

Sat Apr 13 13:31:02 PDT 2024

Context...

In this Universe there was a certain insectoid species (a hive species like ants or bees) that attained sentience very early on, before any other species on any other planet, and they effectively control the whole place. They are mostly uninterested in new species, other than to maintain stability and order.

As new species arise and attain sentience and explore the galaxy they are incorporated into the insects' system (or destroyed, but that's very rare.)

Rules:

1.) Species may only reproduce on their home planets. This limits exponential population growth. Each species must learn to live within planetary limits as proof of their sentience.

2.) War can only be fought by agreement. Before fighting two (or more) species must file agreements with the insects. These agreements detail the theater, forms of combat, parties, win criteria, and stakes for a given conflict. Importantly, the idea is that one cannot force another to fight. You can't use the threat of fighting to force other issues.

3.) Living beings are sacred. The insects generally speaking want there to be more life, not less.

(When species members want to travel between the stars they generally develop either suspended animation or longevity or both. D'oh! I forgot "Bob the Blob" takes care of both, also interspecies communication.)

Most interstellar economic activity is in the exchange of "spices" (biomolecules that are difficult or impossible to synthesize) and art.

To this end, you explore and find viable planets, seed them with life, harvest them until they eventually develop their own sentient species which then join the galactic society.

(Maybe? I'm spitballing here. I'd like to integrate this game universe into a inchoate Sci-Fi universe I'm toying around with, if possible.)

Don't over-think it. "A complex system that works will be found to have evolved from a simple system that worked." Something like that.

John Gall: Systemantics: How Systems Really Work and How They Fail

A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.

So let's make a simple system that works, eh?

Sat Apr 13 14:09:14 PDT 2024

Battles are resolved by proxy. Any other game (that gives a definite result between the parties) can stand in for a battle or war in this game.

Sat Apr 13 21:46:16 PDT 2024

For selecting a star and showing some data about it one option is a static pane of widgets, like on the side. Another option is to have a tooltip kind of a thing, but not transient as in you should be able to select text on it? click controls? A third option is to populate a notebook tab and switch to it? That seems dramatic.

The first and second options are easy to implement, the tooltip needs positioning logic. Let's exercise the notebook...

Sat Apr 13 22:58:12 PDT 2024

We assume that each stellar system has all the energy and protons they need so they can transmute elements. The products of a stellar system are "spices", biomolecules, which require planets to have life, and art which requires sentient life.

So a planet has, let's say, a bio-capacity, the maximum life it can sustain (for whatever factors, temp etc.) and the basic mechanic is to seed lifeless planets with life (using fast cheap robot probes/drones) and then collect and trade spices.

Because acceleration is so expensive, we have "gates" that throw and catch ships for sentient beings to travel. That way the ships don't have to carry mass to eject for delta-vee or fuel to eject it, and I imagine that dust and such is swept out of the regular routes.

But it's expensive to build a gate and you have to bootstrap.

So you start with a home system, two seeder drones, and one ship-of-the-line for defense and you know, to have a ship.

You send out the drones to explore and bootstrap your local economy, fly your other ship around to do...? Fun side quests? Allocate build power to:

  • more build power
  • seed drones
  • ships
  • ?

Sun Apr 14 20:45:17 PDT 2024

Added some planets to stars and stats to planets. There are two kinds of capacity for each planet: "bio" and industrial. The bio capacity is the most bio production (of "spices" and population) possible and the industrial capacity is for production of seeders and ships and bases and gates etc.

Most planets start out w/o life and most planets that have life do not have sentient species.

A population on a homeworld grows at a certain rate, industrial production is limited by population (up to the max: planet capacity) but you can build "multipliers" that can make pop 10x - 1000x more effective.

biomass w/o pop growth, so you need at least two numbers: life and pop. life goes up automatically but pop cannot go up on non-homeworlds (by bug law) except by immigration.

bio is (well, shall be) in the planet table but pop should have it's own table.

Mon Apr 15 09:13:22 PDT 2024 Let's add some people.

I'm thinking that, say, 10% of planets (with non-zero bio capacity) should have naturally occurring life. (Any planet with life will have maximum life, because that's life.) If there are 10000 planets with bio capacity that means 1000 planets with life, if we want only about 10 sentient species that's 1% of those, eh?

Population can move around. Planets, space stations, ships, where else?

Just a note: I'm not happy with the Poisson layout of the star systems, too uniform, I know I've said that elsewhere. I'm also not happy with the radiuseses of the stars, the little ones are hard to click on. It's not so bad because you can click on the labels, but still. It would be neat to have a scattering of stars on the background, just tiny points of light, cosmetic only, no game function. Then the "real" stars could all be several pixels uh radius for clickability eh?

It would be fun to see if the Treeview widget could handle all the stars and planets... 12,300 planets, 1,948 stars, it should be able to handle it? UPDATE: the widget can handle them but it's overwhelming to have thousands of items in a list.

Mon Apr 15 15:48:51 PDT 2024

Pop growth on homeworlds only: we want the populations that are on a planet where that planet is in the home stellar system of the species of the population.

planets.star = populations.homestar

What if in the populations table instead of the species column there is a home system column? We can get the species name from the homestar name as needed?

Is there a good reason not to have the species name with the pops? Extra space used I guess, maybe? pop.homestar.name + 'ians'

Wed Apr 17 08:59:24 PDT 2024

TODO: when the canvas changes size it should keep the center point, uh, in the center. As it is now the upper left corner seems to be the, uh, fixed point.

I think the next thing to work on now that we have life and people would be something to do.

Industry points require population to "work"? E.g. 100 ind & 100 pop => 100 "build points" to spend on ...

  • Increasing IND
  • Ships, stations, seeder drones, what else? Gates
  • there was a third thing, but my notes are way over there...

I guess we need some kind of build queue?

#Seeder Drones

(I'd like to find a better name? "Vivifiers"?)

These carry "bio" in stasis to new barren worlds. They are launched by gates but don't need receiver gates to decellerate, instead they drop seed packages of bio and then self destruct (later I want to have ones that can slingshot to additional destination stars.)

(Again, my notes are sooooo faaaaar (like ten feet, but there are plants in the way) let's see how much I remember)

So you set a destination and launch the seeders drone,

No wait first you load some bio onto the drone, so it has to have a bio capacity and a load command. THen you set a destination and launch it. It travels at a given (relativistic) velocity (a set number of pixels per turn) and during some turn (I think it should take typically three or four turns) it arrives at the destination stellar system.

as an aside, I haven't nailed down how much information players should have at the start (the insects provide star maps) and what we should have to discover by scans and exploration.

Anyhow, once the drone arrives at the system it has to deploy the bio to one or more planets (that have non-zero bio cap).

I came up with three basic strategies"

  • all-for-one all bio goes to the planet with the greatest bio cap.
  • even-split bio is divided evenly among all the bio cap planets.
  • proportional bio is diveded by proportion of bio cap.

(Later when seeder drones can retarget it might make sense to just drop one bio unit on each viable planet and move on. The minimum increase per turn is one bio, so on the next turn the bio on each planet doubles! (From 1 to 2.) It's a small effect that probably gets washed out, but I wonder what the optimal (from the galactic POV) starter pack amount is?)

ALright, there are a lot of embellishments that occur, but this is enough to get something happening.

Seeder drones ("vivifiers") cost cube-root of their capacity to construct, they take one turn to construct, ...

Not the cube root, pow(capacity, 2/3), you have to pay for the shell that contains the volume (plus a little for inner structure (+ 0.001 * cap) so I think that's the relation between surface and volume (2d to 3d). Huh.

All species in game are assumed to be Kardashev Type II civilizations, they utilize much of the energy emanating from their stars.

Kardashev scale

Wed Apr 17 18:16:26 PDT 2024 Let's add a little more info to the star map? Like when hyou mouse over a star it could show the number of planets and the gross bio and ind cap?

Thu Apr 18 12:55:01 PDT 2024 So the Treeview handles all the stars and planets just fine. It takes a moment to load (and also to shutdown!) but it runs fine. However, it's not very useful having them in a big list (although it's fun!) (also the sort order is by db id which has no relation to the name or coords of stars so its effectively random.)

It might be nice to sort by distance from homeworld? (and then alpha by name, eh? or by capacities or number of planets?

Also I'm considering breaking the galaxy up into "sectors" or regions or something. Have that be the top-level tree items with stars as their children. Star clusters. Maybe its time to rework the layout, get something with a little more variety than plain Poisson? Maybe let the minimum distance between stars vary with a Perlin noise function or something like that? That could be nice?

Or for regions do a large-grain Voroni cell with the min distance varying based on how far you are from the centeroid of a region?

The easiest thing to do would be to keep the current star field and impose a grid, or polar coords (angle and distance from center or homeworld). "Almost too easy..."

Thu Apr 18 13:31:43 PDT 2024 I haven't mentioned it yet so far but the game assumes the each sentient species has developed efficient mass-energy conversion. Also, transmutation, they can produce as much of whatever elements they want by collecting protons and energy from their star and converting them directly into whatever matter they require. That's why "spices" and "art" are the only two trade goods, everything else can just be extruded by the solar-powered energy-to-matter converters.

Thu Apr 18 19:48:12 PDT 2024

Ooo maybe some circles around the home star at every 500 pixels or so?

Fri Apr 19 08:01:58 AM PDT 2024 Onlydawnio Overdecat Some of the names the random name generator comes up with are, like, you're kidding me, right?

I want to live on Over De Cat!

Anyway, I'm cleaning up the treeview code. THe placeholder trick works great, you get open/close chevrons and the planets populate imperceptibly quickly.

It's almost time to y'know, implement some game play. I'm still not sure how to represent order codes. It would be neat to use Thun, but I'm not sure it's ready yet. Another idea I had was to specify type signatures for command functions and then the user can implement them in (abridged?) Python or JS or whatever. Or just make a really simple SQL-ish lang? Or GUI goo that then emits a data structure (or SQL code or whatever) that represents the orders?