YeOldeDink User Manual for 0.8

Introduction

YeOldeDink is a source port of the 1998 game "Dink Smallwood" based upon "GNU Freedink" originally developed by Beuc until 2019 and released under the GNU GPL v3. In mid-2022 it was revealed that Freedink had a bug in its variable-clearing on 64-bit builds that effectively broke the D-mod "Charlie's Legacy" on certain platforms. In the wake of this revelation, a Dink Network user by the name of Ghostknight set about to resolve this bug as well as implement a few other features mainly related to debug logging. A month or so later, another user, "Yeoldetoast" decided to fork Ghostknight's repo and add a few extra features to it. Although the new features are mainly designed for D-mod developers or cheat enthusiasts, normal people also stand to benefit from the included bugfixes and improvements.



New Features

Debug mode

Audio

Graphical

Input

Other things

List of bugs from Freedink that are now fixed

Installation

Windows

Windows builds will require at minimum Windows 7 (or maybe Vista) x64 with a DirectX 9-compliant graphics adapter. RAM usage is typically around 100-200MB so whatever PC you have available from the last 15 years or so should suffice.

The most straightforward way to install YeOldeDink on Windows is by using the full-featured Martridge front-end which should have a recent release available for download.

For manual installation, download the latest release and decompress the entirety of the archive alongside your existing dink.exe, and either select the exe in DFarc or create a shortcut to the desktop. Installing alongside 1.08 is erred against due to the possibility of write-protection on the destination location which means your settings will fail to autosave.

Unfortunately, Yeoldedink's numerous DLLs will conflict with Freedink's and must be overwritten in order for it to properly launch. If you'd like to install it alongside, it may be decompressed to a subdirectory with the exe relative path manually typed into DFarc3 (e.g. yeoldedink08/yedink08.exe).

GNU/Linux including Steam Deck

GNU/Linux AppImages will require a fairly recent glibc and an x64 distro, along with an OpenGL-capable graphics adapter. Something modern and recent such as Ubuntu 22.04 or later is recommended.

AppImages can be run from wherever they're located and don't need to be installed. You may use an AppImage integrator such as appimaged if you'd like it added to your menus. Freedink-data comes bundled unless otherwise specified meaning you shouldn't have to install anything extra except for perhaps the Liberation Sans typeface from your package manager if you'd like more authentic-looking in-game text.

Other systems

There are no releases for macOS or any other operating systems/architectures at this time.

Launching

To run YeOldeDink, you will also need a usual collection of Dink data and a few fonts that should have come included. If something is missing at startup, a box will pop up and prompt you to choose a path.

Lauching is usually facilitated through the use of a front-end such as DFarc3 or Martridge which should take care of everything for you. If you would rather not use such a program, you may either launch the program directly, upon which a box will pop up for you to choose several launch options including D-mod selection, or otherwise use the command line with the following parameters.

Command line switches

For example, to start a D-mod in 24-bit mode and windowed mode enabled you might type into cmd.exe: yedink08.exe -w -t -g F:\qcheese

If you want to specify a custom refdir path, it must be the folder that contains "dink", rather than the path to "dink" itself. For example, on Windows, assuming a standard install of freeware Dink 1.06, your refdir path would be C:\Program Files (x86)\Dink Smallwood\ without specifying "dink" at the end.

Be aware that when using AppImages on GNU/Linux you must specify the full path for refdir and game, rather than relative paths due to sandboxing constraints.

Using the Debug Interface

The debug mode interface is where the meat and potatoes of YeOldeDink are located. To access debug mode, you may select the relevant box in your front-end before launching, or otherwise press Alt+D after starting. Text boxes may be typed into by activating the console with Alt+C or by mousing over them before typing. Incrementers such as sliders may have their speed adjusted by holding Shift or CTRL while clicking/dragging.

File menu

Debug menu

Display menu

System menu

Engine Data

This menu will only be visible with "developer mode" set on in the debug menu. The windows in this menu allow you to view and edit just about every parameter within the engine itself, relinquishing the need to use scripts bound to keys or one-liner DinkC invocations from the console.

Sprites

