People say Syberia doesn't exist. But people are so wrong.

The first two installments of Syberia are now ready for testing in ScummVM!

The acclaimed series from Benoît Sokal follows Kate Walker, a lawyer from New York as she initially tries to complete the sale of the Voralberg toy factory. But quickly Kate is drawn into a search for the owner which takes her on a journey of discovery. Join her as she uncovers the owner’s fascination with mammoths, the secrets of Syberia, and a love for adventure.

You will need data files from the macOS version of the games, and a new daily build of ScummVM. The ScummVM Wiki pages for Syberia and Syberia II include instructions on obtaining those files from Windows or Linux. Please file any issues you discover in the issue tracker.

Help us test ScummVM for Android

The ScummVM Android port returns with a new update to the Google Play Store, in the beta testing channel. The new version includes all the latest features of ScummVM 2.7.0 as well as Android-specific improvements and bug fixes.

First off, our team developers have implemented a significant update to the file access system in order to use the Secure Access Framework (SAF) API for secure file access on external memory space, such as SD Cards or USB drives. This effectively should resolve a long-standing issue with modern Android devices, in particular those running Android 11 and above, whereby users could not properly access the game data folders or the save game files in the external storage.

Note that, since this change is a significant one, and one where transition cannot be automated for the end user, you will need to perform a few manual steps to update the paths of your ScummVM-added games with the new access system or to successfully add a new game for which the data files reside on the external storage, eg. on an SD Card. These steps should also appear in a pop-up when launching the new version of ScummVM app, if your device supports SAF. See our documentation page for a more detailed description of the process.

Second, our Android app now features improved key-mapping support for joysticks and modern game controllers and also allows to set the game control method per game entry or globally, per context (ScummVM UI menu, 3d engine game, 2d engine game) providing a choice between "touchpad emulation", "direct mouse" and "gamepad emulation" control.

  • During the beta phase we are interested in:
  • Severe bugs or regressions
  • Feedback on the new features
  • Suggestions for improving related instructions and documentation

If you'd like to participate in the beta testing, please follow the short instructions in this link.

Any issues encountered should be reported on our bug tracker. You can also reach out to the developer team on the forums or on Discord.

A big thanks in advance to our community members who help us polish this upcoming ScummVM for Android release!

ScummVM 2.7.0: The Real Slim Shader

May I have your attention, please? May I have your attention, please?

We are proud to announce the first release of the year 2023. Please welcome ScummVM 2.7.0 – "The Real Slim Shader".

New games

Once again, the number of available games increased substantially thanks to new engines, as well as incredible improvements across older engines.

With ScummVM 2.7.0, we officially announce support for the following games:

  • Soldier Boyz
  • Obsidian
  • Pink Panther: Passport to Peril
  • Pink Panther: Hokus Pokus Pink
  • Adibou 2 "Environment", "Read/Count 4 & 5" and "Read/Count 6 & 7"
  • Driller/Space Station Oblivion
  • Halls of the Dead: Faery Tale Adventure II
  • Chop Suey, Eastern Mind, and 16 other Director 3 and Director 4 titles

Improved support for Broken Sword series

We vastly improved the detection method used for the Broken Sword series as well. Compared to the old detection method, this allows a much higher level of granularity, so we are now able to detect even the slightest differences between all the supported versions. We tried our very best to add all available game versions, but we need your help. If you notice that your version of Broken Sword 1 or 2 is not properly detected in ScummVM 2.7.0, please get in touch with us and report your version to our Bug Tracker!

New localizations

One of our goals is to support as many localized game versions as possible, so people can enjoy the games in their native language. This time, we added support for the Chinese, Japanese and Korean versions of many games, including Beneath a Steel Sky, Inherit the Earth and I Have No Mouth and I Must Scream.

New and revived platforms

Additionally, we proved ScummVM’s portability again by adding (or bringing back) support for numerous new platforms and devices:

  • RetroMini RS90 (using OpenDingux)
  • 1st generation Miyoo (New BittBoy, Pocket Go and PowKiddy Q90-V90-Q20) with TriForceX MiyooCFW
  • Miyoo Mini
  • KolibriOS
  • 26-bit versions of RISC OS
  • Nintendo 3DS

Of course, stable platforms deserve some love as well! We are very proud to announce that support for iOS and Android devices got vastly improved for 2.7.0! We don’t want to spoil everything that we have in mind for the future with these platforms, but stay tuned — it will be awesome.

