It all started during a week off this last November. Long story short, I had too many holiday days and I wanted to use some, so I thought: the children are at school, I guess I can rest and perhaps do something different without them.
It wasn’t a bad plan, but then I got a bad cold, and because it is likely that the source was one of the boys, the young one was ill at home the first part of the week, and then the other one the second half. Stuck at home, not feeling great, so I started playing games: a bit of “Super Mario Sunshine” –but my 3D platforming skills aren’t great–, and then settling for “Final Fantasy IX” on the PlayStation.
Not that I played a lot that first week, because I found difficult to keep focused on the game: the story is goofy and I found little game in the first 4 hours. I complained on Twitter that it was a linear story with sprinkles of combat –and not a lot of it!–. Not what I was expecting from a JRPG.
Arguably I haven’t played many of these, and it was many years ago with emulation of 8 and 16 bit titles on DOS with my Pentium 100MHz. Besides, the only one I managed to finish was Chrono Trigger, that is a bit different –shorter and more accessible, perhaps?–.
Have you played other PS1 FF games? Them all start very guided, but later the world opens and you have a lot more freedom. 4 hours in a 30+ hour game is still early. Japanese RPGs never were the ones with the most hardcore RPG mechanics anyway.
I’m now 14+ hours into the story –I’m still on the second disk of four, the median to beat the game is around 39 hours–, and it is still very linear and… easy? Granted that there have been some party splits and the story is all over the place, but so far I haven’t encountered any hard puzzles or combat –there are a couple of fights that you can’t win, and are basically scripted story–. I don’t know if I’m nailing it, or is just that FF IX is not what I was expecting.
I want to finish it during the Christmas break. Very doable to play one or two hours a day, because the boys like it, and find fun the encounters and when one of the party members execute a super-powerful move that kills a funny-looking monster.
The secret project is not secrete any more, and has a name: Hyperdrive.
I’m officially working on an vertical scroller shooter for the Amstrad CPC, targeting 64K and CPC+ cartridges –without any CPC+ specific features for now– and the Dandanator. So far it has been tested on emulators (CPC+ on CPCEC and WinAPE, Dandanator on RVM2 and CPCEC), and my Amstrad CPC 464 using the CPR file and the M4 add-on.
I don’t like games that put technical excellence over gameplay, but for now the highlight is smooth one pixel scroll at 25Hz, and hopefully the fun gameplay will come later. My own Uchussen Gamma is going to be an important influence, of course, as well as the graphic style of Dawn of Kernel.
So far I’ve been focusing on the core, that is close to be completed. After that I will start with the first round of optimizations to see how far I can get in number of simultaneous sprites on screen –on my initial tests it was 9 8x16 masked sprites, which may not be enough–, and then enemy and level design.
This is not my first SHMUP, and I already know how to do a lot of complicated things that were new to me when I made Uchussen Gamma, but the Mode 0 resolution with 2:1 pixels has some challenges –that I apparently avoided in Dawn of Kernel–.
This seems to be a recurring topic in my Twitter, because every time I start a new project I try to find what is the best way to deal with the map data. I guess I haven’t found the perfect encoding or, at least, an encoding that is good for all cases.
In this post I’m going through the different approaches I’ve used in my games.
Of course, use compression!
This is common to all my games: I compress the map data. Which is funny because, there’s always someone on Twitter suggesting it: “have you tried compression?”. Sure!
Unfortunately compression is not enough targeting some microcomputers and a big number of screens.
For example, looking at Golden Tail, it uses screens of 20x10 tiles with tiles of 8x16 (although it is irrelevant for what we are looking at here, it means the tile map is smaller). The game had a total of 40 screens –not a large map–, which adds up to 8000 bytes with no compression. That is a bit too big for a 64K single-load Amstrad CPC game.
So the idea is compressing each screen independently and you uncompress the screen you need to draw. You may get better compression ratios by grouping screens, but that means a larger memory area to uncompress a group. In Golden Tail I was still using UCL compression –which is good, but the compression library is very fiddly–, and it really helps to reduce those 200 bytes.
Now, this example may not be ideal because in Golden Tail I was already limiting the amount of tiles you can use per screen –explained on the next point– and the screens are optimised for that, but in this case UCL gives us an average of 88.4 bytes per screen, which is 3536 bytes in total, saving us a 55.8%. Not bad!
Bit packing
It is possible that you want to reduce even further the size of the map data. For example, it could be that your tile/sprite engine is using a lot of memory, or the fact that you are writing the game in C –which will use much more space than hand written assembler–. Bit packing can help to go beyond what compression can provide.
One way to do that is limiting the amount of tiles you can use on a single screen, so the tile index uses less than 8-bits, and bit packing the map data before compressing.
Continuing with Golden Tail’s example, using 4-bit per tile, one screen is now 100 bytes (we store 2 tiles in one byte), and the average UCL compressed screen is 79.5 bytes. The 40 screens are now 3180 bytes, giving us a further 4.45% of savings. Again, this is not a good example because Golden Tail’s data is already optimized to use 4-bit per tile, so the plain compression is already giving very good results even without bit packing.
What is the downside of this approach? You have less tiles to design your screens, which makes things harder, but it is just matter of practice. Golden Tail didn’t look too bad despite using a maximum of 16 tiles per screen, if I say so myself.
Let’s look at a more extreme example: Night Knight.
Night Knight screens are 16x22, which is 352 bytes per screen, and the game has 80 screens. That’s 28160 bytes!
In this MSX game I used 2-bit per tile, allowing up to 4 tiles per screen. It also has some information that is not stored in the map data and instead is added by the game: shadows and brick patterns.
By using 2-bit per tile, our screens are now 88 bytes, making the complete set 7040 bytes. Although I’m talking about only map data, game usually include entities –like enemies– that need to be added to the screen, and those are stored in sequences of bytes –in this game is 3 or 4 bytes per entity–, and accounting those the real total is 9864 (123.30 bytes per screen, on average).
If we apply compression –I used UCL in this game as well–, we get a total of 7028 bytes with an average of 87.85 bytes per screen.
Night Knight is a type of game that can use 2-bit per tile, using different tile-sets during the game, and the screen still looks nice. It always depends on the game, but I would say 4-bit per tile is a good compromise. Besides we can always cheat using an entity that allows adding tiles out of the tile-set, in exchange for some memory, of course.
Using objects instead of tile maps
So far the methods I have described are more or less level design friendly, because is just drawing your scene using tiles with your favourite map editor –I use tiled, and I explained how on a video–.
A different approach is to not use a tile map at all but describe objects instead, that will be interpreted by your map renderer to draw the scene.
Brick Rick uses 20x22 screens, which would be a tile map of 440 bytes per screen. The game has 50 screens, which adds up to 22000 bytes –without counting the entities–.
By describing each screen with a set of objects (“fill area”, “draw platform”, etc) –plus adding shadows, brick patterns, etc–, those 50 screens use 3112 bytes, with and average of 62 bytes per screen.
Obviously we want to use the smaller amount of memory to describe those objects. Brick Rick implemented 3 objects encoded as 1 byte offset from the previous object, 3 bits for the type of object, 5 bits for width, and then depending the object, there could be one extra byte.
The end result is very optimized, but the level design is tedious because we have to draw those objects, which is less direct that putting together a tile map, and we won’t have a visual cue of what the screen looks like. This may be more a mismatch of the tool I’m using than an issue with the technique, but I ended drawing the tile map and then putting the objects on top of that using a different layer. Not the end of the world, just a bit of extra work.
In this case, the end result is so tight that there is no benefit from using compression.
Like in extreme bit packing, this method depends on the type of game. If I had to design screens as detailed as in Golden Tail, I would probably need more object types, and the end result wouldn’t be as good. In the case of Brick Rick, the resulting screens are richer than what I could get with 2 or 3-bit per tile.
Using meta-tiles
Some people call this super-tiles, but the idea is the same: use an intermediate table grouping your base tiles, and then use those groups –the meta-tiles– in your map data.
This is the system I’m using in my WIP title for the ZX Spectrum 48K: Outpost.
This game is not finished, so I don’t have a lot of data to show final numbers here, but I can provide some approximations that may be useful.
Outpost screens are 32x20 tiles, which is 640 bytes. Say we go with a small game like Golden Tail, that would add up to 25600 bytes. I plan to add more screens than that, and I’m targeting the 48K model with single-load, so I should do better than that!
If we use 4x4 meta-tiles, 64 meta-tiles would be 256 bytes –the speccy is 1-bpp, and the meta-tiles don’t need to store attributes; is just an indirection to the actual tile data–, and this reduces our screen size to 160 bytes (width and height are the half of the size with regular tiles). Besides, the meta-tiles based maps have the property of generally compressing better than small tiles, so when we apply compression –in this project I’m using aPLib compression, with the awesome apultra–, we reduce this to an average of 62 bytes –with the caveat that I have designed only a few screens, but the number sounds about right to me–.
So going back to our hypothetical 40 screens, that’s now 2480 bytes –plus the 256 bytes overhead of the meta-tiles table, and probably a bit of extra code–.
The downside of this method is that the level design is tricky because we have to draw our tiles and group them in meta-tiles, and then use those meta-tiles to design our screens. In my case I threw Python to it until the problem was simple enough. At the end the game expands the meta-tiles to just tiles, so things like the collision detection are just as usual.
Conclusion
Obviously the game size doesn’t necessarily translate into more or less fun, but if the game works, more game is likely to be better. We will always want to cram in as many screens as possible, and considering that other parts of the game are harder to make smaller –graphics, the code itself–, keeping the map data under control is very important.
As you can see, there is not a “one size fits all” approach, so knowing what are your options when you start to plan a new game, is always useful to avoid ending with a good game that is too short!
Uh, what happened? I haven’t posted here for a few weeks. Long story short, the CPC cartridges turned out to be a very deep rabbit hole.
It basically allows you to have a lot of ROM –and memory is always scarce in 8-bit systems!–, so I went back to try an old idea that I discarded –and instead, I made the Dawn of Kernel, which is not a bad thing!–. I haven’t told too much about it publicly, and the main reason is that I don’t know what I’m doing, so the chances of failing are higher than usual. In fact, I have failed already –I’m on a second rewrite of the thing–.
In reality there shouldn’t be any problem with showing what are you working on, isn’t it? Sometimes things don’t work out as expected, and projects get cancelled. That’s OK, but then there is the Internet and people getting excited, and you may end with projects on your name that don’t exist and never will! For example: Moonstone for the MSX was abandoned and kind of became Night Knight –again: not a bad thing!–.
So over my short career as reto-gamedev, I have learnt to wait and see until I’m reasonably confident that I can –and I will– finish a project before getting people excited.
And that explains, partially, my lack of updates here: I’ve been having fun with this secret project –something may have leaked on Twitter, but it is still secret–, but I haven’t reached that point where I know I can finish a game.
Other than that, I have ported most of the unnamed CRPG game –it needs a name!– to use cartridge. This has been a very good exercise, for several reasons. Fist of all, I’m cleaning the code that was starting to look bad, and secondly I’m finding that not all is magic and rainbows using cartridges. I have a couple of solutions for the main issue, but it is definitely a risk factor. It doesn’t help either that SDCC doesn’t seem to have proper bank support for Z80.
As part of those changes, I have researched –and properly understood– screen splits on the Amstrad CPC, because it was bothering me a lot how hacky my wall of messages was. Now the bottom on the screen is fixed to a memory address and I have to write to it only once, independently of what memory address I’m using for the main area of the game –and this helped to push me further down the rabbit hole and the secret project–.
Finally, the progress on “Outpost” for the ZX Spectrum 48K is good, and you should know that because I released more videos of its development. These videos are fun to make, but I need to be in the right state of mind with a planned feature to implement, and I some quiet at home so I can record. Not easy!
I got to the conclusion that these work better as actual streaming, and when a session is specially inspired, that video could be preserved on YouTube. My current approach is probably the opposite, because I try to make the videos so they are good to share. In any case, the response of these videos is quite mild, so I’m not too excited to make more, considering that they require a lot of effort and slow me down in the making games part.
When the CPC boots from cartridge, our code will start executing at address 0x0000 and we have the first 16K bank mapped on that address (lower ROM, in case you want to check CPC documentation).
The strategy that I’m proposing is the following:
Address
Size
Type
Function
0x0000
16K
ROM
Code
0x4000
16K
RAM
R/W Data
0x8000
16K
RAM
R/W Data
0xC000
16K
RAM/ROM
Video memory/Mapped cart bank
You may or may not use a back-buffer with hardware (e.g. in 0x8000), but considering that we can have all our read only data in ROM, 16K for just code is probably enough.
Thanks to the properties of the memory mapping on the CPC, when we map a bank of ROM into lower ROM (0x0000) or higher ROM (0xC000), reads will go to ROM and writes will go to RAM; and mapped ROM is only seen by the CPU. This is important because the gate array can only see RAM when drawing the screen.
This is great, because we can map a bank to higher ROM on 0xC000 and write to 0xC000, even having video memory active at that address, and we will be fine because those writes will go to RAM –and is RAM what will be displayed on screen, not the mapped ROM–.
So the idea is mapping on higher ROM any of the banks as we need them, and we can use that data with RAM from 0x4000 to 0xffff, leaving on lower ROM the bank 0 with our code.
In the case of the CPC plus cartridges, there’s nothing to do, but in the Dandanator we need to configure the cartridge to support this behaviour. We can do it like this:
; SDCC syntax
; the byte pointed by iy will be overwritten
dilda, #0x8a
.db0xfd, 0xfdld0 (iy), aei
We will run this once at the start of the game.
Then we need a bank set function that takes the bank number we want to map in higher ROM. Let’s look at the CPC plus cartridge:
; SDCC syntax
; defined as __z88dk_fastcall in C - parameter in l
dilda, l; cart slots 0 - 31 start at 128
or#128
ldc, aldb, #0xdf
out (c),cldbc, #0x7f80
out (c),cei
And the equivalent code in the Dandanator:
; SDCC syntax
; defined as __z88dk_fastcall in C - parameter in l
; the byte pointed by iy will be overwritten
dildc, l.db0xfd, 0xfdld0 (iy), cei
Finally we need a function to unmap the higher ROM and have regular RAM on 0xC000. In CPC plus cartridges is done with:
; SDCC syntax
dildbc, #0x7f88
out (c),cei
And in the Dandanator:
; SDCC syntax
; the byte pointed by iy will be overwritten
dildc, #32
.db0xfd, 0xfdld0 (iy), cei
It is as simple as that!
Of course that the Dandanator has more functionality than what I’ve shown here, but if we hide these differences behind some preprocessor directives (e.g. ifdef), we can write the code once and generate both types of cartridges without any other changes –tip: look at my CPR tools to generate cartridges; using raw and padding flags gives you a Dandanator–.
And that’s all! This post is result of my own research and I don’t consider myself an expert, so if you find any issues with the text, please let me know.
Update: I added a comment in the code to remember that the opcode used by the Dandanator to process commands will overwrite a byte, so be sure that iy is pointing to a safe memory address.
The Amstrad CPC was discontinued in 1990 –that’s 31 years ago, and we will see why that’s relevant–, and the main media to distribute software was cassettes and 3 inch floppy disks. The Plus models, including the GX4000 console, introduced cartridges (in fact, the plus models don’t have an on board ROM with the firmware, and it was provided in a cartridge instead).
Despite being in 2021, cassettes are still available. There aren’t that many companies selling them, but I would say that for now the situation seems stable. The only downside is that, putting nostalgia aside, as media isn’t great. Cassettes limit the type and size of game you can make, and don’t work well for multi-load games.
The 3" disks where intended to rival Sony’s 3.5" floppy system, and we know who won that one, so the media used by the 128K models have been out of production for years and is increasingly hard to find new disks. The prices are up, and it is old stock, meaning that the media may have physical issues. We also have to remember that 3" disks won’t work for tape-only models without and add-on; and you are still limited to the 64K memory on board, unless you make your game multi-load from disk –not as bad as cassette, but the wait times are still something to consider–.
There are also ways of using a 3.5" disk drive with CPCs, but this is limited to 128K models and I would put this option as something that only the most hardcore CPC fan will do. At least the sales of games supporting this format suggest it isn’t very popular.
Cartridges, as originally intended, have a protection with a special chip that prevents third parties from producing cartridges; and those usually have features for the Plus models that aren’t backwards compatible with the regular CPCs.
We know how to bypass that protection now, so it is possible to produce Plus cartridges; but there’s still the limitation that it is intended to the CPC Plus models only –the CPC models don’t have cartridge slot, only a expansion port that is not really meant to frequently plug and unplug cartridges–.
The CPC was designed to make it easy to be expanded using ROMs, and that has been a common way to load software into the CPCs for a long time, is just that is not very convenient and it requires a higher level of commitment from the average Amstrad aficionado as it needs an expansion where you can put the ROMs. Fortunately, in the last few years things have changed.
I’m not going to write an history lesson here –I know this post may look like it already–, so excuse me if these aren’t in chronological order or if I’m missing other options I don’t know about:
Dandanator mini –page only in Spanish, as far as I know–: is a cartridge format to be plugged in the expansion port that provides a number of generic and advanced features, including support for 512K of ROM (in 16K banks), and it works on any CPC without jumpers or special configuration.
DES: the Dandanator Entertainment System, which is an interface that goes to the expansion port and supports cartridges. It has the same functionality as the Dandanator, with the difference that the expansion contains most of the functionality, and the cartridges are simpler –and cheaper–. It also makes it easier than the expansion port to plug and unplug cartridges, and these use the Game Boy Advance shells –that are cheap and easy to find–. Perhaps the only downside is that you need to buy the DES expansion, and then cartridges for the games.
Plus2CPC: this is probably the newest of the three and provides a cheap way to plug CPC Plus cartridges on any CPC and, as long as the cartridge doesn’t use any Plus features, it will work. It also offers 512K of ROM, just like the Dandanator, and uses the regular ROM mapping functions of the CPC. The Dandanator provides much more functions, but if we only look at storage, this is almost equivalent. The boards for CPC Plus cartridges are available, but not the shells (as far as I know).
So these would be three different options to distribute software in cartridges for our physical editions, and they work for all CPC models –although the two Dandanator options don’t support GX4000–. Not as cheap as cassette or 3" disks, but is instant access to 512K, and in the case of Dandanator, there are extra features –e.g. the mapping is more advanced, or saving data in the cartridge–.
The Dandanator design is public domain and anybody can build and sell them –not sure what is the status of the Plus2CPC–; which makes them more or less available, and supported by different emulators. And this is another requirement for me because: what if you don’t have the hardware?
Currently CPR files –the format for Plus cartridges, which is a container for 32 ROMs of 16K– are supported by any emulator that can emulate CPC Plus models, and the Dandanator images are supported by several popular emulators as well, so it wouldn’t be too difficult for people to enjoy the games without an actual CPC. Besides, there are modern hardware add-ons that support some of these formats –for example, the M4 can load CRT files; and of course the C4CPC for the GX4000–, meaning that you can still play the games in real hardware without having the cartridge itself.
If the games abstract the ROM mapping code, it is trivial to make the same game work in both CPC Plus cartridges and Dandanator cartridges, and it is trivial to generate CPR and Dandanator ROM files.
I’m not sure what would be the response from the community. We have seen a couple of releases recently that were Dandanator only, and these had a mixed response –the games are amazing, it was more people not having Dandanators to play them on real hardware–, and one that was CPR based (probably the best vertical shooter on the system: Alcon 2020).
I would expect that, having not too expensive and easy to use physical releases, plus the digital version that can be played with different options –both emulated and real hardware–, the CRT/Dandanator duo is probably the future of media for the Amstrad CPC. I don’t think I have capacity to fill all that ROM space, but it would take me less time to make better games, because I wouldn’t waste time wrestling with memory limits and I could use techniques that are usually unviable because they require lots of memory.
I have been investigating both CRT and Dandanator, and I can’t promise anything, but watch this space –just in case–.
It is Thursday again and looks like I have time for a early morning entry on the series, so let’s do it!
My Canvas 2D engine
I got to the point where the engine does most of the basics; which in reality is not much considering that there is no game. I have an idea to make a simple platformer with procedurally generated levels –why make things simple?–, but I got stuck when I tried to draw some graphics.
I do have some tiles that are OK, but they are not very inspiring and I suspect the end result would be too bland. In reality it feels like the type of programmer art you would expect in a game jam, so I’m not too excited.
I put it on ice until for now. Perhaps I should get some palette/restrictions from an 8-bit machine and use that as style. I’m not a big fan of modern games that looks like a ZX Spectrum game but obviously is something that would be impossible to implement on a ZX Spectrum, considering that I can make ZX Spectrum games.
It is possible that I’m overthinking this and instead I should decide that is that I want from this project. Is it just making a simple game using modern-ish Javascript as a tech demo? Is it making a platformer with procedurally generated levels? Is it a prototype to test ideas that later I could implement on an 8-bit system?
It could be all of them, but I don’t know!
Work on Outpost
After I started the combat in my unnamed CRPG –seriously, I need a name–, I programmed the PC movement and I didn’t like too much the code structure, so I decided to walk away for a couple of days.
Then I fired Outpost and… I like how this looks! The engine is solid and there are so many new things I haven’t programmed before that I feel I should finish and release it.
So I’m back to do level design, and things are looking promising, actually.
I have designed 8 objects, most of them to be used as part of a puzzle, which works more or less as “key/door”.
Perhaps the most obvious was doors –of course!–. These require the access card, and once you have it you can open them, but only in one direction –we are not going to question the overall design of the “Outpost”, are we?–.
I have some potentially interesting ideas for another 4 objects, but I still need to come out with some story more than the vague idea I have. I implemented terminals essentially to show information, perhaps as diary entries, so I should use them!
ubox MSX lib has CI
Arguably this is something I could have implemented in GitHub as well, but I think GitLab is slightly easier, so thanks to the initiative of Pedro de Medeiros –so far the only external contributor to the project–, we have added continuous integration to ubox MSX lib repo in GitLab. Currently it only compiles everything, but that’s enough for now, because it helps us to ensure no change we make will break thins that bad.
I’m thinking what can we test, really. We could run unit tests for code that is Z80 independent, and that could be compiled with a modern compiler and run in the CI containers, or we could use a Z80 emulator –doesn’t have to emulate and MSX really–, and generate Z80 and run it in the emulator.
Both sound like good strategies, but before committing to write a lot of code, I would like to be sure there are tests we can/want to write.
Titan support in SpaceBeans
In not really gamedev news, I’ve started implementing support for Titan protocol, which is a simple extension to Gemini that allows uploading files. It is one of those idiosyncrasies of Gemini, where extending the protocol is a no-no, so instead people come with these “alternative protocols” that is basically and add-on that could be part of the main protocol.
Anyway, it shouldn’t be too hard to implement, and considering that Lagrange browser supports it, I think it is going to be a nice addition to SpaceBeans. You could manage your gemlog fully from one single application!
Someone posted a link to Underrun, a JS13K entry by Dominic Szablewski, and I was impressed by the game –despite being a jam game–. So I checked its source code at GH, and a couple of things caught my eye.
First of all: how clean and simple –it is not– all looked! Very readable, despite being a game aiming to provide its functionality within some challenging space constrains (13KB!).
And secondly, turns out Javascript has classes now, and my last attempt at the language was before they were introduced in June 2015 –and adoption by browsers happened around Q1 2016–.
It is not a secret that I don’t like Javascript, but with things like Canvas 2D, it is an OK-ish language for game jams and quick prototypes. Actually, I finished two Ludum Dare using Javascript, being my last attempt 7 years ago, and the code for that one is public.
Back then I defined my own idea of Javascript, limiting what parts of the language I wanted to use, and using some techniques to have “classes” and inheritance.
For example:
varA=function(property) {
varself= {
prop:property };
self.init=function() {
// the constructor is this
returnself;
};
self.say_hello=function() {
console.log("Hello");
};
returnself.init();
};
vara=A("value");
a.say_hello();
To be honest, I don’t remember exactly how, but I had inheritance, private properties, super functions, etc. And it did work, actually.
Since then I have played with some ideas with Scala.js –by porting, more or less, my old Javascript code–, but I found that the functional part of Scala was getting in the way. At the end of the day, I liked the prototype-y feel of Javascript, and using Scala I tried to be functional and, although it is fun, it is also very distracting.
So basically I enjoy using the tools and writing the code, but I haven’t made any games with it; which is the actual point of it! Also, I’m not too convinced on how heavy the compiled code is –Scala compiled into Javascript– because, again, it goes against my idea of a short lived project that you get out of a game jam. It doesn’t need to be Scala-rock-solid.
At some point, I also looked at TypeScript, but I found it adds too little and I hate the Javascript tooling, so I thought: may be Javascript has improved now, they are making an effort with the classes, isn’t it?
Well, not completely, but may be close enough.
I have rewritten my Canvas 2D codebase to use “modern-ish” Javascript, and I think I’m going to push forward enough to make a “jam-type” of game. So far I’m enjoying it –despite Javascript; like having a typo and DoSing my machine because Firefox started allocating memory in an endless loop–, so we’ll see how it goes.
For now the classes are mostly worth the effort. There are some “gotchas” part of the classic Javascript, like the use of this, but nothing that is not manageable. And turns out my Scala knowledge is giving me some answers that I don’t think I had back in 2014.
For now, my only issue with classes has been using methods as callbacks. The problem is with this not being bound to the instance of the class when called by a callback.
For example:
classA {
resize() {
console.log("We are being resized!");
}
run() {
// won't work! this won't be bound when called :(
// window.onresize = this.resize;
// instead, use a lambda:
window.onresize= (ev) => { this.resize(); };
}
}
vara=newA();
a.run();
The solution is not too bad: just wrap the call on a lambda, and this will be bound on that context, so it works fine.
I have read some people suggesting to not use this at all, and I see some issues perhaps when using a minimizer because I won’t be able to “minimize” this –unless it performs some trick using a local variable pointing to this–. For now it is working as expected and the code is easier to read and remember, because I don’t have to do my own Javascript to make the language usable.
I have a couple of ideas I would like to implement, and they may lead to a game!
This week should be more DevOps than gamedev, but for obvious reasons –it is a series!–, I’m keeping the name.
I’m in the middle of reworking my personal server infrastructure. As result of my time at Memset I still enjoy one of their ex-employee perks –a free VPS!–, but the company was acquired and sadly the future is uncertain. It is still the same company I knew, to some capacity at least, but I don’t feel completely comfortable having critical services in there without being a customer.
I have decided to double down on Digital Ocean –I already had a box with them–, basically because I can get nice features for free, like a VPC between my machines in the same zone. It is cheap, perhaps some things are not as good as the stuff I built back at Memset, but I got to the conclusion that the pros outweigh the cons.
So I’ve been using a good amount of my free time to plan, setup, migrate, etc; and I’m not finished, but getting there.
On the dev side of things, after I released a bugfix version of SpaceBeans –my Gemini server–, I worked a bit more in my “Cherrygrove City Pokémon Center” CGI script and released it as open source. And now I realise that is only available in Gemini. Oh, well; it is not too exciting –in fact it is really a pokedex, not a Pokémon Center–, but it was interesting making a CGI using plain Python base library, without any fancy abstractions –I used to work a lot with Django–.
Anyway, not a big update, but sometimes that’s life. I’m planning to start combat in my unamed CRPG game, that definitely needs a name, when I clear a bit my DevOps backlog.
Looking great already, and as it’s my favourite genre, and rather under-represented in modern gamedev, I sincerely hope you can get it over the finishing line. But I can imagine it might be a long and arduous quest :)
And they are right. However, the problem in my opinion are the side quests. There are so many things to do, and so many things you could do, that is easy to lose focus and get distracted. And that can contribute to the game never getting over the finishing line.
Besides, there are things that I may want to do out of this project –like last’s week important Spacebeans 1.3.0 release–. And because it is a project that will take a long time, I think I must learn to re-heat it when it goes cold.
Which may be just a consequence of how I have been doing gamedev for last few years: intense and ultra-focused on one project. Once I have started a good project, I don’t work on anything else until is finished, and considering this is low priority free time activity, it means perhaps a small-ish game needs 3 months. So I need to learn to do things differently with a potentially large project, and it is going to be hard.
Anyway, there was no “this week in gamedev” last week, but I had a few side quests and there was progress. The text wall scrolls nicely –not really “scroll” but a mid-step that looks great–, revamped controls a bit to support two buttons joystick and allow a bit of “console” control –that works very well with my menus–, and added more content to the disc –quickstart party!–.
The game still needs a name, but I’m working on it!