Skip to content

Latest commit

 

History

History
786 lines (569 loc) · 36.4 KB

2020-08-10.md

File metadata and controls

786 lines (569 loc) · 36.4 KB

< 2020-08-10 >

2,414,071 events, 1,204,040 push events, 1,909,660 commit messages, 142,327,333 characters

Monday 2020-08-10 01:56:42 by frick-nedrickson

Redo the Rothenburg house

So I was trying to work with getting the Rothenburg house textured (yes, actually textured, not just a flat color!) but I noticed that it wasn't working. The textures were only showing up when I made the material world triplanar. I remember having a similar issue with the stupid cubes that I made for the wheat.

Turns out I didn't create a UV Map for the models, which, as I understand it, roughly corresponds to the concept of 'Texture Coordinates' that I am MUCH more familiar with. Basically, since I didn't have any texture coordinates, we weren't getting any texture.

So, I added UV coordinates to each of the house's many components. To make my life easier, I also now export all the meshes in a .dae file, rather than exporting the models individually. I then duplicate this to create the RothenburgHut scene.

One advantage of the .dae method - it recreates all the materials that I made in Blender here. Normally I'd consider that an inconvenience and unecessary clutter BUT in this instance, I was going to do that anyway!


Monday 2020-08-10 02:08:30 by PhoenixBladez

1.4.0.3 edits

  • Fixed the Bladewings recipe not requiring Quicksilver Shards
  • The Stone Helmet now has an option to negate the increased fall damage effect (hold UP)
  • fixed a grammatical error in the Adventurer's Scared Vine Quest
  • Aurora music no longer overrides Blood Moon
  • Party Girl now sells the appropriate Music Box
  • Fixed the Starplate Voyager teleporting/staying alive after the player dies in its Phase 2
  • Added the Glowflower, which drops from the pink flowers in the Briar
  • Grove Casters can now be targeted by minions/homing
  • Renamed Freeman Body and Leg items
  • Deadeye Marksman health now scales properly in Expert Mode
  • Orbitite Mini Meteor summon now goes through walls
  • Fixed Elderbark Table being too short
  • Improved the tiling of all Fluorescent Blocks
  • Fixed a couple of Spirit Bosses not dropping Glyphs, or the right amount of them
  • Made Starplate Voyager's death sound more audible
  • Made Occultist spawn slightly less frequently

Monday 2020-08-10 04:16:45 by Doug Wozniak

added some features to the LibrarySim app. Started playing with the GUI. I'll see if I can finish it in the morning. Overall I think we've hit everything except the GUI. Hell yeah!


Monday 2020-08-10 05:33:16 by ma

Start to write script to "mount" roam directories

(sorry for poor syntax, I'm tired so I'll be verbose and probably redundant)

Doom Emacs's Org-roam graph generation requires a specific directory to be used for graph generation. Since there's a lot of info that can be represented using Org-roam graph capabilities, very often I want to generate different graphs for different topics. However, this is not quite intuitive using Org-roam's design.

First you have to define a "roam directory" or something like that so Org-roam can use that directory to place the roam files and then generate the graph. At least that's how I understand it. Anyway, every time I want to create a graph I have to place the files in this "roam directory" and only then generate the graph. If I want to do another completely different without losing the work of other projects I have to back up whatever it was before in that "roam directory", then create the files in this directory and finally generate the graph.

The ~/bin/roam Bash scripts takes care of that process. Maybe in the future Org-roam will solve this issue but for now, I'll be happy to hack it this way.

