Leben – Day 37

Continuando com o desenvolvimento

fiquei vários dias olhando pra tela sem vontade de escrever nada, fazer o desenho do mapa, estava me deixando maluco, o perlin não estava funcionando como eu queria, até que joguei Swag and Sorcery, acabei me lembrando de como eu gosto de 2D side-scrolling

então vou me forçar simplificar mais o Leben pra algum dia terminar ele :sweat_smile:

O que fiz de novo?

estou começando desenhar alguns tilesets, havia falado que ia usar Krita, mas acabei preferindo aseprite, comprei no steam mesmo, se não me engano usei o grátis e me apaixonei.

nada muito completo, apenas o background e o chão, vou fazer o render do céu de outra forma pra facilitar transição de dia/noite, mas por enquanto, é o suficiente.

ainda tem muito trabalho, mas eu estou gostando:

estive sincronizando com a cloud os assets e os códigos que estive fazendo.

vou montar agora algumas construções e começar “brincar” com o jogo

Leben – Day 36

Voltando ao projeto

Estive trabalhando no meu “joguinho”

ainda há muito trabalho, aproveitei minhas férias pra descansar e agora que estou um pouco menos estressado e consegui um cadin de energia

acabei voltando pro Leben.

O que fiz de novo?

acabei implementando o backbone de estruturas no mapa, algo simples onde toda entidade do mundo tenha algum tipo de input e output, por enquanto pensei pequeno com um poço, como havia citado no Leben – 25-2, eu estou implementando tudo via BDD, quero continuar neste formato

ainda não tem tantos detalhes, primeiro estou criando um poço, então indicando que há um ator interagindo com o poço e forço a conclusão da tarefa do ator, então uma referência de “balde de água” é adicionada no inventário do poço.
mas está funcional

eu gosto muito de usar o BDDFy

somente por isso:

futuramente caso necessário eu terei uma comportamento esperado em vários pontos do jogo, evitando que eu quebre :sweat_smile: alguma coisa.

Falando em quebrar…

Estava todo feliz pensando que iria usar a configuração de noise do mapa que havia feito e começar implementar as entidades no mapa.

O resultado é que agora todos os pontos que eu separei nos biomas (desert, mountain, deepforest, forest, beach, nearwater, deepSea, nearwater, beach) estavam quebrados, a única mudança foi que troquei de PC, provávelmente.

mas não tem problema, eu já queria criar um sistema separado pra gerar mapas e poder “pintar” um mapa.
na minha cabeça irei usar a técnica de geração de mapa procedural para fazer maior parte do trabalho, indicando biomas, setando onde é possível ter determinado tipo de recurso e tal, depois dele gerar o mapa eu dô os “tapas” para fazer a finalização.

Em breve mostro uma ferramenta que acabei dazendo para visualizar o mapa de maneira rápida.

ate mais 😁

Async não é paralelismo e não… Async não é mesma coisa que sync.- Parte 1

Intro

Calma, leia até o final :sweat_smile: juro que fará sentido o título, bom… pra mim fez…..

Não sei o quanto vocês conhecem de Async e a famosa maquina de estado no contexto de C#

particularmente eu já tive vários problemas e cheguei odiar porque sempre tive problema e sempre culpei o compilador….

bom, depois de criar vergonha na cara e meter a fuça em como as coisas funcionam aprendi um pouquinho, o suficiente pra não cair em algumas armadilhas.

tenho alguns Links de referência como meu book of reference, tudo que achei útil quando tive problemas eu acabei adicionando nele pra estudar aos poucos.

A importância de saber sobre async e sua máquina de estado.

Recentemente fui convidado pra fazer um Code Review em um código, particularmente devido o projeto que toco é complicado fazer code-review e quando acontece é algo bem pontual onde preciso separar na agenda.

e encontrei alguns itens que me chamaram atenção, foi removido paralelismo, remoção de async e foi adicionado um tal de GC.Collect().

Não me entenda mal, mas se você faz isso, talvez seja importante ler o livro: Pro .Net Memory Management: For Better Code, Performance, and Scalability by Kokosa ele dá um background ótimo sobre com funciona GC e convenhamos… A linguagem já tem mais de 20 anos, com engenheiros super competentes que pensaram durante anos da forma mais eficiênte deste processo, vamos ter humildade :sweat_smile:, existem pouquíssimos casos que você realmente precisa fazer isso, pelo que me recordo em debugging ou fazendo benchmark, com excessão desses pontos, você vai apenas piorar a heurística e se ele está sendo o problema… novamente, leia o livro do Kokosa e comece usar o Stack.