Shader-based scalers

Ah, yes, the release codename. Glad you asked. The new release provides a way to run your games with visual accuracy like you've never seen before. Do you remember the warm glow of CRTs shining on your face? Get that experience back thanks to the introduction of shader-based scalers!

ScummVM 2.7.0 already ships with a curated set of shaders we carefully hand-picked from LibRetro’s shader collection. A more comprehensive set is available as an additional download from within the application itself.

Pre-defined random number seeds

Our speedrun community can now take advantage of a new feature that allows setting a predefined seed for ScummVM’s internal random number generator. Using a predefined seed now provides the ability to have reproducible runs over and over again. Pick a seed, set your route and you are good to go!


Check out the full Release Notes for a comprehensive summary of how our developers managed to create yet another amazing ScummVM release!

You can find all of this goodness available for a number of platforms on our downloads page. If you are using Windows, macOS, or either the Ubuntu Snap or Flatpack packages, the autoupdater will assist you in updating to ScummVM 2.7.0.

As always, thank you for your continued support and happy adventuring!

ScummVM has been accepted to the Google Summer of Code 2023

This year our project was accepted to the Google Summer of Code program for the eighth year in a row (and 16th time in total).

The intention of the program is to bring new contributors to open source projects, and the eligibility rules for participants are the same as last year, with both students and non-students welcome to participate. Check the Google Summer of Code website for details of eligibility.

Participants can apply for either short tasks (about 175 hours) or long tasks (about 350 hours). The coding period typically runs from the start of June to the end of August, but there is some flexibility and the participants can opt to use a longer coding period if they are not available to work full time on the project during the summer.

ScummVM is looking for applicants! A list of suggested projects can be found on this page, but we’re open to your own ideas too. Please make sure you provide the required information in your application before submitting. We also strongly encourage you to join our Discord server and follow the #scummvm-gsoc channel where you can engage with our mentors and the rest of the team, and get advice and help on getting started with the project and writing your application.

We have gathered some information to guide you, based on our previous 15 years of experience in the program. You may start your exploration from our Google Summer of Code miniportal.

We are looking forward to your application and participation!

ScummVM 2.7.0: Call for testing!

A few months have passed since we released ScummVM 2.6.1. It's time to prepare for a new release!

Our lovely developers added support, yet again, for a bunch of new ancient games that require testing:

  • Soldier Boyz
  • GLK Scott Adams Interactive Fiction games (C64 and ZX Spectrum)
  • GLK Scott Adams adventures 1-12 (TI99/4A format)
  • Obsidian
  • Pink Panther: Passport to Peril
  • Pink Panther: Hokus Pokus Pink
  • Driller/Space Station Oblivion
  • Halls of the Dead: Faery Tale Adventure II

Besides these games, we’d appreciate it if you could check our release testing list. Maybe you’ll even find your favorite game on there that has been sitting on that shelf for way too long - otherwise, there are some demos of these games available on our website.

And since ScummVM is about playing games in general, we’ve seen notable changes across many, many engines - so this is the perfect time for giving your favorites another go.

As usual, we are not just adding support for new games. We are constantly working on improving the engines we already support and, in particular, we’ve seen some incredible work being done on the SCUMM engine. Yes, there are the usual bug fixes, but this time we are also adding a feature that helps playing the SCUMM games in a truly original fashion: Support for the original loading and saving dialogs within the GUI!

Speaking of truly original: Remember those old CRT displays we had back in the day? With ScummVM 2.7.0 you’ll be able to replicate this experience on certain platforms thanks to our new shader-based scalers. Go ahead and give it a try!

All testing must be done with stable builds, not development ones. Please report any bugs or oddities on our issue tracker.

A detailed list of all exciting new features and fixes is available in our NEWS file.

Thank you very much for your support! Let’s make ScummVM 2.7.0 a great release - together!

Escape from Hell

Time flies, I didn't notice that my last post is already 3years old... 

In the meantime, I have worked on several engines, with other devs... But today, I passed an important step in the development of Escape from Hell, an old games from Electronic Arts. I loved its spirit when it was released, played it a bit but never managed to go really far in it. So, I worked on it based on good memories and, of course, that this game is particularly obscure and unknown.



