As Eriban, fellow Pico-8 developer and code optimiser extraordinaire (very much unlike me) once observed, I have a habit of creating the completely wrong kind of Pico-8 games: slow-paced, physically accurate, complex and austere simulators. Picotéras is the latest in this slowly extending line of misfits.
I have long held the ambition of creating some sort of 4X analogue in Pico-8. However, it quickly became obvious that compromise would be necessary to make it playable. I ended up keeping the gigantic scale, every game spanning centuries (or even millenia) and dozens of star systems, but simplifying the core mechanics of the genre.
So instead of controlling some galactic power, the player is in charge of a single orbital habitat capable of interstellar travel. By way of analogy: you are leading a nomadic tribe of eXplorers, not an eXpanding empire.
Accordingly, eXploitation involves keeping your orbital alive by harvesting the necessessary resources on your interstellar journey, while eXtermination consists in defending it against hostile robotic swarms (possibly through pre-emptive strike).
The name of the game is obviously a wordplay on Voltaire’s “Micromégas”, which could be described either as an 18th century space opera, or as a playful treatise on the relativity of scale.
By design, Picotéras is meant to be as open-ended as possible, allowing the player to write their own civilisation’s history. However, there are inevitably some constants imposed by the game’s mechanincs (or by the limits of my imagination, take your pick).
First and foremost, the Picotéras universe has periodic boundary conditions, which means it is donut-shaped: traveling to the “east” simply causes you to re-enter from the “west” and vice versa (the same applies to “north” and “south”).
Second, it obeys some basic laws of physics. Every star has a gravitational pull proportional to its mass and inversely proportional to the square of the distance (above a certain range, this force is set to zero for simplicity). Crashing on a star is (surprise, surprise) fatal to your orbital habitat, so learning how to navigate gravitational fields successfully is essential and, according to Terizian (my playtester), quite challenging!
There are 3 types of stars in Picotéras: red dwarves, yellow suns and blue giants. Orbiting each type of star allows you to harvest one of the three resources modeled in the game: red dwarves can be “mined” for raw materials to build up your swarm of defensive drones (more on this below), yellow suns let you restore your habitat’s biosphere (which slowly deteriorates over time), and massive blue giants allow you to replenish the gravitational energy used to propel your orbital from star to star.
Aside from piloting error, which can result in collision with a star, or poor planning, which can cause you to run out of energy or lead to your habitat’s biosphere deteriorating to the point where it can no longer support life, danger to the orbital comes from hostile robotic swarms.
Robotic swarms roam the Picotéras universe, traveling from star to star much in the same way that you do. Nobody knows exactly where they came from, but they are probably the remnants of a long gone alien civilisation. Some are benign (or rather indifferent to your presence unless provoked), but others seemingly hold a grudge against biological life. Those will attack and hunt you down until eliminated. Each robotic drone reaching the orbital will ravage its biosphere, halving the corresponding variable. You may be tempted to think of these doomsday devices as missiles, but a more accurate analogy would be pollutants or an artificial virus. They do not detonate on impact: they break down into trillions of nanomachines that effectively poison the environment.
Your best and only defense comes from your own swarm of sentry drones. These drones, which are built automatically when orbiting a red dwarf, escort your habitat and, when activated, seek and destroy their robotic counterparts (hostile or otherwise). Robotic drones also harvest red dwarf resources to build up their numbers and, when reaching critical size, split into two independent swarms (although they cannot exceed a total number determined by the size of the map).
Controls and interface:
At the very beginning of the game, the player is asked to choose a universe size. The options are 60x60, 80x80 or 100x100. The star and maximum swarm densities are constant (so the corresponding number increases with size). There’s always at least one star of each type, but usually several more. Red dwarves are more common than yellow suns, while blue giants are the rarest. Choose the desired size using the up and down arrows, then hit “x” to start the initialisation process. If you select the largest map, be prepared to play for a while before reaching any kind of victory (NB: 100x100 is almost three times bigger than 60x60!).
In-game, the arrow keys are used to control “thrusters” (in fact, these are relativistic engines that bend the space-time continuum, causing the orbital to “slide” into the desired direction of travel, but that’s a geeky detail). They are used to accelerate or slow down and consume gravitational energy.
Holding down the “z” key causes the sentry drones (if any) to go to high alert, which essentially means that one of them will be dispatched to attack the nearest robotic swarm every second (note that a second is a year in game time). Once a drone reaches its target, both are eliminated, so keep in mind that war is costly: if you run out of sentries before a pursuing swarm has been wiped out, you are in big trouble!
The main display shows your orbital habitat in the centre, nearby stars and all swarms within range (robotic and sentry drones). Blue gridlines help you visualise the geometry of space around you (they are distorted in the vicinity of stars). On the top left corner is a datablock displaying the value of the three key variables measuring the orbital’s “health”. These are: Swarm (SWR), Biosphere (BIO) and Energy (ENR). All are expressed as a percentage of the maximum. In the case of the swarm, the highest allowed number of sentry drones is 32. When SWR or ENR fall below 25%, they start flashing to attract attention.
Individual drones are represented by a colour code. Robotic units can be yellow (unknown or hostile but unaware of your presence), purple (identified as friendly), orange (identified as hostile and aware of your presence) or red (hostile and on an attack vector). Your own sentries are dark green when on low alert, bright green when instructed to seek and destroy nearby targets (“z” key down).
The bottom left corner displays some information about your progress, namely the number of years you have survived (YRS), the percentage of solar systems explored (XPL) and your current score (SCR). The score goes up for every hostile drone destroyed (you gain 10 points bonus for eliminating an entire hostile swarm) and for every star visited. It goes down by the same amount when destroying/eliminating neutral drones/swarms.
The bottom right corner contains a “mini-map” showing some information about the space beyond the boundaries of the main display. Stars that have already been visited are represented by red, yellow and blue icons. The location of “undiscovered” stars is marked by a green cross. Swarms appear as pulsating “radar blips”: yellow for unknown, purple for friendly/indifferent, red for hostile. In addition, if no red dwarf, yellow sun or blue giant is present but at least one has been visited before, an arrow of the corresponding colour is displayed at the edge of the mini-map to indicate the direction of the nearest one (this feature comes handy when you must quickly find a source of a critically depleted resource).
The data overlay can be toggled on or off by pressing the “x” key.
In the purest 4X tradition, there are multiple victories:
1. “Warrior” victory: all hostile robotic swarms have been eliminated 2. “Exterminator” victory: all robotic swarms, hostile or friendly, have been destroyed 3. “Explorer” victory: 100% of stars have been visited 4. “Conqueror” victory: a combination of “Explorer” and “Warrior” victories 5. “Diplomat” victory: “Warrior” victory, contact established with every neutral swarm and none of these was completely wiped out (the odd “collateral” is allowed) 6. “Pacifist” victory: reach “Explorer” victory without destroying a single robotic drone 7. “Survivor” victory: your journey reached the 2000 years mark 8. “Philosopher” victory: a combination of “Conqueror”, “Diplomat” and “Survivor” victories
Victories come with a score multiplier proportional to their difficulty (1-4: the multiplier is 2, 5-7: the multiplier is 4, 8: the multiplier is 8). When you reach any victory, the game pauses and the final score (alongside some statistics) is displayed. The same happens if your orbital habitat is destroyed, only this is obviously not a successful outcome!
With all but the highest (“Philosopher”) victory, you are given the option to continue playing by pressing the “x” key. Note that the end screen for any one given victory is only displayed once, so if you choose to continue, you’ll have to keep playing until the next victory is achieved or the orbital is destroyed (caution: in the latter case, your initial victory is cancelled).
This project is a bit of a self-inflicted ordeal... I set off to make the nerdiest, most minimalistic, least aesthetically pleasing game possible (complete with annoying simulated screen glitches).
Here is how it works:
At the top of the screen is a list of 16 ternary values, "?" (undetermined) "0" or "1" (they all start as "?"). The objective is to change these values until they match a randomly generated binary sequence (i.e. containing only "1" and "0"). You navigate through the sequence using the "left" and "right" arrow keys. Changing a value is done using the "up" and "down" arrow keys.
The way you guess the sequence (or key) is by looking at the generated binary strings that cascade down the screen. The first string (hidden behind the key) always contains one single "0" (located at a random index, where your cursor is also initially positioned). Each subsequent string/line contains one more bit. The way the sequence grows from line to line obeys the rules defined by the key. If the key value at one particular index is "0", then if the string grows from that index, it will be appended to the left. If it's "1", it will be appended to the right. Furthermore, the newly generated bit is the opposite of the "parent" bit from which it grows, so the second line (generated using the single "0" in the first one) always contains a "0" and a "1". If it is "10", then it means that the value of the key at the index at which the seed "0" is located is "0" (the "1" was added to the left of the seed). If it is "01", then the value of the key is "1" (grow to the right). For each subsequent line, a randomly chosen bit is used as the "parent" bit, until the complete string of 16 bits is generated (bottom line). The new bit is always inserted immediately to the left or right of the parent bit (so if the parent is not located on the edge of the string, other existing bits are "pushed" into the corresponding direction). Obviously, the sequence cannot grow "off-screen", so the resulting string is shifted as needed.
Because the parent bit used to grow the next line is often ambiguous (for instance, "1001" can be generated from "101" by adding one "0" to the right of the first "1" or to the left of the last "1", you will almost always need several cascades to reconstruct the entire key. Generating a new cascade is done by hitting the "z" key. Finally, you can check the accuracy of your guess by hitting the "x" key (each erroneous bit will be marked by a "!"). To return to the game, hit "x" again. Obviously, players who wish to challenge themselves should use the "z" and "x" keys with parsimony (ideally only checking the key when all bits have been guessed).
Enjoy the brain torture!
BTW, this version was compiled with the Pocket C.H.I.P. version of Pico-8, which IMHO makes the game the perfect companion to the cyberpunk mod of the C.H.I.P. ;-)
Updated with some interface improvements suggested by aaaidan:
When hovering with the selection cursor over a city, the two other cities with which it is paired (those with which it "exchanges" traffic) are "highlighted", i.e. they are drawn with a white number on a black background (negative image). This function is disabled while holding "z" down (e.g. when planning a new line).
- When the cost of a planned line exceeds the current budget, the additional (unaffordable) segments are drawn as a dashed (not continuous) line.
For the previous update (V1.2), see: https://www.lexaloffle.com/bbs/?tid=30979
For the "complete" manual, please refer to the original post: https://www.lexaloffle.com/bbs/?tid=30916
- All known bugs have been fixed.
- The pricing scheme has been overhauled to make it simpler and more useful. The ticket price is now charged when leaving the point of origin and the value is linearly proportional to the distance to the destination, independently of the route taken (multiplied by the "class of travel" factor, whether the whole journey is by Shinkansen or not). For instance, if the distance is 6 "blocks", 4 of which are on fast trains and 2 on slow trains, the total fare is still 30,000 (if the price is left to the default 5,000). If using only slow trains, it would have been 6,000 in total.
- The decision function to take the Shinkansen (or not) is now nonlinear. Travelers will choose the fast train option if the increase in price is lower than or equal to the square of the reduction in journey duration. For instance, if the duration is reduced by a factor 3 and the price is increased by a factor 5 (default), the traveler will still choose the fast option (5 < 3^2 = 9). This makes the price adjustment function more usable (i.e. it is easier to "convince" travelers to use the Shinkansen for only part of their journey through a small fare reduction).
For the "complete" manual, please refer to the original post: https://www.lexaloffle.com/bbs/?tid=30916
Debugging "Shinkansen" in the Shinkansen ;-)
Deleted original thread by mistake...
A little Particle Swarm Optimisation (PSO) demo. Move the crosshairs using directional keys. Keep "X" down and press up/down to change the number of particles (16 to 128). Move the target to a new location by hitting the "Z" key.
“Shinkansen” is more of a “love letter” to the people (and railways!) of Japan than an actual game, but hopefully it is still at least mildly challenging and entertaining to play…
You are in charge of orchestrating the progressive replacement of the “conventional” railway of a “Fantasy Japan” (each game takes place on a procedurally generated island that bears little topographical resemblance to the real Land of the Rising Sun) with high-speed “bullet train” lines. Your career spans what could be considered Japan’s “golden era”, the 25 years from 1964 (historical introduction of the first Shinkansen) to 1989.
Each map features 16 cities and the inhabitants’ travel pattern is peculiar: in essence, there are commuters between any two cities identified by adjacent numbers, e.g. between “1” and “2”, between “2” and “3” etc. (“16” and “1” are considered adjacent for that purpose). At the beginning of the game, travelers follow the shortest route using the existing (conventional) rail network (grey lines).
By holding the “Z” key while moving the cursor (rounded coloured rectangle) you can connect two cities with a high-speed train line, following any available route between them (you will not be allowed to move the cursor over “forbidden” terrain). It will not replace the existing conventional railway, only run parallel to it. NB: until “Z” is released, the new route is only “in planning”.
The colour of the cursor is specific to the line, of which there can be up to five: red, green, blue, orange and purple. Once the first section of a line has been opened, it can only be “extended” (i.e. any new section must start at a terminus for that line). You can switch between lines by keeping the “X” key down when pressing the left or right arrow key.
Travelers are rational agents (some would call them AI and they’re almost certainly smarter than Sophia ;-) At the beginning of each journey, they compute the cost/benefit ratio of taking the Shinkansen: in the game, the bullet train is 5 times faster than conventional railway. By default, the cost of the ticket is JPY 5,000 per section, which is 5 times more expensive than a normal ticket. Travelers will opt to take the Shinkansen if and only if the travel time to their destination is divided by at least as much as the fare is multiplied. In other words: for the default factor of 5, only travelers whose cities of origin and destination are both serviced by the bullet train will take it.
For every section traveled by one passenger on the Shinkansen, you earn the equivalent of the fare (JPY 5,000 by default). For every section traveled by one passenger on either railway (i.e. including conventional), you must pay JPY 1,000 maintenance and operations fee. In short: if 100% travelers use the bullet train and the ticket price is JPY 5,000, you earn JPY 4,000 per passenger and per section. If fewer passengers choose the Shinkansen, your margin will shrink accordingly.
Opening one new section costs JPY 1,000,000 and you start the game with a JPY 5,000,000 budget. A new line/section can only be opened if you have enough funds available.
The yellow “post-it” note contains all the relevant information needed to play the game and plan your strategy. On the top left is the year (circled, in red). On the top right is the percentage of all ongoing journeys that use the Shinkansen. The other two numbers below are respectively the annual profit/loss (reset at the beginning of each year) and the current treasury, both in thousands of JPY.
The last section at the bottom of the “post-it” note is the current Shinkansen fare (displayed on a white/green background, my best yet pitiful attempt at reproducing an authentic JR ticket!). You change the fare (by JPY 100 increments/decrements) by holding the “X” key down while pressing the up or down arrow key. By making the necessary calculations, you can adjust it down to attract more passengers, but it will of course reduce your margin. The limits are JPY 1,000 (below which you cannot possibly break even) and JPY 5,000 (above which every traveler will choose the conventional railway over the bullet train).
This is a "sandbox" game, so you set your own objective: get 100% travelers on the Shinkansen, reach the 31,999,000 treasury limit as early as possible, use the fewest possible lines to service the whole country…
The number of travelers increases over time (by one unit every year) to reflect Japan’s booming economy. In Jan 1965, one traveler is added to the population commuting between cities “1” and “2”, in Jan 1966, it’s between “2” and “3” and so forth.
P.S. This project took longer to complete than expected and as a result, the code is rather messy... Sincere apologies to my fellow programmers with higher standards!
“Picroisières” is a procedural sailing simulator. Every time you play the game, a new unique archipelago and new weather conditions (wind direction and speed) will be created. Although the map will always look roughly similar, the shape and location of islands should be sufficiently different to keep route planning interesting.
There are two screens: Map and Compass. Toggle between the two by hitting the “Z” key (FR: “W”, DE: “Y”).
Controls are very simple: you only control steering and “power”. Think of the latter as an abstraction for all the trimming, sail changes etc.
Steering is done using the left (port) and right (starboard) arrow keys. “Power” is increased or decreased (by 5% increments) by pressing the up and down arrow keys respectively.
Your boat is a racer: it can easily reach over 15 knots in strong wind! However, sailing at higher speed risks damaging your ship. At 20 knots, a critical failure will statistically occur after approximately 4 hours (game time). At 25 knots (hard to reach but not impossible), after only 45 minutes. Note that this is a probabilistic event, so if you’re unlucky, you could suffer a breakdown much quicker (and vice versa). To be safe, reduce “power” to stay well under 20 knots, where the chance of damage is very low…
The game consists in completing a course through 4 waypoints or gates, in the prescribed order, then coming back to your starting point. Each gate (NW, NE, SE, SW) is marked by a red “+” sign on the map. The next waypoint you must reach emits a “pulsating” signal. The gates are not buoys: you don’t go around them, you must sail “through” them. When you clear a gate, the symbol turns green and the next waypoint is automatically selected. After you clear the last (SW) waypoint, you must return to the starting box.
In “Picroisières”, you race against the clock. The timer starts when you exit the starting box and stops when you re-enter it (after completing the course). Leaving the starting box again restarts the clock, so you can compete against yourself (try to improve your time) or challenge a friend (hot seat).
As in real life, weather (windspeed and direction) changes continuously (and randomly) over time. Before you first exit the starting box, you can randomise the weather as many times as you want by hitting the “X” key (as if choosing the day on which to go sailing). Once the “race” has started, this option becomes unavailable.
White and light blue indicate a safe depth, if you ever enter dark blue or yellow, you will beach your boat (this effectively ends the game as you can no longer manoeuvre in any way). A black symbol at the centre of the screen marks your current position. A black vector (to the edge of the screen) plots your course following the current heading.
If you suffer a breakdown (as a result of sailing at excessive speed), your “power” drops to a maximum of 20% (jury rig) and the drag coefficient of your boat is multiplied by two. Needless to say this makes you rather slow! You must limp back to the starting box (automatically selected in case of damage). When you leave the starting box again, you boat will be repaired.
The map has periodic boundary conditions, which means you can pretty much sail indefinitely in any direction (the archipelago just “repeats” itself). Of course, the gates remain where they are, i.e. you cannot reach the SW gate by sailing NE!
The Compass also shows your heading (CRS), speed (SPD) and the apparent windspeed (WND), as well as the current “power” level. The light blue arrow is the apparent wind direction (taking into account boat speed), the dark blue one is the true wind direction (both obviously overlap when motionless).
A little demo of Polya's Urn's somewhat counter-intuitive dynamics...
The single rule is: draw a marble at random then put it back and add a second marble of the same colour. Although there is an obvious positive feedback involved ("rich becomes richer"), it turns out that a strongly uneven distribution is not particularly likely!
In “Jodorowsky’s Sandmaster”, you play the role of a titular “Sandmaster” on Arrakis, the desert planet in Frank Herbert’s “Dune” universe. I imagined this game many years ago. I first implemented it in TurboPascal in the 1990’s, and have since then created a Java version. The obvious next step was to do it in Pico-8.
I called it “Jodorowsky’s Sandmaster” in tribute to this visionary director’s failed attempt at making a motion picture out of Herbert’s landmark Sci-Fi novel in the 1970’s (an epic story recounted in Frank Pavich’s 2014 documentary “Jodorowsky’s Dune”, which I all-heartedly recommend). I drew inspiration from Jodorowsky’s work in redesigning my game, for instance by making the spice a pulsating, organic, psychedelic blue instead of the more conventional cinnamon brown. The patterns in the sand are also meant to be reminiscent of Chris Foss’s “fishskin” spaceship designs. Of course, none of the great artists who were involved in this ill-fated movie project were involved in my modest game. Should Mr Jodorowsky become aware of it and not wish to be associated with it, I will of course remove his name…
In Frank Herbert’s universe, the Sandmaster is the person in charge of supervising spice mining operations. In the game, you pilot a “carryall”, an airborne vehicle tasked with transporting the spice-mining harvesters to extraction sites. The controls are very simple: the arrow keys set the direction of movement. Hitting the key pointing opposite to the current heading brings the carryall to a halt (hovering). Hitting the “Z” key will do one of 3 things: if above a spice-blow, it will lower a harvester (which immediately start collecting the precious substance), if above an already deployed harvester, it will lift it from the ground. Finally, if above open desert, it will drop a “thumper”.
The difficulty (as everyone familiar with the book will know) is that giant worms roam the desert of Arrakis and search and destroy any object producing a rhythmic noise, such as a thumper or a harvester. In the game, worms perceive vibration up to a distance of 16 sprites and will home into the nearest source. The game consists in finding spice (there’s quite a big patch of desert to explore!), then extracting it while luring worms away with thumpers so as to allow harvesters to complete mining operations. In the game, “wormsign” takes the form of a shifting disruption in the sand pattern. Worms cannot cross rocky areas and have to go around them. If a worm comes within 8 sprites of a harvester, the whole screen starts vibrating as a warning of imminent disaster.
You can deploy as many harvesters and thumpers as you like. Deploying a harvester costs 10 points, a thumper 1 point. Losing a harvester to a worm costs 100 points (this includes financial compensation to the workers’ bereaved families ;-), so look after them! Each spice-blow is worth 100 points if fully harvested, which takes some time: you will know that mining is complete when the harvester icon’s animation stops (it will still attract a worm though!) The load is only secure once safely inside the carryall, but you can lift a harvester out of harm’s way at any time (you only need to be right over it and press the “Z” key) and bank a partial load.
The game lasts for a 12 hours shift (countdown in the bottom left corner), after which the score (spice cargo minus costs) is computed. The game should keep track of high scores (enter your 4 letter/number identifier using the arrow keys). If there are harvesters still deployed at the end of the shift, the game will continue until you pick them up (or they are destroyed by a worm), but you cannot deploy new ones (you can still deploy thumpers though).
Enjoy, comment and report bugs please!
50% PUZZLE GAME, 50% PIXEL-POP-ART PROJECT, 100% WEIRD!
In this old-school cyberpunk-themed game, you are fighting to control the spread of a binary virus in a computer’s memory. By doing so, you progressively reveal the portrait of a famous ‘80s British pop-star. The virus is both friend and foe though, as only recovered memory blocks (those that were once infected) display parts of the hidden picture.
There are two visualisation modes: “scanner” which shows the whole memory, where infected blocks appear as “static” and recovered ones as bits of the background image, and “zoomed in” where both types display a binary number between 0 and 3 (“00”, “01”, “10” and “11”). You toggle between modes by pressing the “Z” key. In both modes, navigation uses the directional (arrow) keys. When you press “Z” while in “scanner” mode to enter “zoomed in” mode, the block that was at the centre of the green crosshair is selected.
While “zoomed in” you can repair memory blocks by swapping them. There is a single rule: you can exchange positions between the selected block and one of its four adjacent neighbours IFF (if and only if) they are both infected AND the neighbour’s number is one unit higher (modulo 4, hence “-P” for “periodic”). In other words: if the selected block is “00” it can be swapped with an adjacent block numbered “01”, “01” with “10”, “10” with “11” and “11” with “00”. To swap, keep “X” pressed while typing the arrow key pointing to the targeted neighbour. After a correct move, the selected block will have changed state from “infected” to “recovered”, the targeted neighbour will have become selected and their binary values will have been swapped.
N.B.: the epidemic pauses while “zoomed in”. “Recovered blocks are immune to the virus and cannot be re-infected. Any infected block completely surrounded by recovered neighbours recovers spontaneously. In “zoomed in” mode, recovered blocks have black digits on white background, infected ones the other way around. The selected block is highlighted (brighter). Susceptible blocks (not yet infected) are marked by two dots. From a fully infected state, there is always at least one solution (i.e. a sequence of 1023 “swap” moves that will result in all blocks being recovered). Good luck finding it though! ;-)
My first completed (or thereabout) pico-8 cartridge. As you might guess, I have a soft spot for "2001, A Space Odyssey", and this work is my tribute to it (and other "optimistic" Hard Sci-Fi, a sadly endangered genre).
The gameplay is admittedly a bit basic: you simply shuttle between two space stations (one in low, the other in high orbit), using as little fuel and time/oxygen as possible. The final score is 1000 points for each successful docking, minus 10 points for each fuel and oxygen unit consumed (both replenished after each docking).
Orbital dynamics are accurate, apart from the timescale obviously. Directional arrows control the thrusters of the Orion shuttle, "Z" is for docking when close to the hub of your destination station (the "selection" box will flash when this is the case). Delta-V is deliberately ignored (too hard to manage, particularly at this breakneck simulation speed! ;-)
Everything else is pretty much self-explanatory. Press "X" when docked to exit the game and see your score. The orange curve is of course your craft's projected trajectory. Labels on the edge of the screen indicate the direction of each space station (useful when out of sight). The "F" and "O" values near the centre of the screen are your current "Fuel" and "Oxygen" reserves (I kid you not!) Running out of either will end the game, as will entering the atmosphere (zero score!)
I hope you enjoy practicing your orbital flight skills!