Skip to content

Latest commit

 

History

History
551 lines (397 loc) · 22.3 KB

2020-11-05.md

File metadata and controls

551 lines (397 loc) · 22.3 KB

< 2020-11-05 >

2,787,652 events, 1,429,678 push events, 2,231,423 commit messages, 167,975,208 characters

Thursday 2020-11-05 05:12:07 by frick-nedrickson

Add 3D Labels for debuggery (for now!)

I was having trouble distinguishing the steps and ramps in the SlopeStepTest. I wasn't having too much of an issue telling the slopes apart, but I was really struggling with the steps. I want to do some more fine tuning of the Pawn's step-up/collision model but since they were essentially unlabeled I couldn't tell where the Pawn was failing.

Since they could change on the fly, I needed something that could be easily edited. So I've created a class that allows us to move and manipulate labels attached to 3D quads.

Putting these together was a proper pain, and I'm worried that using too many might lag the game (since they depend on the Viewport node). It seems like if you copy them, they don't update right away, and daring to load the Quad before the Viewport crashes everything, and I can't really size them or center the text as well as I would want to.

So I basically made a giant pain, but they do have legitimate uses, especially in debug. And, as we go on, this class will serve as the template for other 3D GUI elements (like health bars over enemies and friendly units).

Also, as part of the 3D GUI labels, I added a open source font.


Thursday 2020-11-05 05:28:21 by Nicholas Feinberg

Replace potions of stabbing with attraction

Potions of stabbing didn't quite hit the mark as a design. They weren't particularly popular with players, perhaps because their niche wasn't just narrow but extremely narrow.

So, let's try another idea. Potions of attraction cause the player to magically pull nearby monsters toward them while the duration lasts, a bit like Mass Lesser Beckoning. (Greater Beckoning?). It currently pulls 3 tiles per turn, though I could see 2 tiles or full LOS also being reasonable. The idea here is for melee characters to have something to help them with ranged enemies, though quite situationally!

I also considered making this pull items, as a sort of very silly apportation variant. Maybe it should?

Right now this doesn't wake up sleeping enemies, since it seemed fun to have it help with stabs, too. If that's too strong, we can make it more annoying (to enemies, waking them).


Thursday 2020-11-05 13:26:27 by Yutai Zhou

implementing q learning was easy enough, but holy shit hyperparam opt for eps and alpha is annoying... thankfully taxi v3 is harder than v2 so I am stopping below the 9.1 recommendation originally made for v2. also shoutout to the awesome eps decay visualizer https://observablehq.com/@katnoria/visualising-epsilon-decay'


Thursday 2020-11-05 14:41:35 by dave doolin

avl: initial work on balance and weight

The weight was initially computed during insert, but that's incorrect, it needs to account for the final configuration of the tree. I think this is correct now.

There is an overhead associated with computing the height on demand. I hesitate to memoize it as the tree will change height at any node over its lifespan.

avl: rotation spec clarifications

Mostly added a lot of context blocks around specific rotation specs to better describe which tree (node arrangement) is being tested. The existing rotation code seems to work correctly.

avl: start of balance specs

Balancing by retracing is the next step. This commit provides an initial stab at what the tests should look like. I have other things to do today, will fill remaining tests and implementation later.

It's raining out there, bona rain! In June!

avl: normalize node naming in spec

avl: more example specs

Along with adding more examples, there is a marker for working through the mechanics of the recursion on insert. It's pretty interesting, and not exactly how I though it would work. Could be as much as a day's work to go through how the stack works with respect to arguments passed into the recursing method, which is overloaded, btw, we're calling super, that's the interesting part.

avl: placeholder commit, need to refactor spec on master

The insertion for avl needs to move from node to tree, which really needs to leverage some refactoring of the specs, which should really be done in master. So committing here and hopefully the rebase won't collide with any of the code already on this branch.

avl: interim commit on rebalancing

This is a very small commit which is essentially interrupted work in progress, but I need to work on something else on a different branch.

avl: initial rebalancing for left chain

Seems to work correctly. I tried to implement using the code on Wikipedia as a template, but that code is far too messy for me to understand. So I'm working it out on my own on paper for special cases, and implementing by these cases.

avl: naming clean up for semantic congruence

Changed several method names in the rebalancing procedure to better reflect what the methods are doing.

Specifically, "rebalance" is now "retrace," and only traverses up the parent pointers, invoking the "balance" method each iteration. Much easier to understand. At least for me.

avl: simple ccw rotation for right heavy chain

avl: simple rotations working and spec'ed

The existing implementation of the simple rotations was deficient with respect to setting parent and child pointers correctly. This commit should have all that tuned up, along with a major overhaul of the avl node spec.

There is more overhauling of avl node spec to come.

avl: major start on writeup

Basic rotations are sketched out, along with some notes on implementation. This is a good start. I'm pleased.