The sprites window is divided up into three different tabs consisting of a sprite list, along with two editors. A sprite may be selected from the list tab, and then edited in either the live sprite or the editor sprite tab, assuming it's an editor sprite.

The live sprite tab provides interactive editing of all current sprites on the screen. Altering a parameter will update it immediately, and most changes should be visibly apparent. If your live sprite has a corresponding editor sprite, there is a button that will attempt to save your live changes to its editor sprite, thereby permanently altering it. Of course, due to editor sprites lacking certain parameters, not all are transferred.

The map.dat sprite editor tab allows you to directly edit parameters in map.dat, equivalent to altering them in DinkEdit. Changes will not be apparent in the corresponding live sprite unless the screen is reloaded somehow, such as by walking to the next one and walking back, or by pressing "redraw screen". The "save" button at the bottom must be pressed beforehand, however, or else the changes will be discarded.

Sprites may be added by selecting an inactive index and editing it to your heart's content, and similarly removed by pressing the "deactivate" button, or the "kill" button in the list for live sprites.

Variables

The variables window allows you to view and alter all the DinkC variables current in use. To edit one, click its name in the name column and type in your desired value at the top.

Scripts

This window will allow you to see which scripts are currently active on the screen, along with which line of it is currently being parsed. Clicking on its name in the relevant column will show you the contents of the file.

Editor Overrides

This window contains all of the data saved to the save file when commands such as editor_type() and editor_frame() are used to make burnt trees stay burnt, and barrels flat among other things. There is also a button that will completely reset any alterations on the current screen, or for a singular sprite. As the data is stored completely separately to the main sprite data in the save file, it gets its own separate editor. If a value has been overridden, a relevant warning will appear in the sprite editor alerting you to the fact.

Tiles

New in 0.8 is the tile editor. Unfortunately it is not very user-friendly, but is expected to be expanded in the future. It allows for alterations of both visible screen tiles, and manually stamped alt_hard ones.

Map Index

Allows you to edit Dink.dat parameters such as MIDI integer, outdoor/indoor status, and create new screens by copying the one you're on. The screen script is stored alongside sprite data in map.dat and must be altered in the sprite editor instead.

Hard.dat

As hard.dat is divided into two parts, there are consequently two tabs. The first allows you to view the individual tile contents by sliding the slider.

The second shows the index containing which aforementioned tiles are the default for the selected tilescreen tiles with the drag slider at the top. You will be able to clear existing default tiles, such as for when you'd like to import a new tilescreen of your own. Pressing the "reset bogus index values" button will reset all index values below zero and above 800 to zero.

Dink.ini

This tab will allow you to see which of the 1000 sequence slots from Dink.ini currently have something loaded into them. In the future it will probably also allow for init() line inputs too.

Colour Palette

The palette editor allows you to preview filling the screen, as well as various alterations in the second tab. As palettes are not applied in 24-bit mode, any alterations in the second tab will not be visible unless in 8-bit mode. Palettes may also be exported by copying them to the clipboard, after which they may be saved as a PAL file, and applied to an image in a capable editor.

Speed

The speed menu allows you to change how fast the game runs while in debug mode. Slow mode halves the execution speed.

Quick Save/Load

Saves the game into very high-numbered slots (1337-1339).

Help

Provides some in-game help roughly equivalent to this document, as well as the about box containing various acknowledgements, licensing information, and credits.

DinkC

YeOldeDink features a few new and old DinkC commands for d-mod authors, as well as various others taken from RTDink for the sake of interoperability. These include:

All of the above are also available in DinkLua under their corresponding name. e.g. dink.get_platform() in 0.86 and later.

Config file and fonts

YeOldeDink comes with a config file allowing for minor amounts of configurability of various launch parameters. The config file, by default named "yedink.ini" lives in the ancillary engine data location (yeoldedink) alongside the fonts and other necessary files. A different config file path may be specified with the "-c" command line launch parameter if you would like.

The fields are as follows:

Fonts also live in the ancillary data path, and by default will be searched for there before looking in Fontconfig on compatible platforms. If your specified display typeface cannot be found, a widely-available fallback will be attempted such as OpenSans. If the fallback can't be found, a box should pop up and ask you to manually specify a TTF font for use.

