Release EDDI 3.3 - Bring your cockpit to life

Problem is that, while now that numbers are ok, it is'nt the spoken umanization.
From english "more than two thousands and half light years" (i'm guessing, here, as i don't hear it in english) it translates to "più di due e mezzo mila anni luce" but it is wrong, as it should say (staying literal) "due migliaia e mezzo di anni luce". I see how that Humanise function is beatiful, but also how hard it is to be localized: (perhaps?) it should pick from a a table of localized phrases, not just translating words...? I really dunno, i'm just saying that it is hard to make it works for all languages but i love the idea of the Humanise function.

AFAIK, the Humanize function is English based, and for that, it doesn't draw upon a table. I believe that proper localization would require a function written from the ground up with a particular language in mind, or from the ground up with a completely ambiguous structure relying on an expanding library of cultural interpretation(s). Otherwise, you will get just what you got: literal transposition of words for their translated counterparts irrespective of proper syntax or sentence structure in that language.

(international use is on my mind heavily lately, as I wrap up the last of my system's bugs hoping to finally release a public ED profile for VA and EDDI (and bindED v2.0), where before my beta testers in countries that depict Pi as 3,14 as opposed to my countries depiction as 3.14 would have huge pauses between actions due to the loss of the decimal separator during init -- far beyond simple {DEC} conversions to {DECINV} -- and finally got it sorted after months of tinkering. Localization is so hard when you don't know 'both' languages with equal fluency; I got lucky since it's simple maths in my case)
 
Last edited:
AFAIK, the Humanize function is English based, and for that, it doesn't draw upon a table. I believe that proper localization would require a function written from the ground up with a particular language in mind, or from the ground up with a completely ambiguous structure relying on an expanding library of cultural interpretation(s). Otherwise, you will get just what you got: literal transposition of words for their translated counterparts irrespective of proper syntax or sentence structure in that language.
I'm just guessing (or wondering, or ... dreaming, so don't take what i'm saying more than a general idea):
from what i hear, i think that the functions could "pick the desired phrase" ("far more than...", "less than ....", etc) and then pass the "desired phrase index" along with the rounded numbers and "units" (Ly, credits, tons, whatever) to a "localization function" that will pick from a table the translated phrase[index] and "search/replace" the placeholders with the passed variables.
Not exaclty easy, but all we have to manage are a .... tenth? of different "colloquial numbering".... seems feasible, to me.

OR

Just provide a default personality script called by the Humanise function (or transform the Humanise in a script?) so the whole job will be made by us :)
 
I'm just guessing (or wondering, or ... dreaming, so don't take what i'm saying more than a general idea):
from what i hear, i think that the functions could "pick the desired phrase" ("far more than...", "less than ....", etc) and then pass the "desired phrase index" along with the rounded numbers and "units" (Ly, credits, tons, whatever) to a "localization function" that will pick from a table the translated phrase[index] and "search/replace" the placeholders with the passed variables.
Not exaclty easy, but all we have to manage are a .... tenth? of different "colloquial numbering".... seems feasible, to me.

OR

Just provide a default personality script called by the Humanise function (or transform the Humanise in a script?) so the whole job will be made by us :)

If it helps, I recall a discussion involving this back in summer of 2018 - there was an inline function in C# for VoiceAttack that pretty much shows what the Humanize function is all about, though I am not sure if it has changed much since way back then (obviously not the most recent change involving 1000, 10000, etc.).

Definitely would need to change some parts to ambiguous functions, and gather globalization info from the host PC to choose appropriate alternate phrases/wording.

Syntax highlighting looks crazy on this dark theme website so I turned it off - but here's the code from that Humanize inline from way back:
(VA actions of the test)
Code:
Set integer [~test] value to 4200420
Set decimal [>>test] value to 2300230
Say, 'Integer before conversion equals: {INT:~test}.'  (and wait until it completes)
Pause 1 second
Set text [~HumanizeNumber] to 'INT:~test,DEC:>>test'
Inline C# Function: Humanize, wait until execution finishes
Say, 'Integer equals: {INT:~test}. Humanized, it reads: {TXT:~testINTHumanized}'  (and wait until it completes)
Pause 1 second
Say, 'Decimal equals: {DEC:>>test}. Humanized, it reads: {TXT:>>testDECHumanized}'  (and wait until it completes)