The "roam directory" that I use by default (defined in the ~/.doom.d/config.el") is ~/org/auxRoam"; anything I want to generate a graph from, has to be placed inside this auxRoam directory, create the graph and then backup this roam files in their correspondent place.

Actually, the first solution I tried was to manually change the "org-roam-directory" in the Doom Emacs configuration itself, but it quickly became an annoyance since I had to change it every time I wanted to graph different ideas. Hence, this script.


Monday 2020-08-10 10:24:04 by Marko Grdinić

"9:20am. I went to bed very late so I am very groggy right now.

The recent language design issues leave me stressed. Actually, I need constraints in order to deal with record apply properly, just not dependent ones.

The fact that need to iterate in order for all contraints to be propagated is making my brain churn. Can I do something efficient to gather all the constraints in one go? I have no idea.

9:30am. It is making me stressed. There is no easy way to validate record apply. Unless it is obviously wrong, I'll have to let them pass during metavariable validation.

But leaving out the constraints, I am quite close to being done.

9:35am. I have to admit, one of the reasons I am going to bed so late is because I am hooked on a shitty Chinese webnovel. Devil's Evolution Catalogue's premise where the MC reincarnates as a devil in hell is just too much up my alley. The shitty village arc has really been testing my patience though.

9:40am. I think I really will just leave constraints out of the language. The partial evaluator can take care of it. I just have so many other more important things to think aobut.

...Ok, as the first task of the day, let me change the parser for term foralls. I am going to add kind wildcard to the mix.

Before I start let chill.

10:25am. Let me finally finish this arc, just two more chapters and then I will do some programming.

10:45am. Ok, enough. Let me do some programming.

type RawKindExpr =
    | RawKindStar
    | RawKindFun of RawKindExpr * RawKindExpr

First of all, let me add the RawKindWildcard here.

type RawKindExpr =
    | RawKindWildcard

I'll just assume these are regular one stars in type definitions, but in term foralls, I will have them be kind metavars.

inl f forall (x : * -> *)

I do not want to force kind annotations everywhere.

let rec typevar = function
    | RawKindWildcard | RawKindStar -> KindStar
    | RawKindFun(a,b) -> KindFun(typevar a, typevar b)

This is actually the only green spot.

I will have to make an alternative for RawForall.

One thing that is stressing me out is how will I deal with kind in the partial evaluator. Agh...I'll deal with that when it comes to it.

        | RawForall(r,(_,(name,k)),b) ->
            let rec typevar = function
                | RawKindWildcard -> fresh_kind()
                | RawKindStar -> KindStar
                | RawKindFun(a,b) -> KindFun(typevar a, typevar b)
            let k = typevar k
            let i,v = fresh_var'' k
            forall_scopes.Add(name,i)
            let body = fresh_var()
            unify r s (TyForall((name,k),body))
            term {env with ty = Map.add name v env.ty} body b

Let me go with this.

Now even though I have this here, I will have to pull this out and put it into the let statements.

11am. Hmmmmm...

I have an idea.

I've been obsessed with doing the maximum amount of let generalization possible.

inl f x =
    inl y = ...
    inl g z = y + z
    ...
    g y x

...There might be an alternative to doing no local let generalization.

Right now I am obsessed with generalizing as soon as g has finished processing.

But suppose I generalize at the end?

Suppose y is still a metavariable at the end?

...No it would not work.

The only way I can unambiguously let generalize at the end is when all the top level metavar substitutions are done, but a function still has uninferred arguments.

11:10am. You know what, let me ask about let generalization on the PL sub. Maybe somebody will have some insight there.

let f x =
    let y = failwith ""
    let g z = y + z
    g (y : int) x

I'll also ask about the constraints.

11:15am.

///

let f x =
    let y = failwith ""
    let g z = y + z
    g (y : int) x

I though let generalization would be easy, but it turns out that substituting the leftover metavariables for foralls in the statement body only makes sense if the metavariables do not have paths connecting them to other metavariables outside their scope.

Here

///

...This is not a good example.

Of course if y gets inferred as int, then z should be int as well.

Let me try this instead.

let f x =
    let g y = y
    g 1

11:20am. Great, now I can figure out how to pose the question.

let f x =
    let y = failwith ""
    let g z = y + z
    g (y : int) x

11:55am.

///

I though let generalization would be easy, but it turns out that substituting the leftover metavariables for foralls in the statement body only makes sense if the metavariables do not have paths connecting them to other metavariables outside their scope.

let f x =
    let y = failwith ""
    let g z = y + z
    g (y : int)

Here, when type inferencer finishes with g it would have a type like 'a -> 'a. But I cannot generalize this to forall a. a -> a because y might turn out to have a type like int down the road. So the correct thing to do this is to just let the inference proceed, and g will have the int -> int type at the end.

let f x =
    let g z = z + z
    g (x : int)

Here, g would get inferred as 'a -> 'a once again, but since 'a does not have any paths outside its scope, I should be able to generalize it as a function of forall a. a -> a.

The issue for me here is that I do not want go all over the metavariable array doing an in depth search if any metavariable outside the scope of g connects to it. It does not really feel like the right choice of action here. It is just seems too inexpensive and inelegant as a solution.

In my own language it is possible to simply do...

let f x =
    let g forall a. (z : a) = z + z
    g (x : int)

...and this would force it to generalize. This kind of insight is not what I am looking for though. What I want is to automate cheaply as much as possible.

Is there any way to resolve the inherent tension between wanting to generalize as soon as possible and leaving it for after the inference is done? Are there any insights that can be used to make this easier?

///

Let me go with this.

12pm. https://www.reddit.com/r/ProgrammingLanguages/comments/i71zyx/how_to_do_generalization_of_local_let_statements/

I posted it on the PL sub. But I do not have much hope on getting any good replies.

The idea just now of leaving let generalization for the last is a good one though. This would be pretty decent actually. It is good enough.

12:10pm. I am thinking.

Even though just started an hour ago, let me have breakfast here. No point in starting anything else right now.

All this really is stressful. From a distance something like let generalization seems easier than it is. Once you get closer it is only then that you see all the details that need taking care of and the lethargy hits you.

Well, programming is usually like that. Forget eager let generalization and constraints. I'll do the deferred version, and who knows, maybe for both constraints and generalization, an idea will hit me down the road, much like it did for the prepass.

I really do not want to make this decisions, but for v0.2 I won't be doing constraints in order to lower my workload. But on the positive side, that means that once I am done with what I need to do now, I will be pretty much done with the language.

I do not want to have shitload of stuff that need doing waiting for me after I am done with the typechecker here. I want to be finished with v0.2. The TC can act as support and the partial evaluator can do the rest of the heavy lifting.

Let me put in RecordApply at the type level in now. It is easy enough and I do not want to wait until after let generalization to do it.

I do not want to backtrack. After I am done with the last two cases, I want to start finishing up the typechecking phase and move to testing.

I'll do that after breakfast."


Monday 2020-08-10 12:01:19 by Alexei Lozovsky

Use original OpenSSL version for static frameworks (#7)

...but use the semversified version for dynamic frameworks. That is, for OpenSSL 1.1.1g static frameworks will have "1.1.1g" in their Info.plist, dynamic frameworks will have "1.1.107" in their Info.plist, and the tag on the repository will be "v1.1.107".

This is becase we need to keep the version in static frameworks distributed for Carthage (static ones) so that certain dependency checkers are happy. We need to modify the version in dynamic frameworks as they are going to be included into the app bundle and we need to make the App Store happy. We need to have the tag semver-valid too because Carthage needs to be still happy. But what if there is CocoaPods project which also uses a dependency checked which will be thrown off guard with a weird OpenSSL version? Well, the thing is, you as a maintainer are not entitled to be happy. All package managers apparently want you to suffer until you submit to their demands, so does the App Store where all the apps are going to be submitted. Ultimately, you do want that shiny money, right? If you didn't, you'd be working for a different ecosystem. IDK, making desktop Linux great again, or Plan 9, or Raku.

There is a moment when a person breaks. This is it for me. If someone demands the version to be a picture, or a dance, or a poem, then the version will be just that. If this commit causes you trouble -- whoever is reading this in "git blame" -- because you don't understand why the versioning is so weird, why there is this change that causes merge conflicts, why your customers are not happy because a weird version of dependency of a dependency prevents the app from validating. If any of this happens, please know that I'm deeply sorry for this, but it's your turn. I hope you can make the world a better place, as I hope that no one will have to touch this magic and it will continue working long past anyone remembers why. Until it breaks, that is.

It's 3:10 AM and I probably should not be submitting this change, waiting for a cool down, but... whatever vOv


Monday 2020-08-10 14:24:25 by Marko Grdinić

"> Then another question arises...why am I so stupid after consuming so many souls?

Kek. At least he is aware of it.

2:05pm. Let me resume. I really am into this novel way more than I should be.

One day I dream that these stories won't be bullshit. With Simulacrum I really went out of my way to give the self improvement loop some credibility. But things like absorbing souls or navel gazing of the cultivators is not something that has credibility. The MCs have the spirit, but they need to leave the ancient Chinese bullshit behind.

A new kind of religion is needed.

2:10pm. Focus me, focus.

        //| RawMatch of Range * body: RawExpr * (Pattern * RawExpr) list
        //| RawRecBlock of Range * ((Range * VarString) * RawExpr) list * on_succ: RawExpr

Now that I do not need to do let generalization in these directly, but will instead of leave them for a later pass, things are lot easier for me.

First off though, let me do the RecordApply.

| RawTRecordApply of Range * RawTExpr * RawTExpr

Let me add this to the parser.

let pairs = sepBy1 apply (skip_op "*") |>> List.reduceBack (fun a b -> RawTPair(range_of_texpr a +. range_of_texpr b,a,b))

Let me change * to , in Spiral. I'll make the type syntax symmetric with the term syntax.

    let record_apply = sepBy1 apply (skip_op "@") |>> List.reduceBack (fun a b -> RawTRecordApply(range_of_texpr a +. range_of_texpr b,a,b))
    let pairs = sepBy1 record_apply (skip_op ",") |>> List.reduceBack (fun a b -> RawTPair(range_of_texpr a +. range_of_texpr b,a,b))

This is all that I need in the parser.

In the typechecker I do have some green now. Let me implement the functionality for record apply.

| RawTRecordApply(r,a,b) ->

Let me do this case here.

        | RawTRecordApply(r,a,b) ->
            let q,w = fresh_var(), fresh_var()
            f q a; f w b
            unify r s (TyRecordApply(q,w))

This should be all that I need here.

I forgot to add the TyRecordApply case. That should result in some more green. Let me get on with it.

    and term_subst = function
        | TyVar _ | TyHigherOrder _ | TyB | TyPrim _ | TySymbol _ as x -> x
        | TyPair(a,b) -> TyPair(term_subst a, term_subst b)
        | TyRecord l -> TyRecord(Map.map (fun _ -> term_subst) l)
        | TyFun(a,b) -> TyFun(term_subst a, term_subst b)
        | TyForall(a,b) -> TyForall(a,term_subst b)
        | TyArray a -> TyArray(term_subst a)
        | TyApp(a,b,c) -> TyApp(term_subst a, term_subst b, c)
        | TyMetavar(i,_) -> term_get i
        | TyInl(a,b) -> TyInl(a,term_subst b)

Now this case is tricky as the term_subst will be the one that needs to do the substitutions.

        | TyRecordApply(a,b) ->
            let r = failwith "range"
            match term_subst a, term_subst b with
            | TyRecord l, TySymbol x ->
                match Map.tryFind x l with
                | Some x -> x
                | None -> errors.Add(r,RecordIndexFailed x); fresh_var()

I'll have to pass in range as an argument into term subst.

        | TyRecordApply(a,b) ->
            let r = failwith "range"
            match term_subst a, term_subst b with
            | TyRecord l, TySymbol x ->
                match Map.tryFind x l with
                | Some x -> x
                | None -> errors.Add(r,RecordIndexFailed x); fresh_var()
            | (TyRecord _ | TyVar _ | TyMetavar _) & a, (TySymbol _ | TyVar _ | TyMetavar _) & b -> TyRecordApply(a,b)
            | (TyRecord _ | TyVar _ | TyMetavar _), b -> errors.Add(r,ExpectedSymbolAsRecordKey b); fresh_var()
            | a,_ -> errors.Add(r,ExpectedRecord a); fresh_var()

This is really good. Let me pass in the range as well to term subst.

2:40pm. That is the really complicated part. I had not counter on having to pass range into this.

2:55pm. Did refactoring so that all occurences of term subst take in the range. Damn, this is so hacky, but I do need it.

Let me take care of unifying TyRecordApply with anything else.

| TyB, TyB -> er()

Huh, what the hell is this?

| TyB, TyB -> ()

This should be like so.

        let rec loop = function
            | TyMetavar(a,ka), TyMetavar(b,kb) ->
                if a <> b then
                    unify_kind ka kb
                    if a < b then term'.[b] <- got else term'.[a] <- expected
            | (TyMetavar(a,ka), b | b, TyMetavar(a,ka)) ->
                occurs_check a b
                unify_kind ka (tt b)
                term'.[a] <- b
            | TyVar(a,_), TyVar(b,_) when System.Object.ReferenceEquals(a,b) -> ()
            | (TyPair(a,b), TyPair(a',b') | TyFun(a,a'), TyFun(b,b') | TyApp(a,a',_), TyApp(b,b',_)) -> loop (a,b); loop (a',b')
            | TyRecord l, TyRecord l' ->
                let a,b = Map.toArray l, Map.toArray l'
                if a.Length <> b.Length then er ()
                else Array.iter2 (fun (_,a) (_,b) -> loop (a,b)) a b
            | TyHigherOrder(i,_), TyHigherOrder(i',_) when i = i' -> ()
            | TyB, TyB -> ()
            | TyPrim x, TyPrim x' when x = x' -> ()
            | TySymbol x, TySymbol x' when x = x' -> ()
            | TyArray a, TyArray b -> loop (a,b)
            | TyForall(a,b), TyForall(a',b') | TyInl(a,b), TyInl(a',b') ->
                unify_kind (snd a) (snd a')
                loop (forall_subst_single (a,b),b')
            | (TyRecordApply _ | _), (_ | TyRecordApply _) -> raise (TypeErrorException [r,RecordApplyCannotBeUnified])
            | _ -> er ()

I've refactored this a bit.

Metavar functionality really should come first.

if a < b then term'.[b] <- got else term'.[a] <- expected

No wait, shit. Why am I getting from the top level here. I must be crazy.

            | TyMetavar(a,ka) & a', TyMetavar(b,kb) & b' ->
                if a <> b then
                    unify_kind ka kb
                    if a < b then term'.[b] <- a' else term'.[a] <- b'

This is another bug squashed before it could get in my way.

| (TyRecordApply _ | _) & a, (_ | TyRecordApply _) & b -> raise (TypeErrorException [r,RecordApplyCannotBeUnified(a,b)])

Let me also pass in the type info.

        | TyRecordApply(a,b) ->
            let r = failwith "range"

Pft, nearly forgot to remove this.

        | TyRecordApply(a,b) ->
            match f a, f b with
            | TyRecord l, TySymbol x ->
                match Map.tryFind x l with
                | Some x -> x
                | None -> errors.Add(r,RecordIndexFailed x); fresh_var()
            | (TyRecord _ | TyVar _ | TyMetavar _) & a, (TySymbol _ | TyVar _ | TyMetavar _) & b -> TyRecordApply(a,b)
            | (TyRecord _ | TyVar _ | TyMetavar _), b -> errors.Add(r,ExpectedSymbolAsRecordKey b); fresh_var()
            | a,_ -> errors.Add(r,ExpectedRecord a); fresh_var()

The way this came out is particularly nice. I like it. Though I did need to make some other parts hackier. Now term_subst is less clean as I need to pass in ranges everywhere, but I will deal with it. Record application is worth it.

3:25pm. Let me take a short breather here.

3:30pm.

        //| RawMatch of Range * body: RawExpr * (Pattern * RawExpr) list
        //| RawRecBlock of Range * ((Range * VarString) * RawExpr) list * on_succ: RawExpr

How about these two? Do I finally have enough to tackle them?

Once I have them I will be 80-90% done with the whole of typechecking. Right now I am close to 80%.

3:40pm. Let me take a longer break. Maybe I'll step away from the screen to think about it for a while. I just do not feel like starting this yet.

I really hate how I am making progress by kicking out constraints. But type inference is absolutely necessary. Not only does this provide validation, but it will also fill in the implicits which is a huge service.

Constraints on the other hand are just validation. They are just the cream. Even if I had them, at best they'd be basic. Unlike Haskell for example, the constraints are not enough to cover the full range of uses even for typeclasses in Spiral. Spiral is just too expressive. So I can use that as an excuse.

I think once I start programming, I'll quickly get used to their absence. Though it will be awkward having the + operator unify to things other than primitives, I'll deal with that down the road.

4:35pm. This short breather is sure turning out long. Forget it. Let me shut down and step away from the screen for the next few hours. I need to charge up.

Though I've done this exercise plenty of times already, I'll try to visualize those two cases until I feel like doing them. I really should have everything I need by this point, so it is just a matter of finding the motivation for it."


Monday 2020-08-10 15:33:29 by RavenDuffy

a few tweaks

  • added borders to buttons
  • added rainbow colors to names
  • added links to github and linkedin
  • added past experience
  • added love for my girlfriend
  • added more layout things

Monday 2020-08-10 16:09:19 by Tommy P. Keane

NEW: Markdown Document on Interview Process

  • This is a new markdown file that I wanted to commit as just another README to sort-out and share some of my thoughts on the Interview Process.
  • This is mostly directed at myself, to collect my thoughts and remind myself of the processes I've gone through, and maybe reflect on what I could do more/less of, and how to improve my interviewing experiences.
  • There can be months or years between interviews, so I think that having this here is a convenient reminder for myself. I just wanted to share it in-case anyone else is interested.

Monday 2020-08-10 16:14:12 by bad@names

I never meant to cause you any sorrow, I never meant to cause you any pain

big edits to boat load holdout

  1. added a shit ton of navlinks to the tops of the containers, so cops can chase you up there and bots can climb up there to revive you if you die
  2. snipers have been modified, a boat has been added in the distance to allow for a new sniper position and the two roadside snipers (one on top of the container and one on top of the swat van) have been moved to avoid them being healed by medics
  3. new events on wave 5 and 6
  4. the helicopter drop-ins are no longer 4 FBI heavy riflemen, but instead 3 SWAT heavy shotgunners and a medic shotgunner
  5. some other stuff i probably forgot lol

Monday 2020-08-10 17:30:06 by vishaalkaran

Listview Sizing Solved!!!!!!

For some reason there are tables nested into each other!!! Who the fuck knows Why, but it shouldn't be. In listview examples on ms docs the layout has one table ONLY!!! it took a time since April 2018 to solve this!!! Fuck you listview


Monday 2020-08-10 18:53:03 by cheracc

shop items should be placeable now chest loot and shop items no longer get nbt tags if they aren't placeable blocks (fixes non-stacking arrows etc) spectators only get teleported to spawn if they go outside the original border, not the current border (fixes the nauseating teleport thing that happened at the end of the game) leaves are now 3x more likely to drop cookies for CookieMonster spawn points now load before players can join (fixes spawning on the roof) scoreboard only updates when players take damage or die (should greatly lessen scoreboard flicker) item frames and pictures should no longer be breakable. you can no longer take items out of frames (you can still turn them or put stuff in atm) you will no longer see your own disguise (you will get a "you are disguised as..." message on your action bar and you are indeed disguised quite well to others) the bossbar now correctly shows progress of the border closing Beastmaster: starts with only one egg but can find more in chests. He will only be allowed to have one wolf active at a time however. Analyzer: now sees the regular scoreboard after he dies. Barbarian Bloody Bane reworked - it now takes 10 "spirit power" to upgrade. animals give 1 spirit power, monsters 2, and players 5. you get a message when it gains spirit power and the current total will show in the item lore. (this might be too easy to upgrade, we'll see) bloody bane should no longer be white in death messages. Bombtastic more likely to find TNT in chests


Monday 2020-08-10 19:13:02 by Marko Grdinić

"7:15pm. It is this late? Damn.

At any rate, I've figured out pretty much everything. I know how to do eager let generalization now. I also know how to deal with constraints during the forward pass. I won't be able to deal with all of them during the first inference, but nonetheless, the way I am handling RecordApply right now is abysmal. There is a much better way.

I also know how to deal with forall vars without that ugly hack.

Also...I am going to change the constraint syntax compared to what I had in mind. I have a different perspective on them now.

7:20pm. I'd go into detail, but since I still haven't had lunch, let me get to that first.

8:30pm. Done with lunch. I do not feel like talking about it right now.

...

Let me do it.

///

I figured it out. The way to propagate scope information succinctly is to adjust unification is done.

The way I am doing it right now, is to unify metavariables with compound types directly.

inl f x =
    inl g forall a. (y : a) =
        (y, 1) = x
    ()

For unifying (y, 1) = x, I would do something like the following. x would be a metavariable, so I would unify '0 => (a, i32). Right now I am just using unique ids to differentiate between metavariables and have no scope information. But supposing I had scope information, what I could do is.

'0 (0) => (a (1), i32)

I had this idea before, but discarded it because that is still not enough to make this an error. Strictly speaking, in this example there is, but suppose I had the following chain of unifications...

'0 (0) => ('1 (1), '2 (1)) => (a (1), i32), then that would break.

This chain would correspond to code fragment like...

inl f x =
    inl g forall a. (y : a) =
        inl q,w = x
        (y, 1) = (q,w)
    ()

The way to properly unify this is to do something counter intuitive. Even though at the point this equality constraint is being processed the scope is 1, what I need to do is make a bunch of dummy metavariables with the previous scope of 0.

Then there is a rule if I am unifying two metavariables, the arrow points in the direction of the lower scope.

If I had to unify something like ('2 (1), '4 (0)) => ('0 (0), '5 (3)), those would reduce to '2 (1) => '0 (0) and '5 (3) => '4 (0).

If I had to unify something like '0 (0) => ('1 (1), '2 (1)) => (a (1), i32), it would be better to first extend it to '0 (0) => ('3 (0), '4 (0)) => ('1 (1), '2 (1)) => (a (1), i32)

Since '1 (1) => '3 (0) and '2 (1) => '4 (0), that would leave unifying ('3 (0), '4 (0)) => (a (1), i32). Then '3 (0) => a (1) is an obvious scope error. The great thing is that this kind of unification would propagate scope information in an optimal manner, so if I the type of statement is '5 (1) -> '5 (1) and the current scope is 1, I know I can generalize this. On the other hand if it is '5 (0) -> '5 (0), then I cannot. And thanks to this I should be able to do eager let generalization.

It seems simple, but the way I have the unifier implemented currently has made me myopic to this kind of structure. It is my first time doing top down type inference, so I keep missing obvious things. One thing I can't really use is separating equality constraints from the overall program as SPJ suggests. Type inference needs to be flow sensitive to an extent in order to deal with records and separating unifyication of equalities from the overall program would break that.

One type inference problem that is still difficult to me is how to deal with propagating constraints in mutually recursive blocks.

///

9:10pm. Let me also check out the answer I got on the PL sub."


Monday 2020-08-10 22:54:23 by copperwater

Fix: object materials: many bugs and omissions for material hatred

This started out with me trying to add a special case to searmsg(), which then turned into making the searmsg() code xhity-compatible, i.e. working regardless of who the defender and aggressor are (or even having no aggressor), and ballooned into fixing a ton of things that did not work correctly with regards to the material hatred system.

Changes to functions:

  • searmsg now takes a fourth argument, a boolean representing that the message should be minimal; e.g. "The silver sears foo's flesh!" or "foo is seared!" instead of "Your silver longsword sears foo's flesh!"
  • searmsg now uses "recoil" rather than "flinch" because it makes for slightly better and less verbose sentence structure.
  • New function, attack_contact_slots, which determines based on a monster attack what gear slots if any should be counted as the defender hating it. For instance, attack_contact_slots of an AT_CLAW attack will return the glove and ring slots.
  • mon_hates_material now correctly determines that a player infected with lycanthropy but not transformed should hate silver.
  • All the functions above are now xhity-compatible.

Bugs fixed:

  • Hate_material didn't detect a vampshifted player (one who has #monster'd into fog or wolf or bat form but can #monster again to resume vampire form). Now, Hate_material is just a shorthand for mon_hates_material, which didn't previously include a case for a non-transformed player with lycanthropy.
  • Monster hitting player with a weapon in melee combat applied material damage twice.
  • Player hitting monster with a weapon in melee combat applied material damage twice.
  • hates_material() didn't test is_elf() for iron hatred, meaning that it didn't apply to elvish monsters that are not S_ELF.

Omitted cases that should have caused material damage but didn't:

  • Player hitting self in the foot with a pick
  • Monster versus monster direct contact in melee combat
  • Player kicking an object barefoot
  • Player kicking an iron door barefoot
  • Monster wearing a helm and headbutting player

Omitted cases that did cause damage but lacked a message:

  • Player throwing something up and hitting themself in the head with it
  • Monster hitting a monster with a weapon in melee combat
  • Monster hit by an object from a trap
  • Player hitting a monster with an iron ball or iron chain
  • Player crashing into iron bars
  • Player with boots kicking a monster, while polyselfed into a form with kick attacks

Other:

  • I tried to add a comment everywhere a material hatred if statement does NOT add additional damage due to dmgval() having already added it. Anywhere one of these if statements doesn't have either a damage increase or a comment stating it happened elsewhere is considered a bug.
  • Unified codepaths for monster touching player with a body made of a material player hates and monster hitting player while wearing gear made of a material player hates.
  • Many of the hmonas() calls for special_dmgval have been merged. The code here for multiple claw/touch attacks hitting with strictly alternating arms has been removed; the player will hit with whatever gives the highest damage.
  • Iron haters opening and closing an iron door barehanded is a case I considered for applying material damage, but decided not to because it would really just be annoying. It can be assumed they all have glass doorknobs or something.

One case that this does NOT supply at this time is the one in which the aggressor hits a defender made of a material they hate with their bare skin, and should take damage. I can't think of a way to do this right now that doesn't involve adding more global variables (that could handle the case in the passive() functions). For the time being it shouldn't matter much; it would matter more if monks could be elves or similar.

(cherry picked from commit 047f1ca8cd782ef030f7f3949c3696cee3b8833b)


< 2020-08-10 >