I created a PR on 23/11/2022. The game was mostly reversed, as usual without sound, but it wasn't working so well. It was riddled with bugs, savegames weren't implemented, a lot of functions and variables were using generated names... In short, it was good, but clearly not enough to be sure I would finish it some day. I didn't want to have (yet another) unfinished engine merged in master... So the PR was tagged Not To Be Merged. I got a nice pile of comments from Eugene, that was helpful to improve the engine :)




Today, exactly 2 months later, I finished implementing the last sound function, and music has been working for two days. I have given a name to all the functions and most of the variables, savegames are working, and I squashed a lot of bugs in the process...I'm now confident that the engine will be finished soon, so I modified the PR so that the team knows it's worth looking at it and consider a merge after some more polishing :)



So, don't hesitate to build it and give it a try :) It's a keyboard only RPG game, it's hard, but it's fun and you end teaming with various bad guys, such as Stalin or Gengis Khan... :)

Have fun!




 

Christmas holidays roundup

 Welcome to 2023, everyone. It's now mid-month in January, and I'm back from my long overdue Christmas holidays. Unfortunately :). Whilst I did end up having to spend some of my time taking care of work, I still got significant time to rest, read some novels and, of course, muck around with ScummVM stuff :). As with several previous years, I mostly ended up fiddling around with my disassembly of the early Legend games, and trying to re-implement them in ScummVM.

Thankfully, I was finally able to make some proper progress this year. Working further on my disassembly of the first Gateway game, I started a new iteration of the Legend engine in ScummVM using the latest meta engine/detection code, and gradually pulled in the work I'd previously done in the prior version of the engine. Then using it as a basis, I started implementing the code for the main text window. This included all the logic for caching text, line wrapping, and the -MORE- indicator. When it was done, I finally had the basis for displaying game messages.

Once that was done, for the first time, I started looking at the actual engine implementation. And I made progress, stumbling on a set of methods that implement what seemed like a basic C++ class hierarchy in C, with a table of 734 "objects" that were each one of eight different categories/types. Each type having a given amount of currently unknown data values. The only field of these structures that is currently known is a "method index" into a table of functions. Whilst the bulk of objects have a unique function, there are a few that don't have one, or share the same method. This is also how I know the code was a manual implementation of classes, since the function for getting the method index is basically a big switch statement that reads the appropriate offset, which is different for each category. If it was proper C++, they'd have a common base class and the field would be the same for all of them.

And these methods being pointed to.. what are they? It seems to be nothing less than all the per-game custom logic. With a bit of experimentation, I found that the first category was for rooms. Changing rooms in game is basically a matter of changing the room object being pointed to, and executing some code in the room for entering it. There's a global "room object num" that has the starting room by default, but by changing the value during startup in the DosBox debugger, I was able to change the room I started in.

Funnily enough, I tried changing the "room" to one of the other category types, and realized that it's type was for items. It seems the core engine has some resiliency, since by setting it to the item, the game told me that I was now "in" the item, as if it were a room :). Presumably, the other categories may represent other types of game entries, like non-inventory scenery or room exits, and their internal functions will have the logic for looking at items, moving to new rooms, etc.

This is all a big deal, since it means that when I have time free to work on it, I now have a solid starting point for figuring out game logic, and the methods they call in the engine to do the various things. Once I spend a bit more time figuring out the sentence parser, I'll be able to rapidly progress in finally supporting the Gateway game and, likely in the future, other early Legend games as well. Though it's going to be a pain having to manually implement and test each and every object function in each game. It's a good thing I have the patience to do that kind of thing. Though come to it, if I figure out all the engine methods the game calls, maybe Ghidra can assist in quickly producing readable C code.

As a final treat, a screenshot of the current engine. The listbox, font drawing, and other elements were pulled in from work done in prior years, and they still need work. Mostly, I focused on the text area, and better understanding how the game works:



Seasons Greetings

 With the end of the year upon us, I thought it was time to do a blog post. And then I double-checked, and realized that I hadn't actually done a blog post since the start of last year. Awkward! So, yes, it's definitely well past time that I did a new post :) Things have obviously moved on since the last time I posted. In that time, the AGS engine has been merged into master, and is now officially part of ScummVM. I also spent some finishing the game Chewy Esc From F5, and it now too is finally part of the official releases.