(the inline C# Function "Humanize")
Code:
using System;

public class VAInline
{
    public static string Humanize(decimal? value)
    {
        if (value == null)
        {
            return null;
        }

        if (value < 0)
        {
            // We don't handle negatives at the moment
            return "" + value;
        }

        if (value == 0)
        {
            return "zero";
        }

        if (value < 10)
        {
            // Work out how many 0s to begin with
            int numzeros = -1;
            decimal testval = (decimal)value;
            while (value < 1)
            {
                value *= 10;
                numzeros++;
            }
            // Now round it to 2sf
            return (Math.Round((double)value * 10) / (Math.Pow(10, numzeros + 2))).ToString();
        }

        int number;
        int nextDigit;
        string order;
        int digits = (int)Math.Log10((double)value);
        if (digits < 3)
        {
            // Units
            number = (int)value;
            order = "";
            nextDigit = 0;
        }
        else if (digits < 6)
        {
            // Thousands
            number = (int)(value / 1000);
            order = "thousand";
            nextDigit = (((int)value) - (number * 1000)) / 100;
        }
        else if (digits < 9)
        {
            // Millions
            number = (int)(value / 1000000);
            order = "million";
            nextDigit = (((int)value) - (number * 1000000)) / 100000;
        }
        else if (digits < 12)
        {
            // Billions
            number = (int)(value / 1000000000);
            order = "billion";
            nextDigit = (int)(((long)value) - ((long)number * 1000000000)) / 100000000;
        }
        else if (digits < 15)
        {
            // Trillions
            number = (int)(value / 1000000000000);
            order = "trillion";
            nextDigit = (int)(((long)value) - (int)((number * 1000000000000)) / 100000000000);
        }
        else
        {
            // Quadrillions
            number = (int)(value / 1000000000000000);
            order = "quadrillion";
            nextDigit = (int)(((long)value) - (int)((number * 1000000000000000)) / 100000000000000);
        }

        if (order == "")
        {
            return "" + number;
        }
        else
        {
            // See if we have an exact match
            if (((long)(((decimal)value) / (decimal)Math.Pow(10, digits - 1))) * (decimal)(Math.Pow(10, digits - 1)) == value)
            {
                return "" + number + " " + order;
            }
            if (number > 60)
            {
                if (nextDigit < 6)
                {
                    return "Over " + number + " " + order;
                }
                else
                {
                    return "Nearly " + (number + 1) + " " + order;
                }
            }
        }
        switch (nextDigit)
        {
            case 0:
                return "just over " + number + " " + order;
            case 1:
                return "over " + number + " " + order;
            case 2:
                return "well over " + number + " " + order;
            case 3:
                return "on the way to " + number + " and a half " + order;
            case 4:
                return "nearly " + number + " and a half " + order;
            case 5:
                return "around " + number + " and a half " + order;
            case 6:
                return "just over " + number + " and a half " + order;
            case 7:
                return "well over " + number + " and a half " + order;
            case 8:
                return "on the way to " + (number + 1) + " " + order;
            case 9:
                return "nearly " + (number + 1) + " " + order;
            default:
                return "around " + number + " " + order;
        }
    }
    public void main()
    {
        String[] inputVars = VA.GetText("~HumanizeNumber").Split(',');
        foreach (string i in inputVars)
        {
            String[] input = i.Split(':');
            decimal? number = 0;
            switch(input[0])
            {
                case "INT":
                    number = Convert.ToDecimal(VA.GetInt(input[1]));
                    break;
                case "SMALL":
                    number = Convert.ToDecimal(VA.GetSmallInt(input[1]));
                    break;
                case "DEC":
                    number = VA.GetDecimal(input[1]).Value;
                    break;
            }
            VA.SetText(input[1] + input[0] + "Humanized", Humanize(number));
        }
    }
}

(same on pastebin with proper syntax highlighting: https://pastebin.com/U5Z10Xd5 )
 
Last edited:
I see. I've also found the Humanise function on Github also, and the "problem" is the same:
"nearly " + number + " and a half " + order;: this order of concatenation is'nt the right one in every language.
Spaking of Italian only, the elements are the same, but some are swapped. Other than the fact that we have two words for "thousands" (i'm unable to explain it, so i give you this wordreference link). There's may be a lot of other cases for other languages, so I think Humanise should handle the "logic" behind the logic of picking the right phrase and then calls something else that is "culture specific" (that's the right jargon, right?).

A question: should i have the time to try to sort out something.... should i do it? If yes, should i fork on github the project? i've almost 0 experience in there....
 
I see. I've also found the Humanise function on Github also, and the "problem" is the same:
"nearly " + number + " and a half " + order;: this order of concatenation is'nt the right one in every language.
Spaking of Italian only, the elements are the same, but some are swapped. Other than the fact that we have two words for "thousands" (i'm unable to explain it, so i give you this wordreference link). There's may be a lot of other cases for other languages, so I think Humanise should handle the "logic" behind the logic of picking the right phrase and then calls something else that is "culture specific" (that's the right jargon, right?).

A question: should i have the time to try to sort out something.... should i do it? If yes, should i fork on github the project? i've almost 0 experience in there....
Am I correct in believing then that "and a half" numbers are where the problem lies and that other numbers are OK?
What is the correct order of concatenation in Italian? "nearly " + number + order + " and a half"?
 
Am I correct in believing then that "and a half" numbers are where the problem lies and that other numbers are OK?
What is the correct order of concatenation in Italian? "nearly " + number + order + " and a half"?
exactly.
but while it works from millions and up, it wont for thousands and hundreds unless using "migliaio/a" and "centinaio/a" instead of "-mila" and "-cento".
-edit (again)-
thinking at it, for thousands and hundreds the simplest (and still right) way is to round the number to 1500. "nearly 1500 inhabitants" is perfectly right, and it does'nt requires too much hassle :)
 
Last edited:
Re Humanise() I was wondering when the issue of word order would rear its ugly head. We are going to continue thinking about this while we proceed with the release as planned.

First thing to say is that localised Cottle scripts are of course not obliged to use Humanise() if it isn’t working for them, and they can speak large numbers however they choose.

It’s very difficult to create a fully general localisable implementation of Humanise() but it might be possible to do something where the logic is in the C# code and there is a localised template string for each of the use cases, specifying the word order.

As a recent student of Russian, I am aware that it has a special word for "one and a half". And like most(?) Slavic languages, there is the issue of genitive singular for 2..4 vs genitive plural 5 and more.
 
@VerticalBlank Hey dude, I recently have ((EDDI entered supercruise)) kicks me into witch space under {TXT:Environment}. It's very random when it happens but usually it happens as I engage supercruise when launching from planet, or engaging supercruise after undock. I caught it in the first seconds of this vid. Can you take a look please? And see what else you need from me to ID? Cheers.

Source: https://youtu.be/CYkWl830aHQ
 
@VerticalBlank Hey dude, I recently have ((EDDI entered supercruise)) kicks me into witch space under {TXT:Environment}. It's very random when it happens but usually it happens as I engage supercruise when launching from planet, or engaging supercruise after undock. I caught it in the first seconds of this vid. Can you take a look please? And see what else you need from me to ID? Cheers.

Source: https://youtu.be/CYkWl830aHQ
Thanks for the video evidence!

I'm the non-VA-using dev whereas T'Kael is the VA-using dev. So I'll wait for TK's input.
 
First thing to say is that localised Cottle scripts are of course not obliged to use Humanise() if it isn’t working for them, and they can speak large numbers however they choose.
Yep, but i think that, for the less programming/scripting inclined users, it's a nice thing to have.

It’s very difficult to create a fully general localisable implementation of Humanise() but it might be possible to do something where the logic is in the C# code and there is a localised template string for each of the use cases, specifying the word order.

As a recent student of Russian, I am aware that it has a special word for "one and a half". And like most(?) Slavic languages, there is the issue of genitive singular for 2..4 vs genitive plural 5 and more.

The question therefore becomes: how much can Humanise() be expected to do?
I shall reflect on this.

I agree, that's why i was wondering about a "table".... or a "callback script", or somewhere to pick up the localized way to say what Humanize thinks it need to be told.
Humanize should do the "intelligent part" (which is the harder one for the non-programmer script user) and leave the localization somewhere else.
 
Hi there.
It's my first try with EDDI and i need a little help.
All i want is that EDDI gives me the right amount of my shield cells in Voice Attack.

I tried this code:
Code:
{for compartment in ship.compartments:       
    {if compartment.module.name = "Shield Cell Bank":    {set cellbank to cellbank + 1}
        {set ammo_cells to ammo_cells + compartment.module.ammoinhopper + compartment.module.ammoinclip}
        {SetState('eddi_ammo_cells', ammo_cells)}       
 }
}

With {ammo_cells} EDDI gives me a number. But how could i use this in VA?

Any help would be appreciative.
 
Hi there.
It's my first try with EDDI and i need a little help.
All i want is that EDDI gives me the right amount of my shield cells in Voice Attack.

I tried this code:
Code:
{for compartment in ship.compartments:     
    {if compartment.module.name = "Shield Cell Bank":    {set cellbank to cellbank + 1}
        {set ammo_cells to ammo_cells + compartment.module.ammoinhopper + compartment.module.ammoinclip}
        {SetState('eddi_ammo_cells', ammo_cells)}     
}
}

With {ammo_cells} EDDI gives me a number. But how could i use this in VA?

Any help would be appreciative.

Would love to lend my experience, though I deal with EDDI in VoiceAttack only, not much familiar with the cottle scripting or creating functions directly in EDDI but in VA itself (through command actions or inline functions). I may be unable to help, but figured I'd ask anyway: Are you using a command in VoiceAttack to trigger this function? Or how/where is this script executed from? If this is from the plugin, and it has vaProxy access, you can use that to set that as an integer variable in that code:
C#:
public static void VA_Invoke1(dynamic vaProxy)
{
vaProxy.SetInt("eddi_ammo_cells", ammo_cells);
}

which can be retrieved by VoiceAttack using a token {INT:eddi_ammo_cells}
Code:
Set integer [MyIntVarNameOrWhatever] value to the converted value of {INT:eddi_ammo_cells}
 
Hi there.
It's my first try with EDDI and i need a little help.
All i want is that EDDI gives me the right amount of my shield cells in Voice Attack.

I tried this code:
Code:
{for compartment in ship.compartments:    
    {if compartment.module.name = "Shield Cell Bank":    {set cellbank to cellbank + 1}
        {set ammo_cells to ammo_cells + compartment.module.ammoinhopper + compartment.module.ammoinclip}
        {SetState('eddi_ammo_cells', ammo_cells)}    
}
}

With {ammo_cells} EDDI gives me a number. But how could i use this in VA?

Any help would be appreciative.
You can access the State variable directly in VA by name. In the example you have, you can use "EDDI state eddi_ammo_cells". So for example, you could set a new decimal value to 'another variable' like this:-
1610046822184.png


I believe this should do what you are looking for. :)

Edit: I should have said, this will obviously only work after you have run the code you mentioned first, so that the State variable is then available to VA.
 

Attachments

  • 1610046636545.png
    1610046636545.png
    33.7 KB · Views: 52
Last edited:
I agree, that's why i was wondering about a "table".... or a "callback script", or somewhere to pick up the localized way to say what Humanize thinks it need to be told.
Humanize should do the "intelligent part" (which is the harder one for the non-programmer script user) and leave the localization somewhere else.
Yes, we are thinking along the same lines. We are looking into reworking the C# code to use translatable format strings such as nearly {0} and a half million which in French might be près de {0} millions et demi.
 
@VerticalBlank Hey dude, I recently have ((EDDI entered supercruise)) kicks me into witch space under {TXT:Environment}. It's very random when it happens but usually it happens as I engage supercruise when launching from planet, or engaging supercruise after undock. I caught it in the first seconds of this vid. Can you take a look please? And see what else you need from me to ID? Cheers.

Source: https://youtu.be/CYkWl830aHQ
Found a found where the hyperspace flag in status.json can temporarily flip to true when when entering or exiting supercruise (so an FDev quirk). I've implemented a simple fix for the next release.
 
Found a found where the hyperspace flag in status.json can temporarily flip to true when when entering or exiting supercruise (so an FDev quirk). I've implemented a simple fix for the next release.
Thank you sir.
Hello @bronney, there is a second variable for the Supercruise
Maybe you can use it additionally.
  • {BOOL:Status supercruise} a boolean value indicating whether the ship is currently in supercruise
This is good to know but it doesn't apply to my particular case. I am trying to detect where you are and stop you from saying certain things :) but thanks.
 
Top Bottom