Using a joystick/controller

To use a plugged-in controller/joystick you must start without the -nojoy switch. If a controller is detected it will be mentioned in the relevant window that is found in the "system" menu. If you started without something plugged in, or opted for the -nojoy flag, you can press the "reinitialise input" button and see if it has been detected.

The button mapping is standardised across devices and cannot be changed at the moment. If you have a particularly new model that doesn't seem to be working properly, you may attempt to update the mapping database by replacing the relevant text file and then pressing the "reload button map" button.

Other things

Setting a SoundFont

YeOldeDink supports a variety of MIDI output backends when compiled with MixerX support, including the use of sf2 SoundFonts with FluidSynth. On GNU/Linux which has no system MIDI output, it is the best way to achieve high-quality MIDI output.

A SoundFont may be set in the audio settings window, but this is not persistent unless you manually set the SDL_SOUNDFONTS environment variable with the full path to the sf2 file. This may be done using "export" by doing something like export SDL_SOUNDFONTS /home/weeds.sf2 however for a more permanent solution you will want to add it to your bashrc or equivalent shell init file. If setting the environment variable worked, the path to the SoundFont will be displayed in the audio settings window upon the following launch.

Be aware that on other operating systems, setting the SoundFont may make system MIDI output inaccessible even if you press the button, with all MIDIs played through FluidSynth. Also of note is that your RAM usage will skyrocket if you're using a particularly large sf2 such as Jummbox or General User GS for example, with performance potentially taking a hit if you're using a decrepit PC.

TiMidity GUS Patches

If you'd like to use the TiMidity MIDI backend, you'll need to install a set of patches beforehand. These are a bunch of samples that allow for it to render audio rather than instantly crashing. Download these and then decompress to the root of your C:\ drive on Windows. On GNU/Linux, they may be installed with the relevant TiMidity packages from your package manager, or extracted to /usr/local/lib.

A search for "TiMidity GUS Patches" with your favourite search engine should yield myriad alternative pats in case the collection above is not to your liking, with many being available on Doom source port sites.

PNG Graphics and transparency

Along with BMPs, PNGs are supported for use but only in D-mods. Attempting to use them in your main data (refdir) will incur errors while loading.

For the sake of transparency, 24-bit graphics are not converted to the 8-bit palette in 8-bit mode which means some D-mods will look odd compared to Freedink and will require you to restart in 24-bit mode.

Positional audio and distance delay

Releases from 0.7 onwards use the SoLoud audio engine to provide SFX output, with its positional audio system used for sprites with sounds attached to them. Please see the SoLoud documentation for more information.

The distance delay parameter attempts to emulate the difference between the speed of sound, and the speed of light (e.g. a fireworks display). In this case, it helps to mitigate the blast of misplaced positional audio on savebots and other sprites that occurs upon changing screens. This misplacement is due to the player position not being updated until after a screen change has finished for the sake of backwards-compatibility.

Playsound() return values

As with previous incarnations of the Dink engine, the playsound() command may be used to return a value after which the sound may have its volume altered or snuffed out completely. Unlike these previous incarnations, however, the values return by playsound() in YeOldeDink are unique for every invocation of a sound effect. This means you cannot guess "soundbank" numbers between 1 and 20.

DinkLua

Releases from 0.85 onwards include Phoenix's Lua scripting backend, allowing for an actual programming language to be used for doing things with. The differences in programming style are documented by the author here, and a more general Lua tutorial to get you started may be found here, or a short reference here.

To use DinkLua for your mod, in 0.86 and later you should have the line "dinklua_enable" in your dink.ini somewhere. You can also switch DinkC off with the line "dinkc_off", in case you don't want to mix backends.

Be aware that script precedence starts from Lua files in your mod data, followed by those in Dink's data, before looking for DinkC d and c files, assuming DinkC is on as well.

Extra SFX features

A few new features have so far been added to SFX playback in 0.86. By default a sound can be played back like so:

sfx = dink.playsound(soundnum, hz, rand, sprite, repeat)
sfx = dink.playsound(soundnum, hz, rand, sprite, repeat)

With "repeat" being true or false, and hz optionally zero. The parameters apart from sound number are now optional, and you can write the above as:

sfx = dink.playsound(num)
sfx = dink.playsound(num)

This will cause the sound to be played back at its native speed, unattached to a sprite, and no looping in case you just want a "one-shot" sound effect somewhere.

Sound properties can be accessed and set like so:

sfxvol = sfx.vol
player:say("The volume of this sound is set at " .. sfxvol)
-- make it 1/10th as loud
sfx.vol = sfx.vol / 10
sfxvol = sfx.vol
player:say("The volume of this sound is set at " .. sfxvol)
-- make it 1/10th as loud
sfx.vol = sfx.vol / 10

Unlike in DinkC, the default volume of a sound is 100 rather than 10,000. Along with this, in 0.86 and later one may also get and set:

There are also several new functions for sounds:

-- fade the sfx to half normal volume over a period of 5 seconds
sfx:fade_vol(5000, 5)
-- fade the sfx to half normal volume over a period of 5 seconds
sfx:fade_vol(5000, 5)

Along with fade_vol, there is also:

As well as a few oscillators:

These oscillators may be reset/cancelled by setting the relevant oscillating parameter to something else. e.g. set pan to zero.

Building and developing

If you'd like to compile the source yourself, you must realise that you are set for an arduous endeavour. Like Freedink, YeOldeDink is a nightmare to get to compile, and is even more nightmarish due to the extra libraries such as SDL-GPU and SDL MixerX that you may have to build yourself. These instructions are incomplete and will be finished at a later time.

The most general of build instructions is to install all the SDL2 dev packages from your package manager, along with gettext, autoconf, and build SDL-GPU and MixerX yourself. Afterwards, run ./bootstrap, and then ./configure, and make -j8 (or however many cores/threads) to output an executable (hopefully).

MacOS >=10.14

All development of YeOldeDink is done on macOS 10.14 meaning that it is the easiest OS to compile on. The simplest way to get started is by getting Homebrew set up and then installing the freedink package which should give you most of the dependencies needed for YeOldeDink. You will also need a few autotools-related ones for running ./bootstrap however.

Windows

To build on Windows, you'll have to install MSYS2 and use the Mingw64 environment, rather than the UCRT or Clang one. Install the relevant mingw64 packages and perform the general compilation steps and pray that it outputs an exe.

GNU/Linux

Assuming an Ubuntu/Debian system, you must first install build-essential then all the SDL2 dev packages except for net, and then Lua 5.4 (for >=0.85), autoconf, autopoint, then compile SDL-GPU yourself.

Hacking on stuff and adding your own windows

All of the ImGui-relevant rendering is performed in a function called "dbg_imgui()" in "debug_imgui.cpp". Within is a giant if-statement that is triggered from the screen-rendering functions each frame when debug mode is enabled.

Within this if-statement are a bunch of smaller if-statements that toggle the display of individual windows from the menus. Please see the ImGui_Demo.cpp file for more in-depth programming examples of Dear ImGui.

For a very basic example, pasting the following into the giant if-statement in debug_imgui.cpp somewhere will show a window with the title "Dink's Life" and a read-out next time you run debug mode.

ImGui::Begin("Dink's Life");
ImGui::Text("%d", &plife);
ImGui::End();
ImGui::Begin("Dink's Life");
ImGui::Text("%d", &plife);
ImGui::End();

As you can see, the syntax is designed so that a little goes a long way. We can further expand this example by placing a button to restore the player's HP upon clicking. In Dear ImGui, buttons return "true" when clicked on and will run whatever's in the statement.

ImGui::Begin("Dink's Life");
ImGui::Text("%d", &plife);

if (ImGui::Button("Restore health")) {
    &plife = &plifemax;
}

ImGui::End();
ImGui::Begin("Dink's Life");
ImGui::Text("%d", &plife);

if (ImGui::Button("Restore health")) {
    &plife = &plifemax;
}

ImGui::End();

Known issues