avl: notes on retracing

avl: so-called double rotation implemented

The double rotation operation is very simple to implement by composing the two single rotations opposing each other. The key is using the correct rotation roots for each.

A few remarks on implementing retracing added.

avl: cleaned up naming convention for rotation

The names for the rotation methods are now very simple: rotate_[left|right[_[right|left]]. An alternative scheme would have been to stick with clockwise and counterclockwise, but the abbreviations "cw" and "ccw" aren't descriptive enough, and spelling it out makes for very long method names.

avl: "knee" rotation case from tree retracing

I think this is the commit which finishes the tree insertion which handles retracing and rebalancing correctly.

The main thing I've gotten out of this is that the references I've been using make it more difficult than it really is, primarily because they all use large functions which do too much.

There is also the notion of returning an updated root node from a rotation. This may be a useful notion, and worth investigating in more detail.

What's next is another round of refactoring the insertion and rebalancing, then deletions, which I believe will be far more difficult.

avl: major refactoring and cleanup, found bad bug

Major bug found while trying to build a large tree using in-order insertions. The bad thing is that it's nasty and will require clunky code to fix. The good thing is that it should be fixable within the node rotation methods. Hopefully.

avl: major suckage on rotations

Well this blows. I thought I had rotations nailed, but it turned out I did not. I found this out by inserting an in order sequence of keys, and seeing that the rotations really did not work at all.

The main issue is handling the change of parent for the rotation roots.

This commit solves it for a right chain induced by the in-order insertion. It turns out inserting the 6th node produces a classic "AVL" structure for a height-balanced tree. So I'm pretty stoked about that.

Four specs had to be xit'ed on this commit to pass. That sucks, but it does isolate where the problem is. It may be that I get the insertions working correctly, I can delete a bunch of the unit tests. They will almost surely have to be modified.

avl: more writeup on rotations

Specifically, retracing and implementation.

Also, introductory remarks on red-black tree.

avl: too many rotations on inorder insertion

The inorder insertions induce pathological rotations skewing the tree out of balance to left, that is, left heavy. Not sure why quite yet. Will require some major digging into the rebalancing logic.


Thursday 2020-11-05 14:45:24 by whitequark

Stuff all of the custom_repl infrastructure into a bonfire.

Custom REPLs are very nice. custom_repl is awful for several reasons:

  1. It required the user to watch out for a warning and then remember to switch to a different, inconsistent command, or else experience strange breakage.
  2. It lacked any way to provide arguments to the REPL runner, which in turn was justifying the behavior in (1).
  3. It involved some incredibly gross metaclass code.
  4. It was completely unnecessary. All of the metaclass stuff has been replaced by a pair of methods that's easier to understand and provides more useful functionality (REPL arguments).

I don't know what I was thinking.


Thursday 2020-11-05 17:53:00 by Marko Grdinić

"9:45am. I went to bed nearly at 2am and getting nearly 8h of sleep per day. But I am actually sleeping well so, that is 4h more of waking hours than usual. That is the Baldur's Gate effect.

Let me chill a bit and then I will start.

10:05am. Let me start.

Focus me.

10:15am. ...So I had some ideas yesterday, but now I am unsure of how concurrent compilation of packages if I make everything else lazy.

If I made everything else but the attention lazy then I have to think of how to deal with the attention mechanism.

3:40pm. Where did the last 5h go? I spent the morning ~1.5 hours deep in thought. Then I had breakfast for ~1.5 hours. Then I did the chores for another ~1.5. So it is roughly 5, I wasn't keeping exact track.

3:45pm. I am still thinking about it.

Just like yesterday I had waves of inspiration come onto me again.

I think this time, I've solved pretty much everything. Everything.

Not only do I know how to do the attention, I know how to optimally take care of the prepass as well.

One thing that gave me a lot of trouble is figuring out how to make use of the regular typechecker pipeline to do both the compilation for the prepass and the regular reactive response while the user types in editor.

This was a huge problem me that I tried talking myself into doing 90% right since I just could not see how to do 100%.

3:50pm. But now I see how I could do it 100% correctly. With my current ideas I can meet all my requirements.

4pm. Agh, screw semantic highlighting. I'll do everything 100% correctly except it. Doing it correctly would force me to merge tokenization and parsing, and I do not want that. The only thing that ever makes use of it is the editor anyway. Even if in theory it might end up being wrong, it won't affect the correctness of compilation.

4:05pm. I've cooled down a bit.

4:10pm. I do not feel like really talking about right now, as I am still thinking about it.

But the basic realization that I've come to is that laziness is not enough.

What I will do is turn the various servers into streams themselves. Rather than them taking in streams and outputting the results of processing them, they will also return their won update function. I am going to do this everywhere, and this is what will make things work.

4:20pm. Let me chill for a while. In order to do what I have in mind, I am going to have to break everything once again. In particular, in order to turn them into streams, I am going to have to redesign all the servers so they use exclusively immutable data structures.

For the past few months I've been modeling the problem as a chain of communicating servers, so I thought I would be able to get away with using mutable structures, but I was wrong.

4:25pm. Agh...seriously, I am going to have to redesign the parser so that the tokenizer are updated immutably.

No, I won't be lazy and leave it as they are. I am going to do it all properly from the beginning.

4:45pm. Now I am thinking about incremental compilation of join points again.

I am going over everything with the latest insights in mind.

4:50pm. I've been reading the review of the new Zen 3. AMD is on top again, and its processors at the top end have 12-16 cores. My own CPU has only 4, so I am not too interested in concurrency from a performance perspective, but in the future that will be a consideration.

4:55pm. Forget concurrent partial evaluation for a while. Yes, it will be quite challenging. But if I do all the other segments properly, that will leave me mental space to do it as it should be done.

I do not need to bust my head on this right now. I'll be able to take care of it once the time comes assuming I can survive this part.

The stream server ideas should allow me to get through.

5pm. Damn it, this is going to be the longest and the hardest redesign yet. I am going to have to break everything starting with the parser.

let tokenizer req =
    let lines : LineToken [] ResizeArray = ResizeArray([[||]])
    let mutable errors_tokenization = [||]
    let mutable blocks : Block list = []

All this mutable shit? It will have to go away. Only then will I be able to restate the servers as immutable streams.

It is worth it. The ideas I have in mind are particularly powerful.

Even if it takes me a full month, if I do it like I have in mind currently, things will come out right. I really will be able to put the servers behind me.

type SpiralToken =
    | TokVar of string * SemanticTokenLegend ref
    | TokSymbol of string * SemanticTokenLegend ref
    | TokSymbolPaired of string * SemanticTokenLegend ref
    | TokOperator of string * SemanticTokenLegend ref
    | TokUnaryOperator of string * SemanticTokenLegend ref

Damn it, it is actually in the tokenizer that I have to break this.

type SpiralToken =
    | TokVar of string * VSCPos
    | TokSymbol of string * VSCPos
    | TokSymbolPaired of string * VSCPos
    | TokOperator of string * VSCPos
    | TokUnaryOperator of string * VSCPos

I've done it.

let token_groups = function
    | TokUnaryOperator(_,r) | TokOperator(_,r) | TokVar(_,r) | TokSymbol(_,r) | TokSymbolPaired(_,r) -> !r

I have red everywhere, but let me deal with the tokenizer today. I'll leave the parser and the rest tomorrow.

type SpiralToken =
    | TokVar of string * VSCPos * SemanticTokenLegend
    | TokSymbol of string * VSCPos * SemanticTokenLegend
    | TokSymbolPaired of string * VSCPos * SemanticTokenLegend
    | TokOperator of string * VSCPos * SemanticTokenLegend
    | TokUnaryOperator of string * VSCPos * SemanticTokenLegend

Actually, let me do it like this. I meant to replace the tokens, but now I see that I do not have anything good to replace them with. So I can only update their meta info.

5:15pm.

let var (s: Tokenizer) =
    let from = s.from
    let ok x = ({from=from; nearTo=s.from}, x)
    let body x =
        if skip ':' s then TokSymbolPaired(x,ref SemanticTokenLegend.symbol) |> ok

Aghh...this is the next red. But I can't fix it because I do not the token line and col info.

5:20pm. No, I am on the wrong track here.

type SpiralToken =
    | TokVar of string * SemanticTokenLegend
    | TokSymbol of string * SemanticTokenLegend
    | TokSymbolPaired of string * SemanticTokenLegend
    | TokOperator of string * SemanticTokenLegend
    | TokUnaryOperator of string * SemanticTokenLegend
let tokenize text =
    let ar = ResizeArray()
    let er = match (spaces >>. many_iter ar.Add token .>> (eol <|> tab)) {from=0; text=text} with Ok() -> [] | Error er -> er
    Array.collect List.toArray (ar.ToArray()), er

Instead of using an array here, since I will be updating it during parsing, let me move to a persistent vector.

No wait, I am using a list here...

let tokenize text =
    let ar = ResizeArray()
    let er = match (spaces >>. many_iter ar.Add token .>> (eol <|> tab)) {from=0; text=text} with Ok() -> [] | Error er -> er
    Seq.concat ar |> PersistentVector.ofSeq, er

No wait, why am I doing this? I should just be adding the whole damn range.

let tokenize text =
    let mutable ar = PersistentVector.empty
    let er = match (spaces >>. many_iter (List.iter (fun x -> ar <- PersistentVector.conj x ar)) token .>> (eol <|> tab)) {from=0; text=text} with Ok() -> [] | Error er -> er
    ar, er

Let me get right to the meat at once! This is the way to do this.

let replace (lines : _ [] ResizeArray) (errors : _ []) (edit : SpiEdit) =
    let toks, ers = Array.map tokenize edit.lines |> Array.unzip
    lines.RemoveRange(edit.from,edit.nearTo-edit.from)
    lines.InsertRange(edit.from,toks)

    let errors = errors |> Array.filter (fun ((a : VSCPos,_),_) -> (edit.from <= a.line && a.line < edit.nearTo) = false)
    Array.append errors (process_errors edit.from ers)

Now here is the next red.

5:40pm.

let replace (lines : _ PersistentVector PersistentVector) (errors : _ list) (edit : SpiEdit) =
    let toks, ers = Array.map tokenize edit.lines |> Array.unzip
    lines.RemoveRange(edit.from,edit.nearTo-edit.from)
    lines.InsertRange(edit.from,toks)

    let errors = errors |> List.filter (fun ((a : VSCPos,_),_) -> (edit.from <= a.line && a.line < edit.nearTo) = false)
    List.append errors (process_errors edit.from ers)

I really do not feel like it. Let me make the persistent vector replace.

5:55pm.

module PersistentVector =
    /// Replace the specified range in a vector with the sequence.
    let replace from near_to seq vec =
        if from <= near_to = false then raise (ArgumentException())
        if from < 0 || PersistentVector.length vec < near_to then raise (ArgumentOutOfRangeException())
        let rec rest s =
            if from < PersistentVector.length s then
                PersistentVector.unconj s |> fst |> rest
            else
                Seq.fold (fun s x -> PersistentVector.conj x s) s seq
        let rec init s =
            if near_to < PersistentVector.length s then
                let s',x = PersistentVector.unconj s
                PersistentVector.conj x (init s')
            else
                rest s
        init vec

I am going to have to test this function out. Did I get the comparisons right?

6:25pm. Done with lunch. I did the test before I left.

open System
open FSharpx.Collections
module PersistentVector =
    /// Replace the specified range in a vector with the sequence.
    let replace from near_to seq vec =
        if from <= near_to = false then raise (ArgumentException("`from` must be less or equal to `near_to`."))
        if from < 0 then raise (ArgumentException("`from` must not be negative."))
        if PersistentVector.length vec < near_to then raise (ArgumentException("`near_to` must not be beyond the length of the vector."))
        let rec rest s =
            if from < PersistentVector.length s then
                PersistentVector.unconj s |> fst |> rest
            else
                Seq.fold (fun s x -> PersistentVector.conj x s) s seq
        let rec init s =
            if near_to < PersistentVector.length s then
                let s',x = PersistentVector.unconj s
                PersistentVector.conj x (init s')
            else
                rest s
        init vec

let x = [1..5] |> PersistentVector.ofSeq
printfn "%A" (PersistentVector.replace 1 0 [34;45;77] x |> Seq.toArray)

Cleaned this up a bit and played around with it. Everything works. Let me plug it in and I will call it a day.

6:35pm.

let replace (lines : _ PersistentVector PersistentVector) (errors : _ list) (edit : SpiEdit) =
    let toks, ers = List.map tokenize edit.lines |> List.unzip
    let lines = PersistentVector.replace edit.from edit.nearTo toks lines
    let errors = errors |> List.filter (fun ((a : VSCPos,_),_) -> (edit.from <= a.line && a.line < edit.nearTo) = false)
    let errors = List.append errors (process_errors edit.from ers)
    lines, errors

I've decided to in SpiEdit to just change the lines from an array to a list...

No that would be too inefficient.

let replace (lines : _ PersistentVector PersistentVector) (errors : _ list) (edit : SpiEdit) =
    let toks, ers = Array.map tokenize edit.lines |> Array.unzip
    let lines = PersistentVector.replace edit.from edit.nearTo toks lines
    let errors = errors |> List.filter (fun ((a : VSCPos,_),_) -> (edit.from <= a.line && a.line < edit.nearTo) = false)
    let errors = List.append errors (process_errors edit.from (Array.toList ers))
    lines, errors

Let me do it like this then.

6:40pm. Yeah, this is good. I can finally call it a day here. Tomorrow, I will redo the parser. It won't be too hard. I'll just return a array of positions to update in the original token array. I should have gone with that from the start.

6:50pm. Let me finally close. Time for BG. I've been really enjoying myself for the past week, and that is not going to stop here. Today is done, but I think that with these ideas, I will have a clear path ahead of me for finishing the compilation pipeline."


Thursday 2020-11-05 18:17:33 by İ. Göktuğ Kayaalp

dotfiles/config/pycodestyle (ignore): add E401 for multiple imports on one line

Fuck your rigid existence.


< 2020-11-05 >