bom pulando pra parte que eu queria falar :sleeping:

Async at last!

não sei se vocês tem o costume de ler o que o código vai gerar ao escrever o código, não é sempre que você precisa disso, na verdade você ignora essa parte porque são poucos cenários que você precisará entender o que acontece por trás do código gerado ou IL pra determinar uma nova forma de escrever código

um código simples :

using System;
using System.Threading.Tasks;
public class TestSubject {
    public void DoSomething() {
    }
    public async Task DoSomethingAsync() {
    }
}

e o compilador irá traduzir isso para:

using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
public class TestSubject
{
    [CompilerGenerated]
    private sealed class <DoSomethingAsync>d__1 : IAsyncStateMachine
    {
        public int <>1__state;

        public AsyncTaskMethodBuilder <>t__builder;

        public TestSubject <>4__this;

        private void MoveNext()
        {
            int num = <>1__state;
            try
            {
            }
            catch (Exception exception)
            {
                <>1__state = -2;
                <>t__builder.SetException(exception);
                return;
            }
            <>1__state = -2;
            <>t__builder.SetResult();
        }

        void IAsyncStateMachine.MoveNext()
        {
            //ILSpy generated this explicit interface implementation from .override directive in MoveNext
            this.MoveNext();
        }

        [DebuggerHidden]
        private void SetStateMachine(IAsyncStateMachine stateMachine)
        {
        }

        void IAsyncStateMachine.SetStateMachine(IAsyncStateMachine stateMachine)
        {
            //ILSpy generated this explicit interface implementation from .override directive in SetStateMachine
            this.SetStateMachine(stateMachine);
        }
    }

    public void DoSomething()
    {
    }

    [AsyncStateMachine(typeof(<DoSomethingAsync>d__1))]
    [DebuggerStepThrough]
    public Task DoSomethingAsync()
    {
        <DoSomethingAsync>d__1 stateMachine = new <DoSomethingAsync>d__1();
        stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
        stateMachine.<>4__this = this;
        stateMachine.<>1__state = -1;
        stateMachine.<>t__builder.Start(ref stateMachine);
        return stateMachine.<>t__builder.Task;
    }
}

é possível perceber que toda vez que você deixa uma assinatura de “async” no método ele gera uma máquina de estado, é até um dos motivos que eu tento não criar nested async, afinal invariávelmente será alocado em memória, então em cenários críticos eu penso bem… Continuando….

Precisava dar esse contexto caso alguém não tivesse ainda a oportunidade de saber o que acontece por baixo dos panos, então foi um resumo pra continuar

em minha memória do código de algum tempo atrás era o seguinte:

public async Task SomeMainTask(){

    var id = 0;
    var processoUm = Task.Run(()=>{ id = DoSomething();});
    var processoDois = DoOtherThing();

    await processoUm;

    (... outros processos sincronos e assíncronos)

    var processoDois = DoOtherThing(id);

    Task.WaitAll(
        processoDois,
        (...)
    );
}

public async Task<id> DoSomething(){
    (... alguma chamada pro banco)
    ///código apenas pra contexto
    return Task.FromResult(id);

}

e quando eu li o código:

public void  SomeMainTask(){

    var id = 0;
    var processoUm = DoSomething();
    var processoDois = DoOtherThing();

    (... outros processos sincronos e assíncronos)

    var processoDois = DoOtherThing(id);    
}

public id DoSomething(){
    (... alguma chamada pro banco)
    ///código apenas pra contexto
    return id;

}

eu fiquei meio intrigado, eu queria entender a motivação… particularmente eu faço tudo sincrono mesmo e eventualmente quando estou fazendo meu próprio code-review eu penso se faz ou não sentido colocar um async.

quando questionei, a resposta foi que async e sincrono seriam as mesmas coisas no final das contas ou seja :

isso

var id = DoSomething();

public int DoSomething(){
    (...chamada pro banco)
    return someid;
}

é igual isso:

var id = await DoSomething();

public Task<int> DoSomething(){
    (...chamada pro banco)
    using(var someconn = new SqlConnection(connectionstring)){
        return someconn.FirstOrDefaultAsync<int>("select 1");   
    }   
}

será?

tentei explicar que não era… afinal na própria documentação da microsoft (inclusive… que maravilha de doc ) explica exatamente o que eu disse. Apesar do meu esforço de mostrar que ele vai bloquear uma thread até ter resposta…

