Title: Boinas Verdes: De Commandos a Pyro Studios: un turbulento viaje del estrellato al olvido
Author(s): Jaume Esteve
The late nineties were a golden era for videogames, with so many great titles coming out, and most of them being released on PC. The Spanish game development scene was a far cry from the 8-bits era, but there were a few good studios remaining, and new ones appeared, like Pyro Studios. Their first game, Commandos: Behind Enemy Lines would would become an international success, but also a national example of how Spain could also create triple-A titles. The saga would spawn a trilogy, plus a mission pack (of the first game) and a first-person shooter spin-off, and the studio would release a few other titles, before pivoting to only mobile games, and lastly disappearing in 2017.
This book narrates the story of all the Commandos series games, but also tells us about cancelled prototypes of other titles, and the last decade, when they slowly faded away into nothingness. A story full of insanely hard work, some good and some (many?) bad decisions, and many, many human problems that would impede the studio from flourishing, and instead sentenced it. A story of some well known characters in the Spanish game development scene, but also of other hard workers that helped building the titles and might not have had enough recognition until now.
It is hard for me to not be subjective evaluating Boinas Verdes, because of two reasons. On the one hand I played all the titles, although, as we'll read that was common, I was one of those people who finished the first game, but then only purchased but didn't really finished the following ones (although I might now, except the FPS). On the other hand, I've had the pleasure to meet and briefly chat with a few of the main characters (except in the case of Unai Landa, that we've met a few times) and I admire them (even if, in some cases, they are not perfect).
The title covers a breadth of topics, and I was happy to find some technical details explained here and there, although always in a simple language that anybody can understand without technical knowledge. And how could a discussion about Pyro not mention Cops, a doomed title that could have been amazing (at least technically) but never materialized after 3 iterations and a lot of money invested? If anything, reading this book felt short, but around 250 pages it is quite packed, including some great illustrations and sketches of scenery and characters.
In summary, a great tribute to a great saga.
Today I wanted to write about a quick Linux and Docker/containers tip. I might write more of these, as I have gathered a non-trivial amount of Linux and Ubuntu tips, tweaks and miscellaneous things (plus some related adventures at work) that might be worth sharing.
Since Ubuntu 20.04 (and earlier at Debian), /bin
and /sbin
are symlinks to /usr/bin
. While this sounds nice and simple, it is good to be aware of this change when migrating containers from Ubuntu bionic
to focal
, because, if they copied any binary or script to /bin
, now they will error.
The error if attempting to move stuff to /bin
, while hinting the issue, is not 100% clear. It'll be something along the lines of:
ERROR: cannot copy to non-directory: /var/lib/docker/overlay2/<a-big-hash>/merge/bin
If you inspect the contents of the layer, or just do a quick test like RUN ls -al /bin
before moving your script(s), you will notice the presence of the symlink instead of either nothing or a folder.
The solution is simple, just move the scripts to /usr/bin
instead. And for clarity, change your script invocations to also run /usr/bin/<script-name>.sh
and the like. Although /bin/<script-name>.sh
will still work, it might not be clear why there are multiple, different paths.
Until recently, I barely knew about Hashbangs or Shebangs other than, when building a shell script, you have to put #!/bin/bash
at the first line of the file.
What I wasn't aware is that you can create scripts out of many file types, because the hashbang is a declaration of which interpreter to use when running the script... which means that you can run things like Python files as scripts.
Python works as a really good cross-platform language because the os
and sys
libraries allow to build platform-independent code (e.g. via path.join
). But there is a small catch that you need to be aware of when marking a file as a script.
In general, you should strive for always pointing to python3
:
#!/usr/bin/env python3
But if you still need to use python 2 (remember it reached end of life January 2020!) you should instead use python2
:
#!/usr/bin/env python2
And, if you really need compatibility with both versions of python, the only solution is to use the generic python
, because you can't specify both previous ones:
#!/usr/bin/env python
But here is the trick: Depending on the operating system, and especially on the more recent versions of Ubuntu, MacOS and the like, both the installed python version and/or any downloaded one might only be installed as python3
. There is no guarantee that there will exist a symlink to the generic python
(and can be dangerous to manually setup one).
How to solve supporting both versions then? Well, after reading the PEP-394, they advise to only use python
if you plan to run the python script inside a virtual environment (venv or virtualenv).
So there you have it, a two-step approach to support both versions at once:
a) Always run the script inside a virtualenv (easy if you use Docker nowadays)
b) Define the shebang as
#!/usr/bin/env python
I recently learned that there's a pretty decent Web Speech API, and I have the perfect (although outdated) pet project for it, my choose your adventure system: Lots of text that, with minimal cleaning, make for a nice reading.
There is a very practical online demo that will also give you a feeling of how good or bad the speech synthesizer will sound. And trust me, you should test it, as at least under Ubuntu Linux, Firefox sounds quite terrible, meanwhile Chrome is decent enough that I decided to target that browser for speech.
Most of the API consists on two objects, a single SpeechSynthesis instance to handle the main configuration, and then one SpeechSynthesisUtterance instance per sentence you wish to get read by the API.
I won't enter in the details of how to use it, because I merely followed the nice explanations and checked the source code of the demo (which are concise and good), but I will warn about one issue that I'm having with Chrome: If the sentence is too long, it gets cut, and the API seems to hang, not playing any further sound until closing and re-opening again the browser application!
In order to workaround the length limitation, I am applying the following simple split:
fullText.split(/[.,\:;!\?]| - /).forEach((textFragment) => {
const text = textFragment.trim();
if (text.length > 0) {
const utterance = new SpeechSynthesisUtterance(text);
utterance.voice = desiredVoice;
utterance.pitch = pitchValue;
utterance.rate = rateValue;
synth.speak(utterance);
}
});
You can perfectly enqueue any number of "sentences" (utterances), just make sure that each is not too big.
I might improve the logic a bit in the future, mostly if I still find too big sentences I will try to discern the aprox. max length and split to the previous full word. Also note that when reading numbers (e.g. 5.6
) it will split them. But overall, it is a nice first step, and really simple to use.
Note: This post refers to version 0.4
of the game.
I sometimes purchase early access videogames (not yet finished and sometimes even in alpha state) to support game developers. I don't do it often, though, because being an early adopter usually means coping with a lot of bugs and sometimes having to reset your game progress.
I am enjoying the slow, calm, and non-violent pace of The Planet Crafter, but with a recent update I faced a hard choice: start a new game to experience the new content, or keep with the old game and focus on finishing all the things I can... still eventually having to begin anew.
I decided to do something in the middle: Create a new savegame, but see how to alter the file and "cheat" by transferring as much as possible.
First of all, make a backup of the Survival-X.json
file located at C:\Users\<your-username>\AppData\LocalLow\MijuGames\Planet Crafter
folder (or a different drive if not installed in C:
).
If you open that file, you will notice that is some kind of ndjson file, but using \n@\n
as the line separator.
You can recover your old terraforming levels by editing the first group in the file:
{"unitOxygenLevel":156052032.0,"unitHeatLevel":52146160.0,"unitPressureLevel":7044543.5,"unitBiomassLevel":5064053.0}
Another of the first blocks contains a property called "unlockedGroups"
, if you also set that to your old values, when you reach the corresponding terraforming levels you will have again the extra unlocks (I think they are blueprint-based). Combined with the previous tweak it's a nice progress recovery. I for example had the following value:
"unlockedGroups":"MultiToolMineSpeed1,BootsSpeed1,HudCompass,MultiToolMineSpeed2,BootsSpeed2,podAngle,MultiToolMineSpeed3,RecyclingMachine,InsideLamp1,ScreenMap1,RocketMap1,Destructor1,Jetpack2,RocketMap2,MultiToolMineSpeed4,BootsSpeed3,DisplayCase,Pod4x,Jetpack3,MultiToolLight2,RocketMap3,RocketInformations1"
For context, this is how an item description line looks like:
{"id":204986269,"gId":"Backpack5","liId":0,"liGrps":"","pos":"0,0,0","rot":"0,0,0,0","wear":0,"pnls":"","color":"","text":"","grwth":0}|
And this is how a group looks:
{"id":1,"woIds":"209872472,202646469,202558410,202173013,204755405,202003892,204986269,206167325,202455419,203517384,205709091","size":12}|
From my research on the files, the basic rules are:
"pos"
attribute value), or inside a container ("liId"
property is non-zero)id
s seem to be unique, but I haven't tried crafting new ones or reusing the same idid
attribute, which contained items will have set as their liId
attributewoIds
attribute that contains a comma-separated list of item ids"id":1
"id":2
|
characterI played safe and didn't altered group "size"
attribute, and just in case didn't messed with the equipment in use group. Instead I placed the desired items in the inventory, booted the game and equipped them in-game.
As I haven't added new items, what I do when I want to convert an item into another is to go pick some generic materials, save and exit, and edit, replacing them by my desired item. This in practice is just changing the "gId"
attribute of the item.
This is a partial list of item gId
s. (there's a bigger list at NexusMods) Note that they seem to be case sensitive, and sometimes contain typos or have case inconsistencies 😅:
Alloy
Aluminium
astrofood
Backpack1
Backpack2
Backpack3
Backpack4
Backpack5
Bacteria1
Bioplastic1
Cobalt
EquipmentIncrease1
EquipmentIncrease2
FabricBlue
Fertilizer1
Fertilizer2
FusionEnergyCell
HudCompass
ice
Iridium
Iron
Jetpack1
Jetpack2
Jetpack3
Magnesium
Mutagen1
MultiBuild
MultiDeconstruct
MultiToolLight
MultiToolLight2
MultiToolMineSpeed1
MultiToolMineSpeed2
MultiToolMineSpeed3
MultiToolMineSpeed4
Osmium
OxygenCapsule1
OxygenTank1
OxygenTank2
OxygenTank3
OxygenTank4
PulsarShard
PulsarQuartz
RedPowder1
Rod-alloy
Rod-iridium
Rod-uranium
Seed0
Seed1
Seed2
Seed3
Seed4
Seed5
Seed6
SeedGold
Silicon
Sulfur
Titanium
TreeRoot
Tree0Seed
Tree1Seed
Tree2Seed
Tree3Seed
Tree4Seed
Tree5Seed
Tree6Seed
Tree7Seed
Tree8Seed
Uranim
Vegetable0Seed
Vegetable1Seed
Vegetable2Seed
Vegetable3Seed
WaterBottle1
Zeolite
Being able to recover the old terraforming parameters and unlocks, your old equipment, and optionally altering items to ease things like having your nuclear power plants and labs again, makes it kind of similar to a "new game+" mode: You maintain your progress for all practical purposes, but you will still need to rebuild your base, and gather and grow plants and flora again.
Lately I'm having fun tweaking and modifying games when either I get a bit tired of them, I finish them but want to keep playing, or simply when faced with issues like progress resets, so expect similar posts on the topic in the near future.