My passion has always been reverse engineering, and due to certain real world considerations, I wanted something simple to work on for the last six months. I ended up choosing Might and Magic 1 for several reasons. I had already done some minor initial work on it, and found the disassembly areas I'd already looked at fairly straightforward. Plus, we already supported the Xeen games. I figured that if M&M1 were supported, M&M2, which I think is closely based on 1, would also be easy to support in the future. Plus, Xeen was closely based on M&M3, so it would be easier to support that as well. So we could eventually end up supporting all the Xeen games 1 through 5. And since I know there's projects implementing M&M6 and later games, maybe one day they could be merged in, and ScummVM could support the entire series. And then maybe onto Wizardry and Final Fantasy :)


.Plus, given my familiarity with the Xeen engine, I was very interested in the possibility of introducing an "enhanced" mode to M&M1 that brought the user interface of the Xeen games to the primitive user interface of M&M1. With cleaner visuals for the various dialogs and niceties like the minimap, it could encourage people who never played the original to finally try out the game that started the entire series.


So, how is my work on the game progressing? As of today, I'm finally closing in on finishing re-implementing the original. All the user interface and game logic is done and tested, and all that's left is debugging the combat subsystem. Just last night I finished fixing the code relating to party members attacking the monsters, and now I need to start working on the code for when monsters attack the party. Apart from that there'll just be general testing.

Though there are a few other limitations remaining. I wasn't able to figure out the PC speaker code it uses for sound, so the game will be soundless. At least for the original un-enhanced version. Since the original only had sound in a few places, like when bumping into a wall, or a few notes when a party member is killed in combat, I don't consider that as a major loss.  I was also never able to properly figure out entirely how the original did image decoding and handled the EGA palette. The engine has it's own decoding that I figured out from trial and error, but it does mean that the monsters appear with the wrong colours. Unless I can figure out exactly how the original did the image rendering, I may simply have to use one of the online wikis to see the colors of each monster, and set them up in ScummVM to be correct..

Anyway, I'm hoping to at least get the remaining bulk of combat debugged before my Christmas holidays, and then worry about playing around with doing an enhanced version in the new year. As has been my habit in previous years, I'll likely find something else to do during my holidays. I'm kind of thinking to return to work on the Legend engine again. That seems to be my default fallback project. And who knows, one of these days I may even actually finish re-implementing one of the games :)

So seasons greetings to everyone, and I hope both myself and you all will have a good 2023 to look forward to.


GSoC Final Report

Welcome!

Google Summer of Code 2022 has now ended, so this post will wrap up everything that’s been done and what is left to do.

The branch of my repository with the latest code for The Immortal can be found here: https://github.com/Quote58/scummvm/tree/immortal/engines/immortal


What has been done

– Initial analysis of the source code and ScummVM engine skeleton [relevant post] [relevant commit]

The original plan was to continue the implementation started in a previous GSoC for the DOS version of the game, however after taking a look through the source code for each version and discussing it with my mentor, the plan changed and I began work on implementing the Apple IIGS version instead.

– Support for ProDOS with Common::Archive [relevant post] [relevant commit]

The first challenge that presented itself when I began work on the Apple IIGS version was the file format for the game itself. The Immortal was originally packaged as ProDOS disks, which was an issue because ScummVM did not have support for reading this file format at all. Adding support required learning about and understanding the way ProDOS files work,  and experimenting until I had code that could parse the entire disk and list the files within. Once it was possible to get and return files from the disk with a file name, I was encouraged to integrate this with the Common::Archive class in ScummVM, and proceeded to do so.

– Compression Routines [relevant post] [relevant commit]

Once the file could be read by the engine, I decided to begin by tackling something that looked fairly self contained. The compression/decompression routines did not seem to be tied in to any other functions within the engine, and so could serve as a way to get comfortable with what I would be doing in the rest of the engine, through something with a clear purpose and input/output. In the linked post, I talk about the process of beginning to translate the assembly of the engine into C++, with the compression routines as the example.

– Initial engine and subsystem skeletons [relevant post] [relevant commit]

After the compression functions were written, the next step was to start analyzing the files in the engine and begin to understand the main path of the game logic, the connections between different files, and ultimately create the initial engine skeletons. This meant creating the outline of immortal.cpp, kernal.cpp, and logic.cpp, and creating the necessary function stubs for everything along the way.

– Palette processing [relevant post] [relevant commit]