achei mais simples criar um código muito simples pra apresentar o problema:

Apenas pra dar contexto, eu sou um usuário assíduo do LinqPad, logo quando estiver escrito “someText”.Dump(); no código abaixo, entenda como Console.WriteLine(“sometext”);

async System.Threading.Tasks.Task Main()
{
    int nWorkers; 
    int nCompletions; 

    ///aqui estou forçando que apenas exista uma única Thread no meu sistema pra apresentar um cenário que dá pra observar o comportamento
    ThreadPool.SetMinThreads(1, 1).Dump();
    ThreadPool.SetMaxThreads(1, 1).Dump();

    /// apenas me assegurando que é apenas uma thread..... vai que... 
    ThreadPool.GetMaxThreads(out nWorkers, out nCompletions);
        "workers: {nWorkers}".Dump();"nCompletions: {nWorkers}".Dump();

    ///estou deixando uma thread executando sem parar, com um intervalo de 2 segundos, como se fosse um heart-beat.
    System.Threading.Tasks.Task.Run(async ()=>{
                while(true){
                    "Heartbeat".Dump();
                     await System.Threading.Tasks.Task.Delay(2000);
                }
    });


    for(var i = 0; i<=4; i++){
        /// aqui estou criando algumas Tasks assíncronas para executar alguma ação representando um insert no banco.
        await System.Threading.Tasks.Task.Run(async ()=>{
                await System.Threading.Tasks.Task.Delay(5000);"{Thread.CurrentThread.ManagedThreadId}-{DateTime.Now.ToString("HH:MM:ss")}".Dump();
        });
    }

    "-----------------------Async Done-----------------------".Dump();
    for(var i = 0; i<=4; i++){
        /// aqui estou criando as mesmas Tasks mas desta vez estou forçando a execução síncrona para executar a mesma ação no banco.
            System.Threading.Tasks.Task.Run(()=>{
                System.Threading.Tasks.Task.Delay(5000).Wait();
                $"{i} - {Thread.CurrentThread.ManagedThreadId}-{DateTime.Now.ToString("HH:MM:ss")}".Dump();
            });
    }
}

O que você acha que aconteceu?

eu tive que gravar um vídeo…:sweat_smile:

como esperado a thread que está resposável pelo heart-beat continua a execução, é liberada e então a task Async de “persistência no banco” consegue trabalhar, termina e assim o fluxo continua..

agora quando chega no síncrono… nenhum funciona, infelizmente não consegui compreender o motivo, a thread acabou ficando em lock no Task.Delay, mas isso eu não vou tentar entender hoje.

mas espero que esse post traga a luz para alguém que assim como eu também já sofreu com async.

p.s. eu sei que acontecer um thread starvation em alguns cenários é difícil dependendo do seu cenário, mas no cenário que eu verifiquei isso pode ser a diferênça entre aumentar a capacidade do servidor pra dar vazão no processamento, sendo que o custo pode ser evitado com um uso inteligênte dos recursos.

p.s² Pegadinha! eu não falei sobre paralelismo ainda :laughing:, mas o que eu falaria não escapa da gloriosa doc da mãecrosoft:

e depois continuo :p

Esteja Curioso!

Só pra manter o Blog ativo.

Bom, eu gosto de escrever pro meu blog,

Estou sem desenvolver no Leben, dá um pouco de preguiça e existe muitos projetos que quero fazer e ainda preciso me distrair pra manter a sanidade.

estive jogando Raft, mindustry, this war of mine e autonauts.

Mas principalmente estou dando suporte á minha ferramenta para gerenciar mods pro jogo Kenshi

Conforme ela está crescendo percebo como é legal ajudar outras pessoas gerenciar seus mods e melhorar a experiência de um jogo tão legal, por isso vou continuar melhorando ela.

bom era isso, só queria postar algo mesmo

:p

Hoje não tem update do Leben :x

Também tenho outros projetos.

hoje recebi um comentário no meu youtube de um mod manager que eu havia feito, era uma pessoa com dificuldade, então enquanto estava respondendo ele de como fazer funcionar e percebi que havia outro vídeo explicando como minha ferramenta funcionava, fiquei bem feliz e orgulhoso.

Então parei um pouco pra dar um update no Leben, só pre adicionar alguns recursos no mod manager.

ah! o manager é pro jogo Kenshi, por enquanto parei um pouco de jogar, mas é muito bom, um dos jogos que mais joguei no Steam.

