Jump to content
The Dark Mod Forums

Recommended Posts

Posted

The Problem

Readables are available in a wide range of TDM bitmap fonts. Unfortunately, the majority of these fonts lack non-ASCII glyphs for European languages, and it would be a prohibitively lengthy task to craft them. This is one of several translation hurdles. (Another is soliciting, organizing, and distributing the work of human translators; see “AI for Translations: An Exploration” for work on an alternative. This also promotes the use of meaningful alphanumeric #str_ IDs - possibly automatically generated – instead of traditional numeric.)

A Proposed Solution

Suppose that when a particular page of readable is shown, it is shown first is English, with the mapper-specified font (e.g., Camberic), and then, after a number of seconds, shown in the current user-selected language, with a different font (e.g., Stone), one that offers the needed diacritics? And with the translated font size scaled down to accommodate potentially more-lengthy translated strings?

Both the English and translated text can be viewed in sequence. That opens the door to “quick and dirty” default translations, e.g., machine translation. In particular, the reader may sometimes be able to work-around any layout problems and sub-optimal translation by consulting the English text.

(Nevertheless, default translations may sometimes miss subtle nuanced hints, so the ability to improve them with tweaked text is a necessity.)

The Proposed Mechanics

Recall that the game engine currently passes these values to a readable’s gui:

  • gui::title
  • gui::body

With a multipage readables, the content of these parameters changes as pages are flipped.
For clarity, it is proposed to replace them with:

  • gui::titleEnglish
  • gui::bodyEnglish
  • gui::titleTranslated
  • gui::bodyTranslated

The latter 2 would be just like gui::title and gui::body, except that they would serve empty strings when the current language is English or there is no translation available in the current language (and so be used for gui code program logic, to suppress a transition). Observe that this behavior does not substitute an English string for a missing non-English string.

Skip the remainder of this section if details are not of interest.

Each stock readable .gui would need a one-time conversion to use them. Instead of the traditional 2 winDef overlays for text, there would be 4, corresponding to the 4 text-passing parameters just mentioned. This allows the translated text to fade in while the English text fades out, when an onTime event starts the transition (at 2 seconds in this example). Here is the fragment of .gui code that has been altered:

Spoiler

 

...
#include "guis/readables/readable.guicode"
// readable.guicode already defines READABLE_FADE_TIME as 200
// Could be moved to guicode...
#define READABLES_TRANSLATE_FADEIN_START 2000
#define READABLES_TRANSLATE_FADEIN_DONE 2200

windowDef Contents
{
    ...
    float hasTranslation 0
    float translationShown 0
...

    windowDef titleEnglish
    {
            WORLD_SCALE
            rect 30, 56, 260, 310
            forecolor 0, 0, 0, 0 //1st show before fadein. keep at 0,0,0,0
            font "fonts/camberic"
            text "<title>"
            textscale 0.4
    }

    windowDef bodyEnglish
    {
            WORLD_SCALE
            rect 30,56, 260, 310
            forecolor 0, 0, 0, 0
            font "fonts/camberic"
            text "<body>"
            textscale 0.31
    }

    windowDef titleTranslated
    {
            WORLD_SCALE
            rect 30, 56, 260, 310
            forecolor 0, 0, 0, 0 //1st show before fadein. keep at 0,0,0,0
            font "fonts/stone"
            text "<title>"
            textscale 0.33 // Keep font smaller than original for languages with more chars per sentence.
    }

    windowDef bodyTranslated
    {
            WORLD_SCALE
            rect 30,56, 260, 310
            forecolor 0, 0, 0, 0
            font "fonts/stone"
            text "<body>"
            textscale 0.24 // Keep font smaller than original for languages with more chars per sentence.
    }

    onTime 0
    {
        ...
        set "titleEnglish::text" "$gui::titleEnglish";
        set "bodyEnglish::text" "$gui::bodyEnglish";
        set "titleTranslated::text" "$gui::titleTranslated”; // Differs from 2.12 & gui::title in that empty if no translation available for current language.
        set "bodyTranslated::text" "$gui::bodyTranslated"; // likewise
        set "hasTranslation" 0; // until we know better
    }

    onTime 10 // Needs to be separate block from onTime0 due to early evaluation issues
    {
        if( "titleTranslated::text" == 1.0 || "bodyTranslated::text" == 1.0 ) // 1.0 if non-empty
        {
            set "hasTranslation" 1;
        }
    }
}
windowDef ContentsFadeIn
{
    notime 1
    onTime 0
    {
        transition "titleEnglish::forecolor"          "0 0 0 0" "0 0 0 0.85" READABLE_FADE_TIME;
        transition "bodyEnglish::forecolor"       "0 0 0 0" "0 0 0 0.85" READABLE_FADE_TIME;
        set "Contents::translationShown" 0;
    }

    onTime READABLES_TRANSLATE_FADEIN_START
    {
        if ( "Contents::hasTranslation" )
        {
            // Fadeout...
            transition "titleEnglish::forecolor"          "0 0 0.1 0.95" "0 0 0 0" READABLE_FADE_TIME;
            transition "bodyEnglish::forecolor"       "0 0 0.2 0.75" "0 0 0 0" READABLE_FADE_TIME;
            // Fadein....
            transition "titleTranslated::forecolor"          "0 0 0 0" "0 0 0 0.85" READABLE_FADE_TIME;
            transition "bodyTranslated::forecolor"       "0 0 0 0" "0 0 0 0.85" READABLE_FADE_TIME;
        }
    }

    onTime READABLES_TRANSLATE_FADEIN_DONE
        {
        if ( "Contents::hasTranslation" )
        {
            set "Contents::translationShown" 1;
        }
        }
}

windowDef ContentsFadeOut
{
    notime 1
    onTime 0
    {
        // Fadeout...
        if ("Contents::translationShown" == 0)
        {
            transition "titleEnglish::forecolor"          "0 0 0.1 0.95" "0 0 0 0" READABLE_FADE_TIME;
            transition "bodyEnglish::forecolor"       "0 0 0.2 0.75" "0 0 0 0" READABLE_FADE_TIME;
        }
        else
        {
            transition "titleTranslated::forecolor"          "0 0 0.1 0.95" "0 0 0 0" READABLE_FADE_TIME;
            transition "bodyTranslated::forecolor"       "0 0 0.2 0.75" "0 0 0 0" READABLE_FADE_TIME;
        }
    }
}

Aspects of this Design – Transition from English

The transition is timed, so no extra “Translate” button is shown, nor a hard-to-come-by hot key required. If you want to see the English again, you would briefly navigate away from the page to another, then return; or, if a single-page, close and re-open it.  A simple implementation (as the code above and example below) uses a fixed, hard-coded time.

Alternative Mechanism. At some cost to code clarity, it is probably possible to get by with just the 2 normal text-passing parameters (gui::title and gui::body) and their traditional 2 overlays, though additional variable(s) would be needed for tight time-synchronization between engine and gui; and overlapping fade-in/fade-out between English and translation would not be possible.

Advanced Version. In the longer term, timing could be made more flexible, by passing it as parameter from the engine, e.g.:

    “gui::transitionTime”

Where does this value come from? While it could somehow encoded into the .xd file by the mapper, I prefer a different approach. Have the engine calculate it from character or word count of the body, with user-specified globals for reading rate and min and max bounds, e.g.:

    sys_readablesWordsPerSecTransTime
    sys_readablesMinTransTime
    sys_readablesMaxTransTime

A drawback of a timed transition is that additional reading time is needed to get to the translations, which may, with immobile readables, increase risk of discovery by guards. So having these additional user controls would let a user get to the translations faster, even skip the English entirely by setting bounds to zero.

A Simulated Example – FM “readableTranslationFadeIn”

In the absence of engine support for the 4 text-passing parameters, it is still possible to make an approximately-functional mockup using some hard coding. However, this prototype DOES NOT suppress the transition when the current language is English. That is, it shows (rather than prevents) an English-to-English transition with change of font & font-scale.

TDM with the languages set to “Francais” (French). The first screen shot shows page 1 of a 3-page scroll, momentarily displayed in English with Camberic title and body.

translation_fadein_page_1_English.thumb.jpg.13050b96cc39ec21cf6965174417c429.jpg

After a few seconds, it transitions to the second screen shot, in French in Stone font. With accents.

translation_fadein_page_1_French.thumb.jpg.dd0e832cfec32ce3eadc8edb2a99541f.jpg

While shown here as a scroll, this approach should be easily adaptable to books and sheets.

About the Example’s Implementation

The screen shots are from a prototype FM: readableTranslationFadeIn

Notable files are:

  • guis/readables/scrolls/scroll_calig_camberic.gui, a custom override of the standard Camberic scroll readable, with the translation transition mechanism from above, plus additional simulation fakery described below.
  • strings/all.lang, a UTF-8 file containing 6 #str_ (2 per scroll page – title & body) in each language section. Only the [English] and [French] sections were implemented. The English example content was loosely derived from the St. Lucia FM. The English text (without #str_ structuring) was manually converted to UTF-8 French using Google Translate (website, not API).
  • strings/english.lang & french.lang. These were generated from all.lang using my gen_lang_plus program to create the 8-bit “ANSI” versions as required, e.g., ISO-8859-15 encoding for French.
  • xdata/readableTranslationFadeIn.xd, that contains the #str_IDs for the 3 scroll pages.

Within scroll_calig_camberic, this simulation had this fakery:

  • “gui::title” and “gui::body” were stand-ins for hypothetical parameters “gui::titleTranslated” and “gui::bodyTranslated”;
  • The English text was hard-coded, and the appropriate content selected by actual parameter “gui::curPage”, to make up for missing hypothetical parameters “gui::titleEnglish” and “gui::bodyEnglish”.

The READABLE_FADE_TIME is currently set to 2 seconds for testing. Probably 5-6 seconds would be better during game play.

Aspects of the Design – Font Scaling

As mentioned earlier, the translated font is scaled to make the text smaller than the original, to accommodate languages that need more room. A simple implementation (like in the example code) uses fixed values with “textscale”. So the textscale for the two Translated winDef overlays is smaller than for the 2 English winDef overlays. Specifically, in the example GUI code, the text scaling factors from the original Camberic readable were retained:
            textscale 0.4 // titleEnglish
            textscale 0.31 // bodyEnglish

and supplemented by (with a different font, namely Stone):
            textscale 0.33 // titleTranslated
            textscale 0.24 // bodyTranslated

The goal is to keep the rendered text smaller than the original English rendering for languages with more characters per sentence. These values, while hard-coded, will differ across readables (due to different starting fonts), and would need to be experimentally determined.

But this treatment, with just a fixed scaling value that is independent of both text content and current language, is unlikely to be very satisfactory. Better ideas, needing additional engine modifications, will be considered in a follow-on post.

Additional Considerations

When Authoring the XD File. Recall that TDM is relatively inflexible when using #str_ within an .xd file. So this form will not work:
    "page1_body"    :
    {
        ""
        ""
        "#str_fm_scroll_camberic_pg1_body_parish_inspection_excerpts" 
    }
Instead use
    "page1_body"    : "#str_fm_scroll_camberic_pg1_body_parish_inspection_excerpts"
With the 2 leading linebreaks moved into the #str content as leading \n\n.

When Testing. If there is a mismatch between the TDM Language setting and the PC’s language setting (e.g., under Windows), then some characters may turn out wrong or indicated as missing (e.g., as boxes). The degree will vary by language, and is unlikely to be seen in the initial English render (because that’s almost all in ASCII, common to all the ISO encodings.) Even with such mismatches, the translation can be reviewed as to overall length and where linebreaks occur.
Be aware that direct editing of *.lang files is not recommended, and could risk converting from a particular “ANSI” raw 8-bit encoding into “UTF-8”.

Applying this Technique More Broadly. A few fonts have oddball glyphs for certain characters, e.g., a skull and crossbones in Treasure Map. This would require special handling during translation.

For Briefings, Objectives, and Messages, similar approaches can be conceived. However, for each of these (and different from readables), only one particular font is routinely offered. And there are alternative designs to be considered. For instance, the English and Translated text could be shown simultaneously side-by-side in various ways, instead of sequentially. The Objectives have the additional complication that the font size is already user-adjustable.

 

  • Like 3
  • 2 weeks later...
Posted

More about Dealing with Translated Text Expansion across Languages

The Problem: Changes to Text Length upon Translation

English is a relatively terse language, in most writing styles and subject domains. Translations to most other TDM-supported languages (except perhaps Nordic languages) tend to be somewhat longer. How much longer? It varies. (I put together a table of language-specific estimates from translation companies, but they're all over the lot. Forget about it.) "Worse case" estimates can be over 30% for body text and over 100% for single words.

But I think a better focus is on "most case" estimates, which tend to be in the 10-15% expansion range. With possibly somewhat less for body text compared to title text.

General Coping Strategies

Consider a multi-page word processing document (e.g., MS Word). Usually, there is text flow from one page to the next. But you can enforce page breaks when you need them.

Our readable's .xd format in effect always enforces page breaks. So text flow, induced by translation, has to be either minimized (by scaling) or faked by manual intervention. Manual intervention involves going to the string tables in various .lang files and moving words from one readable page to another. And iterative testing.

No matter what, it is desirable for TDM to offer a set of standard (but under this proposal, revised) readable .gui that are "good enough" for most cases, without needing frequent custom overriding by the FM author.

Implementing a Simple, Fixed Scaling Independent of Current Language and Actual Text

This involves the following:

  • Values of "textscale" for bodyTranslated and titleTranslated are hard-coded (as with bodyEnglish and titleEnglish.) A Translated value is said to be scaled relative to the corresponding English value. The "faked" gui example earlier does this.
  • These scaled values will differ across readables, depending primarily on starting English font, but secondarily on layout attributes affecting line widths, line counts, and word wrapping.
  • The values are experimentally determined. It is hoped that with representative text samples, values could be determined that are "good enough" as FM defaults.

On that last point, earlier when I defined what titleTranslated and bodyTranslated were, I said:

"The latter 2 would be just like gui::title and gui::body, except that they would serve empty strings when the current language is English..."

But to do testing, you need to serve English text as well, so ideally there must be an additional boolean CVAR, e.g.:

sys_readables_debug_show_english_as_if_translated

OK. Within the 3-point framework, there are two approaches. Consider a given .gui's "scaling ratio", the ratio of English textscale to Translated textscale. (There can be different ratios for body and title.)

Approach 1 – Scaling Ratio to Only Handle Font Change, with Added Pages

Under this approach, the ratio of English textscale to Translated textscale only accommodates the change of font, not expansion due to translation. More precisely, this "Equivalent Size" ratio attempts on average to keep a string (either a title or body text) rendered in both fonts to the same length. Thus, it is best determined by English-to-English "translation". (If both fonts are the same, e.g., Stone, the ratio would be exactly 1.0)

Upsides: Translated text font remains fuller-size. Good for pages with short English body texts. Good for pages with no or very short English titles. Vertical text collisions between title and body less likely.

Downsides: For full body texts, lots of manual flow work to next-higher-page-number. Often English version will need an extra empty page to accommodate. With full title line, more likely to cause less-desirable text wrap, with text collisions between title and body. Not helpful for conserving page breaks.

Approach 2 – Lowered Scaling Ratio

This is our earlier simple example's treatment. The readable's .gui textscale is hard-coded to accommodate translations that are possibly somewhat longer. The ratio of English textscale to Translated textscale must accommodate both the change of font (when applicable) and "most cases" of language expansion.

Upsides: Unlikely to have to add pages. Far less manual text flow needed.

Downsides: To accommodate the expansion, font will be smaller, and many translated languages will be have somewhat-awkward layouts: title text will be too far to left, and there will be empty space in the lower page. If an English sentence spans pages, it is likely for some languages that manual text flow will still be required (either to higher-page-number or lower-page-number; with the latter, in some cases the last page might end up blank). If the expansion ratio used for title and body are not the same, vertical text collisions are more likely, requiring extra \n insertion.

A Fuller Example of Approach 2

See my testing with two Air Pocket readables. These sheet readables sport English in respectively mac_humaine and shoppinglist font. From this admittedly tiny text sample, but across all TDM languages, preliminary estimates were developed for text scaling factors.

Advanced Approaches with Variable Scaling.

I'll get into this next. No matter whether Fixed or Variable Scaling is used, some experimentation with each readable would be needed. But this would be one-time.

 

  • Like 1
Posted

Variable Scaling, based on Specific Translated Language and/or Text Content

With fixed textscale values discussed previously, a translated multipage readable that ideally would have the appearance of smooth text flow across pages will often have per-page underflow (ugly) or overflow (data loss), requiring lots of per-language #str editing (that is, word moving) to correct.

An alternative approach is to vary the textscale on each page, to nicely-approximate smooth text flow (at of course the expense of consistent font size among the pages). There are 3 approaches:

Fully automatic. It is true that at some point, the engine has all the information it needs about how each English string is laid out, e.g., where – after text wrapping - the last rendered row is within the readable's margin, and the last character within that row. It could similarly do trial layouts for the current non-English language, iteratively adjusting the textscale until the layout matches. I don't really know, but this strikes me as hard. I'll concentrate on alternatives.

Semi automatic. The engine is still involved, but just does a simple ratio calculation based on the string (English versus current language) alone, ignoring layout. The very simplest form would just look at character counts.  It would not iterate, but provide a "good first guess", and rely on manual verification and, if needed, tweaking by per-language scaling adjustment and/or #str editing.

Manual. The engine does not itself calculate variability, but you can do your own per-language scaling adjustments, which the engine will pass on to the GUI. Such adjustments may be faster for you than #str editing alone. (Arguably, with the fixed-scaling system, you can override a given .gui with a custom version, and tweak it's scaling at you wish. The proposed manual-variable implementation will avoid custom .gui overrides.)

I'll consider how the semi-automatic and manual systems could be implemented.

Aside: Scaling with "@aspect"?

Besides dynamic horizontal and vertical scaling by changing "textscale", the GUI system offers an alternative. You can append a horizontal scaling factor, to the "font" gui parameter, e.g.:

font    "fonts/stone@aspect=16:9"

If you were to specify "@aspect=4:3", that would be a scaling of 1.0, i.e., no scaling. In the engine code (DeviceContext.cpp), the scaling is calculated (for @aspect=X:Y) as

    params.scale.x = float(4 * Y) / (3 * X);

X and Y are decimal numbers, so don't have to be integers.

Can the "font" GUI parameter string value (particularly, aspect value) be changed dynamically? No example of that was found. Since "font" is a non-register, probably not. As a workaround, you could have a set of overlapping winDefs with different @aspects, that you would select among, hiding all but one. Sounds like a nightmare.

(Also, the Carleton font has a Carleton Condensed relative, which pre-dates the @aspect system and can be considered deprecated by @aspect.)

Recap: Scaling with "textscale"

As we have seen, this factor, which takes a decimal number, scales the font proportionately in both vertical and horizontal directions. Importantly, it can be changed dynamically. This can be observed with the Objectives GUI, based on a global user value setting. In tdm_objectives_core.gui:

    // overall multiplier which scales:
    //  * box sizes
    //  * text height and font
    #define OBJ_SIZE_MULT "gui::objectiveTextSize"

I will pursue a similar approach to passing a scaling factor from the engine to the .gui as a "gui::" float.

A Division of Responsibilities between GUI and Engine Code

The readables .gui does not know what the current language is, and even if you passed it in as string from the existing global CVAR, its values (e.g., "english") could not be used in .gui logic because the .gui code cannot really do string comparisons. Nor can it count the number of characters in a string.

While there may be workarounds (e.g., represent language choice as an integer enumeration; maybe associate an object script with the readable to perform calculations), a more straightforward approach is to have the GUI and engine collaborate.

Recall in our readableTranslationFadeIn example FM with the Camberic scroll, we used these fixed values for translated text in Stone font that would be of equivalent layout length (when no translation expansion is present):

            textscale 0.33 // for titleTranslated
            textscale 0.24 // for bodyTranslated

Let's give them #def names In the .gui:

#define EQUIVALENT_SIZE_STONE_FONT_TITLE 0.33
#define EQUIVALENT_SIZE_STONE_FONT_BODY 0.24

Further, let's create two new values passed from the engine, and give them #def names too:

    #define TITLE_TEXT_RATIO "gui::readableTitleTextRatio"
    #define BODY_TEXT_RATIO "gui::readableBodyTextRatio"

Let's interpret the ratio as (speaking loosely) "English text length"/"Translated text length". So that an expanded translation text causes a value less than 1.0, and a corresponding scale-down of the Stone font.

Then the translated part of the gui would have:

    textscale EQUIVALENT_SIZE_STONE_FONT_TITLE * TITLE_TEXT_RATIO
    textscale EQUIVALENT_SIZE_STONE_FONT_BODY * BODY_TEXT_RATIO

What the "Text Ratios" Mean with a "Manual" Approach

Simply put, the definition of every applicable non-English #str_ value could take an optional tab-separated third parameter, the text ratio. If not stated, 1.0 is the default.

Thus, in all.lang, you might have...

[English]
    "#str_fm_scroll_camberic_pg1_title_dear_reverend_bernard" "Dear Reverend Bernard -"
...
[French]
    "#str_fm_scroll_camberic_pg1_title_dear_reverend_bernard" "Cher Révérend Bernard,"    0.95
...

So, the creation process of files like french.lang would have to propagate this new third parameter. (Hand-editing can take care of this in the short term.)

Then the engine, when parsing files like french.lang and applying them to the readable's .xd entry, would have to pick up the specified ratio values and then deliver them, consistent with the current TDM language.

What the "Text Ratios" Mean with a "Semi-Automatic" Approach

This would be similar to the "manual" approach, except the ratio delivered to the .gui is a composite of the manual value specified in the *.lang file, and a calculation performed by the engine. The simplest calculation would be:

gui::readable...TextRatio = (Count of English characters / count of Translated characters) * manual .lang file ratio

As before, 1.0 is the default value for the optional third #str parameter. The difference here is that, because of the engine making a "good first guess", there will be far less need for the user to specify that third parameter.

Possible Improvements. Since the penalty for underflow (ugliness) is much less than overflow (words not seen), perhaps there should be an engine-applied fudge factor that would bias away from overflow:

gui::readable...TextRatio = FUDGE_FACTOR * (Count of English characters / count of Translated characters) * manual .lang file ratio

where FUDGE_FACTOR could be, oh, 0.98 for body and 0.90 for title.

Beyond that, one could imagine more sophisticated variants of this calculation. For instance, it might use font character-pixel-widths instead of character counts. Or employ heuristics with average-word-length or space-char-frequency to guess at word-wraps and number of lines. At the extreme, this heads toward the "fully automatic" approach.

 

  • Like 1
Posted

I just posted a new-feature request, to see if I can get a ball rolling on a "fixed scaling" implementation of this proposal.

https://bugs.thedarkmod.com/view.php?id=6638

Also, earlier here I mentioned the desirability of making in possible to vary the time the English is shown, before switching to translation. However, the mechanism I sketched - passing a gui:: parameter, and have the GUI code handle the switch - would not be viable. This is because onTime can not take a variable, only a literal number. Probably the engine would need to drive the switch somehow.

  • 2 weeks later...
Posted

Instead a button can make the translation activate? This way you could also switch back.

Or instead use the translated text and add a button to switch to English. I think it's better to keep control to the player.

  • 1 month later...
Posted

I did originally consider using either a key binding (hard to come by) or a button. The button would seem to require a lot of iteration and per-readable customization to find a location where it's not blocking the text. Plus i18n for its label and complex treatment of when to hide and show it (or in some cases toggle the text). I got tired just thinking about it.

So while I don't deny that player control is good, my more-limited version I feel is more-practically implementable with a reasonable amount of core-coding and GUI-hacking work for 2.14 or 2.15

  • 2 weeks later...
Posted

Now there is a big problem in translation work -  number of pages in readables differs from language to language. For example, in German or Russian text require more pages than same text in English.

I have to add pages to each readable manually, after playing mission again and again. This way seems to be exhausting.

Another way is to reduce original text. But it is a bad idea, because affects the quality o the whole game.

 

Posted

Off topic:

It would be cool if the book-text could be read out loud by a voice (maybe via text-to-speech?), then the subtitles can show the translation. This way no formatting change needs to be made.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recent Status Updates

    • Ansome

      Terribly difficult juggling map designing with work, but I'm still alive and chipping away at something very special. I'm actually making a collaboration of sorts with a friend, I make the map itself and he acts as my "Chief Scope Creep Consultant" that checks in every so often to make sure this project isn't getting out of hand. It's a good system!
      · 0 replies
    • JackFarmer

      We don't need artificial intelligence; we need artistic intelligence. 
      Ralf Hütter, Kraftwerk
      · 5 replies
    • taaaki

      The post editor for the dark themes should be working again. Apologies for the inconvenience.
      · 1 reply
    • jaxa

      Talk GabeCube:
      https://forums.thedarkmod.com/index.php?/topic/18055-2016-cpugpu-news/page/39/#findComment-508710
      · 3 replies
    • The Black Arrow

      Things have been so bad these days for me...
      Just a year ago, I've been feeling dizzy, I thought it was nothing, today's stress, that type of thing, went to sleep...Still dizzy! 9 more days dizzy, went to doctor (I would have gone on the first day if NOT for the long appointment time)
      Said it may be Neck Dizziness...I did exercises for 6 months, no changes.
      Went to a Physical Therapist, went to another, no changes.
      I've asked my doctor for a full check this time.
      I hated yesteryear so much due to personal reasons, this year might be the same.
      To be brutally honest, I'd rather have cancer or/and chronic pain than suffer dizziness any second longer, especially when nothing helps.
      Hard to enjoy Thief when you're dizzy so I was hoping this year, Winter will be best for me.
      · 7 replies
×
×
  • Create New...