While creating the skeleton for kernal.cpp, I decided to implement the main palette processing functions. There are not too many functions related to this, and it was a core component of the engine, so I felt it was good to implement along the way. It also served as an example of how the assembly code makes heavy use of bit manipulation and interesting math/programming principles.

– Scope and engine outline [relevant post]

One part of translating the engine that took some time to get sorted out, was the general structure of the engine itself. It isn’t initially clear how each component of the engine relates to each other, but it is important for knowing how to structure the translation, what data types to choose, how to manage scope, etc. The linked post goes over the entire process of sorting through the files and determining the general scope and relation of each component in terms of ‘layers’ in the engine. This was important for the translation going forward, as it could inform decisions about how each new component that was translated related to the whole engine.

– Story subsystem [relevant post] [relevant commit]

The ‘story’ subsystem in the game is crucial, as it defines many of the important aspects of each level of the game. It defines what and where the objects, enemies, and more are in each level, as well as the dialog strings, the sprite animations, and more. The way it is implemented in the source code is unusual, and the linked post goes into detail about it.

– Cycles [relevant post] [relevant commit]

‘Cycles’ are the way that this engine handles sprite animations, and the linked post goes over the oddities with them.

– Flameset [relevant commit]

‘Flamesets’ are the torches that you find on the walls in each level. They are not objects or enemies, but are in fact their own little subsystem consisting of a sprite cycle, and code for interacting with fireballs, and even dimming the screen when they are ‘off’.

– Sprite rendering [relevant post] [relevant commit]

Sprite rendering involved many different subsystems and took some time. This is because the method for preparing and drawing sprites is a bit unusual, and translating it accurately was a challenge. The post goes into detail about some aspects, but there are several others throughout which detail the process of understanding them.

– Text parsing and printing [relevant post] [relevant commit]

– Hit gauge [relevant commit]

This acts as the wizard’s health bar in the game, and is drawn with sprites from the font sprite sheet.

– Implemented many functions for Kernal, Logic, Level, Room, Sprites, and more, creating the skeleton of the engine in a way that supports a continued, accurate translation


What is left to do

I had hoped to have some of the map drawing in time for this post, but unfortunately the map data is stored in multiple file types (.CNM and .UNV) which require unpacking and processing before they are usable, and the formats are specific to the Apple IIGS version of the game. I am working on it, but it will take more time to decipher.

  • Drawing level data from maze files with drawchr (requires deciphering the .CNM and .UNV files)
  • Implementing an input layer through ScummVM (the engine code currently references ‘actions’ and has function stubs that are called for input, but functions for getting input from ScummVM need to be written)
  • Object and Monster subsystems
  • Music and sound implementation
  • Filling out the rest of the static and dynamic story entries (the first level is written out and the structure is there, it just needs the data for the other levels to be written out) (the static data for Str and Cyc are included, but Motive, Program, and ObjType still need to be written out)
  • Filling out remaining functions in kernal.cpp, logic.cpp, level.cpp, and room.cpp
  • Implementing motives, pickups, and other object/enemy structures and their related functions

Conclusion

My time with Google Summer of Code 2022 has been wonderful, and in some ways I am sad for it to be over. However I am also grateful to have been a part of it this year, as I have learned a lot and have gotten to contribute to something I think is meaningful. ScummVM is a great program, and a great community.

I was hesitant at first about making these blog posts, but I ended up enjoying and learning from them. It allowed me to strengthen my understanding of the code and concepts at hand, and it served as a good organizational tool, allowing me to keep track of progress each week.

I will continue to work on The Immortal, building from I have done the past few months towards a complete implementation of the game. And if possible I will continue to update this blog with progress.


 

Lastly, I want to say Thank you. To Google and ScummVM for this opportunity, to my mentor Criezy for the advice and code reviews, to Sev and all the other ScummVM members that helped me (especially with Git!), to my brother for pushing me to apply for GSoC in the first place as well as his support and help along the way, and to anyone that has read any or all of these blog posts or simply followed the progress in any number of ways. I am truly grateful to all of you for this past summer.

Weekly Update – Text Rendering

Welcome

 

As shown above, text rendering is now implemented enough to display the introduction to the game. It’s kind of neat, because every time I had tested the game ever since implementing the logic system, it was trying to display this introduction sequence. It was just calling a function that couldn’t render text until now. Similarly, after these text sequences, it loads the first level from story, getting the basics of the room set up, but it can’t display anything until I implement the tile drawing (and some ‘universe’ properties for getting relative positions and whatnot).