Eu sei deveria ter postado…

Mas sabemos Como é os feriados :p

Lado positivo quase zerei o xcom 2.

Conheci um garoto de 12 anos, possui um projeto de browser game, vou ajuda-lo
É pelo menos algo mais simples que o Leben :p

Também joguei this war of mine e rust.

Sendo o primeiro uma atmosfera bem pesada.
Fiquei meio deprimido ao ver um dos meus “amigos” morrer.

Hoje pela noite saberei mais sobre o projeto e vou participar também.

Até 🙂

Just the usual

Ah! finalmente internet normal, ainda ruim, porém é pelo que pago, então é o “justo”.

 

mas não tô afim de trabalhar no Leben, me empolguei com gnomoria e vou ficar alguns dias jogando isso,  por enquanto.

 

Ah! me peguei olhando blogs de algumas pessoas, existem bons escritores de poemas e artigos por aqui, fico feliz por isso, apesar de nunca ter procurado esse tipo de conteúdo, hoje me parece um ótimo passatempo aside podcast 😀

ainda vou fazer um link á um blog que me fez pensar, por algumas horas, na verdade, me pego pensando nele ainda.

 

só tenho que me organizar para escrever, sobre o assunto, não quero fazer um link com uma péssima apresentação, sendo que o conteúdo foi tão… singular 😛

era isso

Bye

Internet lenta…

Na minha casa estou com uma internet que eu pago caro e é um péssimo serviço pra não falar que é uma merda 😡 , enfim é tenso, monopólio da vivo aqui em minha região e outras operadoras não aparecem (triste pra mim)

mas enfim, já que a internet não ajuda e estou cansado demais pra ir ao Leben, estou aqui ouvindo a cantora que sou fã desde 2003 ou 2004, é a pessoa que nasceu no mesmo dia que minha mãe, muita coincidência, é ela, Utada Hikaru, que está em Hiato, mas ainda tenho um grande amor por ela S2 😛

pelo menos existem outros cantores que chegam perto do estilo de música que eu gosto, como a Yui Yoshioka, IU e Miwa.

Enquanto minha internet está ruim não vou poder ver algumas coisas no meu pc, e enquanto estiver com cansaço será difícil mexer no Leben, pelo menos vem ai o feriado, vou usar algum dia pra compensar.

 

vou jogar Gnomoria, acho que eu disse que tinha desistido dele, mas é o único jogo mais próximo (hoje) do que eu gostaria de jogar (chuckle)

 

bom é isso

(bye)

Entrevista as cegas

Vou lhes contar um projeto que tenho engavetado.

Eu nunca fui do tipo de conversar, nem conversar direito eu consigo e falar em público sempre foi um problema, apesar deste último eu já ter aprendido como manejar

O projeto consiste em algumas perguntas simples como nome, idade e profissão, estado civil.

E outras pra saber das experiências fama pessoa

Ainda não montei o questionário, pois nunca foi uma prioridade pra mim.

Neste projeto você tem que entrevistar
Alguém que você não conhece e gravar, preferencialmente por áudio, lembrando que a pessoa deve ser informada.

Bom, este é um projeto que eu tenho em mente há aproximadamente 8 anos

Um dia faço um protótipo.

Bom era isso 😉

Coisas do dia a dia

Como qualquer dia normal de segunda a sexta, estava eu e meus amigos do trabalho indo ao almoço.

Eu e um outro colega, anda um pouco mais rápido (como bons paulistas)
Até que percebemos que os outros já tinham saido de nosso campo de visão, então paramos para esperar-los

Foi então que spawnou 3 NPCs falando uma língua que parecia ser português, estava impossível entender o que eles falavam, porém pude compreender que precisavam de um auxilio para ir do ponto A ao ponto B o único problema é que eu não entendia de jeito algum o ponto B e meu colega do lado também não entendeu uma palavra do que estes ilustres turistas estavam falando.

Por fim eles foram embora e agradeceram foi engraçado na hora, um dos meus amigos chegou sorrindo e falou:

– o que ocorreu ai ?
– nada, o cara estava querendo informação, mas não tinha como compreende lo
– UE mas porque você não conversou em inglês com ele?

– ahh, porque eu já havia compreendido que ele precisava de informação, eu só não tive capacidade de saber onde era o lugar que ele queria ir.

E era isso, precisava compartilhar tal causo 😀

Tchau, acho que hoje eu pego o Leben pra programar