There are still a few things to do for text rendering, but it can even handle ‘formatted’ text, which means the string has denoted at the start that it will use automatic page breaks and spacing. For example:

For this kind of text sequence, the game will actually check the distance before drawing a word, to see if the word will fit on the current line. If not, it will start a new line, and if there is no room there either it will clear the screen and start at the top. Very neat stuff.

The process of making text render is surprisingly complicated, but not for the reason you might think. The actual text parsing is fairly straightforward. It is the individual letter drawing that gets complex. To understand why, I need to mention first what’s going on with the text drawing at all.

For any given text, the game ‘writes’ it out to the screen. Whether it is the intro text, where it fades in to a fully rendered text screen, or it’s a dialog sequence that draws across the screen at a certain speed. In all cases, the same system is used. To draw a letter, whether it’s part of a string, or just a character on its own (ex. the password ‘certificate’, or the health bar), the game uses a virtual ‘Pen’ to do it. By which I mean, the source specifically calls it PenX and PenY. I think this refers to two things. 1. The coordinates are relative, and 2. Each letter is drawn individually, in a natural way. The first is pretty simple, ‘Pen’ coordinates are relative to the edges of the viewport. So any coordinates you give to the character drawing function will automatically assume the edges of the screen are included. The second, refers to both the fact that each letter drawn gets a potential delay (which can be influenced by what buttons are held or not held down), and that letters are drawn relative to their own size, and the size of the other letters. For example, you can see that the letter ‘i’ is much thinner than ‘m’, but it fits snugly between other letters as if they were a uniform size. The thing is, when you put together all of the sprite offsets and pen movements, there is a ton going on to draw a single pixel of a letter. The process looks something like this:

Starting with a Pen of (0,0), a text sequence starts by clearing the screen (drawing a black rectangle at the viewport), and then setting the penX to 8 and penY to 4. This is just to give any text a bit of space. Keep in mind that the screen edges get added on when the Pen becomes coordinates for the sprite drawing function.

After this, we start the string. The first 4 characters of the intro string are spaces, which simply add 8 pixels to the PenX position.

Next, the letter is a capital E, and all capitals get 8 pixels of extra space added to the X. This is because every letter will add 8 pixels to the PenX after they have drawn, to cover the basic width of a letter. However wide letters like m and w add an additional 8, and this applies again if the letter is a capital, as they are twice as large in this font. Like I mentioned before however, some letters are smaller, and actually subtract a number of pixels from the Pen. For example ‘t’ subtracts 3 pixels to make sure it is drawn closer to the last letter. This is all taken into account in the sprite sizes, but we’ll see that in a moment.

Now we are about to draw the sprite, but we’re in the middle of where we know the letter gets drawn, why is that? Well along with the Pen and screen parameters, the sprites have their own individual offsets and spacing. For letters, they have a centre X of 16 pixels. This means that before drawing, the sprite game will subtract 16 pixels from whatever X position it is at.

This leaves us pretty far away from where we know the sprite draws. But before we solve that, the next step is turning the X and Y coordinates into a pixel index (the original game used a mix of byte and pixel positions, and had to convert between them. This is because the virtual screen buffer where sprites draw contains two pixels per byte, for more info on that see the post just before this one. For ScummVM, the equivalent screen buffer is stored as one pixel per byte). After this, we can start looking at the sprite data itself, which begins with a scan line offset of 20 pixels. This offset puts our index right where it needs to be to draw the first two pixels. Following that, each scan line defines the difference in position to get to the first pixel of the next line.

Putting this all together, we can see that there are many steps to translate a Pen position, to the actual sprite being drawn.

But it ensures that text renders like that, and not like this:

Next

This is now the final week (19 – 26), so this week will be both working on the next code (which I’ll mention in a moment), and also cleaning up the code a bit, getting the commits uploaded, and then making the final GSOC blog post for the submission. The code that I will try to get working this week is for drawing the map tiles (which does not use the sprite function at all, contrary to what I thought before due to sprite properties of some kind being referenced there). This first requires loading in the ‘maze’ data, and then implementing the drawing routines for tiles. These are quite complex, and ultimately I may need to just write a function for now that interprets the data on its own, and fully implement the source process in the future. Either way, I will do what I can in the time remaining. Thanks for reading!