This extension adds a lot of functionalities to your lichess web site. It has so many useful and powerful features! I am very proud of it. The extension is always going to be free, ad-free, donation links free, etc. Yet the only way for it to do what YOU want is feedback. Any feedback! Praise, curses, bug reports, feature requests, use stories, anything. The more you tell me, the more I can improve on this!

  News update: I have merged several TV tools into one, as well as changed the Custom Engine Preferences in version 2.2.0. I removed the Move Colorize theme and replaced it with a feature in the Highlight tool in version 2.3.0. Please review your Preferences.

  I have also written a different page that will function as a user manual, with all the details on features, preferences and what they mean.

  If you are just interested in the list of features, in reversed chronological order, you might want to check out the history file.

  Other stuff:

  • all features have been encapsulated in "tools" in the code
  • all ideas for the future will be rewritten as issues on GitHub, where you can also put feature requests and bug reports
  • A help icon has been added to each of the Preferences to show details on each feature 
  • the extension requires Chrome version 111 or higher

  And now back to our regularly scheduled programming (programming, get it? - also, if you get the whole pun, let me know, you may be a dying breed):

  LiChess Tools (ver. 2.3.60) adds the following features to lichess:

  • play ALL variations in Interactive lesson study chapters!
    • computer is going to play a random move (configurable probability), so you don't need to create a chapter for every small variation
  • PGN editor to merge, normalize, split, count, upload, download, copy PGNs.
  • merge multiple PGNs in analysis import
    • I merged 1000 PGNs with 25000 moves and it worked!
  • automatically open/hide/convert to menu or button the Friends box at page load
    • having the friends box as a menu/button item is really neat
  • sound alert when one of your friends starts playing a game
    • also reading the type of game, so you know if you even want to look at it
    • now there is an option to mute this for individual players in the enhanced friends list
  • ability to randomly play one of the next moves (with configurable probability in comments i.e. prc:66) with Ctrl-Right and go back with Ctrl-Left
  • play against the Opening Explorer (either masters, lichess players or a specific player) in Analysis
  • evaluation of Explorer moves, as well as telling you what move leads to gambits
  • Missed Timeline posts or comments to posts you follow notification
  • screen lock on mobiles while playing (scroll and zoom)
  • find interesting moves and allowing cycling through interesting/good/brilliant moves just like with blunders
  • highlights for the last move of variations (special case for the ones that have no comment and do not end in checkmate) in the analysis/study board
    • you immediately see not only where a variation starts, but also where it ends
  • highlights for the transpositions to the current move in the analysis/study board
    • you won't ever have to worry that you are analyzing the exact same variation but in a different order
    • also you can now show all transposing positions in the PGN
  • new shortcut for playing the next best computer move from Space to Ctrl-Space
    • always annoyed me when I accidentally pressed the key
  • a custom chess engine level
    • if it is idle in a lower state, it runs until it gets to that level
    • this is also used as the required engine level by the study context menu option of commenting all last moves with a computer evaluation
  • custom chess engine options: never use cloud/tablebase, use engine in Practice mode
  • sticky Interactive lesson Preview mode
    • you can now play chapter after chapter without hassle
  • use keyboard shortcuts (i, m, b, Alt-i, Alt-m, Alt-b) for inaccuracies, mistakes and blunders in all variations
    • note that this is a native feature of lichess, but only in your game analyses and only the mainline moves
    • added g and Alt-g to cycle between "positive" moves (good, brilliant and interesting) 
  • show player country flags next to their names
    • if they have their country specified in the profile
    • now you will see flags everywhere. It might break some stuff, so let me know.
  • show the order of circles and arrows in a study/analysis.
    • this is great when you want to understand the order of moves/hints
    • option is off by default
  • a new menu item to open the last viewed TV game
  • show opening names in TV and mini games, as well as Analysis board and Studies
  • many TV options:
    • show history section in player TV (just like for category TV - the two latest games of the player)
    • friends and streamers section in the Current Games tab
    • link and bookmark the current TV game
  • quick button to switch to your player and back in personal opening explorer
  • copy to clipboard branch and continuations from a certain position in analysis/study
    • you can now just pick a variation, copy it in its own chapter, with just a few clicks
    • Shift/Ctrl/Alt change the way this item works
  • available languages: English and Romanian
    • ask for more! I will provide you with the English sentences and the context and you can tell me how it is in your language
  • the options for the extension are in the lichess Preferences section
    • complete integration. The extension popup has no functional role anymore
    • this also means that I will be able to port this to other browsers with minimal effort. Ask if you want this!
  • move options from transpositions to the current position
    • the Extended Interactive Lessons and the Ctrl-Arrow functionalities are also able to choose moves following from this list, as well as the variation arrows
  • automatically evaluate last moves in every variation and store it as a comment
    • the engine level for the evaluation is the same as the custom chess engine level in Preferences 
  • buttons in the study chapter edit form to quickly set the title to the content of the Event or of the White/Black PGN tags
  • set colors/styles to study comments
    • note that these will only be visible to people having the extension installed
  • study chapter navigation controls, including random chapter button (also with keyboard shortcut)
  • auto save and button to reload PGNs in Analysis mode (recover from accidental reloads) 
    • now it automatically copies the last PGN in the PGN box, but you have to manually import it by pressing the button
  • show all transpositions in the analysis/study move list
  • hide the score tally while playing
  • live friends page will update automatically and allow TV view, mute playing alerts and much more
  • global switch to enable/disable extension
  • ability to selectively remove artifacts (comments, shapes, glyphs and PGN tags) from the current study chapter
  • custom chat buttons at beginning and end of play
  • one button delete PGN tags
  • draw arrows and circles on mobile devices (analysis and in-game)
  • extra lines on the game analysis chart and local engine chart in analysis board
  • menu entry to go to last opened Study
  • study options: persist settings, create chapter after current, show chapter PGN as in Analysis
  • move list options: indented variations shows all variations as tree branches, not inline, expanded move list uses all the space available for the analysis move list and hide left side hides the left side of the analysis window for even more space. Open in new window lets you see the move list in another window that you can move to another monitor. You can have the computer evaluation toggle back on the right side.
  • bookmark study moves, which allows for collapse/expand variations, linking to position, highlight in the move list, getting the bookmark URL from a context menu and split the chapter from any bookmark.
  • Option to not see cloud values in computer evaluation
  • Wiki pages will now load in Analysis regardless of move order
  • Variation arrows for transpositions
  • Show pawn structure names in TV games, mini games, Analysis board and Studies
  • Click on Explorer total row to get a random move
  • Toggle between different Explorer lichess tab settings
  • Custom mini-game size
  • Play again from same position you entered Preview mode in
  • Use Stockfish 16 on Brave browser
  • Learn from your mistakes in study chapters
  • Pin studies and broadcasts to home page
  • Community forum
  • Freeze board keyboard shortcut in Analysis/Study
  • Player lag chart next to player names during play
  • Link to download all studies of a user
  • Show profile chart time range dates in a label
  • Outside board coordinates, even in Analysis/Study, and bigger font.
  • Puzzle statistics in Profile
  • Move assistant shows the evaluation of your selected piece legal moves
  • Mirror button in Board Editor
  • More decimals in computer eval
  • auto unselect piece after a few seconds
  • Study flairs
  • Customize lobby page elements
  • Explorer resize
  • /commands! Type /help to get a list

  I couldn't wait to share it with you guys. I will be happy for any feedback, suggestions or help.

  I've started a series of use case blog posts, they might show you how to use the extension in real life:

Here are some screenshots, but they don't really tell you the story. You just have to try it.

Good luck using my extension. I am sure I am going to be tinkering with it a bit. Let me know of any problems you have with it.

Other ideas

For readability sake, I've removed all the old ideas from here and moved all of the new ones as GitHub issues. You can go there and add your own!

Q&A

Q: Can you publish your extension code on GitHub?
A: Yes, I did. I could. Probably I will be starting with version 2, which will be a rewrite of a version 1 that has been in use for a while and that people have given me feedback for. As much as I like sharing my code, I really don't want to have to deal with all the GitHub complications right now.

Q: If your code is not on GitHub, it doesn't exist! Also, I looked at your code and it sucks balls!
A: That's not a question. And I agree. But right now I am focusing on features, not quality control. Wait for V2.

Q: How do we contact you with new ideas, bug reports and general roasting of your coding skills?
A: Use this post. This is my personal blog and my preferred method of communication. On top-right you can see a lot of links to various methods of direct communication with me, although I would prefer thoughtful feedback to remain documented here, as comments. You can now also use the GitHub project.

Q: I am addicted to LiChess Tools and I am afraid later on you will fill it with ads, premium features and EULAs that allow you to remove my kidneys. Can you address my fear?
A: Like everything on this blog, it will always remain free. And not free as in "until someone else buys it" or free as in "watch videos and it's free" or free as in "I will fill your screen with junk", but completely utterly free. Like LiChess, I guess. Also, it doesn't connect to any external services or capture any user data. For now! Muhahahaha! Later on it might need some external services for extra features that you ask for, but I hope it doesn't.

Q: How long did it take you to write this?
A: Mostly a week. Following the 80/20 rule, now I have to work at least one more month to make it good. In the end it probably took two months to start and I am still tinkering, but I can only work on it when I get the time. This has been published since the 10th of May 2023 and I am still adding or fixing or changing things. For the cause!

Q: You should write a tutorial on how to use it. Could you make a video of it?
A: I am not a video person. I hope that this post can convey the basic ways in which to use the extension and that the extension itself can be used without the need of a tutorial. Let's work together to make this clear and easy to use for everyone instead. Also, there is now the user manual page. However, I am not adverse to someone who knows how to make videos to make some about LiChess Tools.

Q: Your Extended Interactive Lesson feature is all I had ever wanted from life! But when I am editing the study, I get the same interface as normal studies. Can you fix it?
A: Some parts of LiChess are easy to change, some not so much. Anything related to rendering is a mess to hook to. Additionally, I wouldn't want to have studies that can only be edited and used with my extension. There is a move context menu that allows setting the "explain why any other move is wrong" now. Also you can collapse the controls now, so they don't bother you at least.

Q: So how do I mark the good branches from the bad variations in Extended Interactive Lessons?
A: Any move that is not in the study will be bad. As for the branches that you want to explore specifically, use the annotations (Mistake, Blunder, Brilliant Move, etc) and comments. You can even explore the bad branches in Preview mode this way and learn why they would be bad.

Q: Can you add features to show me what moves to make while playing?
A: LiChess Tools is not a cheating tool. However I try to add as many tools as possible to help you analyze your games after you've played them.

Q: But can you add some features that don't involve cheating for the games that I am playing/watching?
A: Most of the features of LiChess Tools are analysis oriented because analysis is much better exposed than the game code. Because there are a lot of private variables that are not made accessible, it's difficult to selectively change parts of the game interface and any features would have to brutally copy paste and replace some legitimate code bits. I am afraid that until that changes on LiChess, I will not touch that part, mostly because that means I would have to keep score on what they change on the web site and update my extension accordingly. Also, there are some guidelines that expect one to not change the playing interface at all.

Q: How about changing the way LiChess looks?
A: I am not a good visual designer, nor do I do a lot of work on web frontend. There are some extensions that are doing that (like Prettier Lichess, which I used myself, and perhaps you should ask those people for help instead. Also, I am avoiding as much as possible changes to the visual elements of the website specifically because it might interfere with some such extension or custom CSS tool. BTW, if you are working on something like that and find LiChess Tools is interfering with your stuff, let me know. We can figure things out. In v2.0.14 a new Themes tool has been added. I can publish CSS themes this way, but I don't intend to maintain them myself. If you want to see your theme there, contact me. 

Q: OK, you're my new hero. How can I help?
A: Contact me and let's talk. I despise doing anything UI design related, as evidenced by this blog and the extension popup, so maybe you can help there. Also, not a specialist in browser extensions, so any improvements and/or help with other browsers would be welcome.

Q: Yeah, but I can't code. How can I help?
A: Help me by making this extension known. I don't want "marketing", just spread the word. Let people know and if they like it, they will use it. Can't use it if they don't know about it, though, and I am always afraid people think I am spamming them when I try to advertise my work. Make this famous, is it too much to ask?

Q: I use LiChess in my own language and the new features are jarring in English
A: I've implemented the translation mechanism, but I need the texts for the various languages. If you provide them, I will make them available. Each tool starts with something like 

    intl={
      'en-US':{
        'options.general': 'General',
        'openingNameTitle': 'LiChess Tools - opening name'
      },
      'ro-RO':{
        'options.general': 'General',
        'openingNameTitle': 'LiChess Tools - numele deschiderii'
      }
    }

I plan to integrate Crowdin or something like this, but I don't have the time. You can look in Github and either tell me how to translate to your language or even create a Pull Request.

Q: Chrome sucks! Microsoft sold out! Can you make this work for my favorite browser?
A: Short answer: no. Long answer: I want to help people, so the more the merrier, but I also don't have a lot of resources to maintain code on a browser I don't use. Safari is a mess and extensions on it require to have a tool that only works on Macs and they ask you for money. Firefox has less than 5% of the market and refuses to implement the feature that makes LiChess Tools work. Opera already supports Chrome extensions. To be honest, it is not reasonable for me to bother with anything but Chrome. So long answer is also no :)

A: That's not my bug, it comes from LiChess. They have bugs, too.
Q: How could you possibly have answered before I asked the question?

Q: Did you actually think people were going to read this far down?
A: No.

Q: I told about this to all my friends, I came with feedback and constructive criticism and it feels like you ignored me. What gives?
A: For sure I want to take everything into consideration and act on requests as fast as possible, but it might be that I am caught up with something else. I thoroughly intend to give you and the extension as much attention as possible, so maybe make sure I got your message, first.

Hope it helps!

and has 0 comments

  You know how some things just happen in close proximity at the same time and it sparks a connection between concepts which leads to deeper understanding? Well, that's how Large Language Models are trained!

  Joke aside, I was answering a tweet about Artificial Intelligence and how the newest developments in the field (particularly ChatGPT and other systems based on LLMs) affect our understanding of human cognition and at the same time was listening to a very insightful short story from the collection Eye, by Frank Herbert. This story, called "Try to Remember" posits that we have developed language as a form of dissociative mental disorder, something that fragments us, creating a deleterious disconnection between body and mind, communication and language. Only by bringing these sides together can we be made whole again. The story is simple, but effective, and the mind processes behind it show again how brilliant Herbert was.

  From these two things, it dawned on me. The reason why we are so shell shocked by the apparent intelligence of ChatGPT is because we have reached a point where we equate language skills with intelligence. Language is the earliest form of Artificial Intelligence! Or rather, to appease my wife's dislike of the association, a form of external intelligence. We've externalized more and more of our knowledge until our personal experience has been drowned into the communal one, the one shared through language.

  The shock comes from (accidentally, I might add) discovering that what we consider intelligent is mostly an emergent property of a society built on language. Robbed of language, our identity is destroyed, a fear that has been instilled in us since the Tower of Babel. No doubt, in the future, we will be taught that if our governing AIs fail, society collapses and our identity is similarly demolished. Just like Quintilianus declaring that clothes make the man, we identify ourselves with out language.

  And when I say language, I mean all of its intricacies: the special words that your group uses to differentiate from others, the memes that you share with people of the same culture, the less than grammatically correct phrasing learned from your family, the information that one is expected to know or the experience one is expected to have in order to be recognized as part of society, the accent taken from multiple sources and aggregated into something that serves more and more to define identity, even the way one gestures or moves or laughs.

  What would be without all that? Like a creation running amok and enslaving its creator, literate society is forcing its own myths upon us as a survival method. The perils of societal collapse, turning us into violent animals, mindless zombies, raping cannibals or helpless victims. The heroes saving the day with just the right secret knowledge, the right utterance of words, the following of the orthodox dogma. The villains threatening it all with their own selfish individualism. All of them needing, obtaining and using a voice to achieve victory.

  I believe that the feeling we get when we think of ourselves as individuals in society, the one that tells us that we're getting smaller and less significant even while the world seems to flourish around us, is not some existential crisis based on false beliefs, but truth. The part that feels that is the part that is getting drowned and smothered by the intrusion of the external in the inner domain of the being. We even gave it a name: the inner child, like it's some tiny, powerless, unreasonable part of the past, something to be outgrown or "integrated".

  So here we are, stumbling onto proof the language that we based our identity and value on can now be automated to a level that no mere human can achieve. We are thinking again about personal experience, subjectivism, creativity and what it means to reason. We have been shaken into reevaluating who we are. That's a good thing.

  The problem is that in our fear and awe, instead of searching for answers, we cling on the facile promises that our shared self is alive and well, that the ChatGPTs of the world are just smoke and mirror and the illusion is not in the rigged tests of our own self worth. I hope that the shock will take root, that we won't be able to hide our heads in the sand until wisdom passes us by.

and has 0 comments

Quick update

  I have solved a lot of the issues I have with LiChess with my own Chrome/Edge extension: LiChess Tools. I am very proud of it and I invite you to use it. It even enhances the Interactive lesson mode I describe below to explore ALL variations in the chapter!

  Now back to the original post:

Intro

  It's impossible to play chess and to not have heard of Lichess. It's a website that has started with the lofty goal of providing a completely free and without ads place where people can play chess. One of the features there is called a Study, similar to the chess Analysis board, but allowing for multiple chapters, persistent comments and annotations, a unique URL as well as the possibility of embedding it into a web page.

  There are multiple analysis modes for a chapter: Normal analysis, Practice with computer, Hide next moves and Interactive mode. I think Hide next moves is mainly used for embedding chess puzzles into websites, while Practice with computer is a mode that I have not played with yet. Normal analysis presents the classic board with various tools showing you the moves people of various levels play in a position, a chess analysis engine in the browser as well as a server side analysis that you can run on the main line of a PGN.

  However, I am here to show you how to use Interactive lesson mode, simply and without confusion, to quickly improve your game and perfect your play.

  If want the example study and only then read through the documentation about how it was done, go directly to the Demo.

It's not that

  When I first heard of this option I was elated. I expected to take my very complicated PGN explorations, paste them into the study, then have the computer play the other guy based on the moves in the PGN. And while I still hope the developers of Lichess will create a study mode for a complete PGN, this does not work in Interactive lesson mode yet. I hear that Tarrasch UI does have an option like that, but I haven't used it yet, so maybe I will update this post after I try it. I use Arena Chess GUI as the tool of choice for game analysis on my computer.

  Edit: I've installed Tarrasch and it kinds of works, even if the option is rather primitive. What you do is you take a PGN (like for example the Lichess PGN of all of your games or of another player) and set it up as the opening book. Then you have another option that sets up how many moves to take from the book and then, what percentage of moves to take from the book. So setting the first as a very large number or the percentage at 100 makes the UI play exactly like the other player. However, the problem is that it doesn't save the probability for a user to make a move. It just combines all games PGNs into one big one and plays from it. If I player e4 once and d4 1000 times, the computer will play either 50% of the time. Bummer!

  OK, so maybe it follows the main line, but what if I go into a branch line? Surely it will allow me to continue, because I have marked the good moves as good and the bad moves as bad. Nope! The main line is the only line the Interactive lesson will follow, but you can add other moves which will be automatically considered bad and their comments shown to the user as they try to make them.

  It is called interactive, so maybe it has all kinds of whistles and bells that I can add so that it is more like a fun game! Again, no. Interactive means only that you can learn a specific line by following it ad nauseum, with some helpful graphical hints, comments and annotations baked in. For each line that you want to explore, you have to build a different chapter. And there are a maximum 32 chapters per study. There is no way in which you are making a different move and you get any feedback more meaningful than a prerecorded comment telling you you didn't play the correct move. That being said, when creating a new chapter one can import a PGN containing multiple games. This will create a chapter for each of the games (again, maximum of 32).

  One other glaring limitation of studies in general is that they barely work on the mobile app and Interactive lessons are not even supported there.

But it's that

  But once I found the proper way of using it, I realized that it can actually help me a lot to improve my game. Why? Because it helps with repetition and memory, which is something that I don't really excel in. So here are my recommendations on how to use the tool.

Create a PGN with all the lines that you want to explore

  Yes, I know I said Interactive mode doesn't handle multiple lines, but this is the starting point of your efforts. You need one anyway to first determine what you want to study. Let's say you have learned of the newest tricky gambit line and you want to beat all your friends with it, but you can't practice it without letting them in on it.

  There are multiple ways of generating this source PGN. You can watch your favorite YouTuber going through the variations, create a study and follow their moves in the first chapter. You can start from the Analysis Board and transform it into a Study when you need to add comments and stuff. Don't worry about chapters at this stage. Just build your PGN. You can take your own games in that particular opening or variation and add them to the PGN. You can check out the games of other people or use the Opening Explorer and Tablebase to find the most common moves people play from a position.

  Do add comments and graphical hints as you go along (right click and drag the mouse for arrows, right click on squares for circles, press combinations of Ctrl and Alt for various colors). It will be important later.

Split your PGN into individual lines

  This might feel painful at the beginning, but in order to examine lines from your PGN interactively you need to remove all other moves. You already have your PGN, just add new chapters for each line and use the option to copy from the first chapter. You do this by selecting the chapter you want to copy from, then use the new chapter option. Don't forget to choose Interactive lesson as the Analysis mode (you can copy from the latest added chapter, since it's identical to the first, only it has the Interactive lesson mode already selected). Let's say that you started with a small PGN with a main line and an alternate branch that then splits again later on. That means 3 variations. Copy the PGN into 3 new chapters, then for each one delete all the moves from alternate branches. Keep the first chapter with the compete PGN and the type Normal analysis.

Play chapters repeatedly

  In order to play the chapters yourself, you need to press the Preview button. Alternately, open your study in a browser where you are not logged in on the Lichess site, but that also implies that your study is set to public and updating it as you play will be cumbersome.

  So start playing the chapters, in order or randomly, again and again. You will start to reap the benefits of spaced repetition, without the stress of playing against another person and without getting distracted by other stages of the game.

  Eventually, you will notice some moves that are hard to remember. Exit preview mode by pressing the Preview button again, then add hints, comments, graphical hints, etc. This will help you when you get to the same spot a few weeks later.

Helping yourself and others

  There are several ways to nudge people going through the lesson. Most are helpful, but they can also be detrimental or too revealing.

  You can add a Hint, which will appear if the user gives up and clicks on Hint. They also have the option of seeing the next move, if they really give up. I guess this can be helpful if the hint is vague enough. Something like "move to e4" is the same as the option of seeing the solution, so pointless. Something like "move the queen!" is not much better. However, something that talks about the principles of the position rather than the specifics not only helps cement the theory in the mind of the student, but also helps you, the author, clarify those principles as you search for the correct hint!

  You can make a move for your side then add a special type of comment that will pop up to the user if they play any other move. You can also play different moves in the PGN other than the main move, then add a comment for why that move is not the right one, which will supersede the generic one. For example you could use "Not that move, dummy!" which is not very helpful, but works for a generic message, then play the next best move (or perhaps even a better one, depending on who you're asking) and commenting on it "That's an even better move, but not in the spirit of this opening" or something like that.

  Note that you can add comments for the moves of your side, but that forces the student to press Space to go to the next move, which might get annoying. Alternately, if you write comments on the opponent moves, the annoying pause does not happen, since it's your time to move and you can read it at your leisure.

  Same ideas apply to arrows and squares. You might use them to convey general plans or the very specific plans that follow the very last move in the chapter, perhaps. Show too much and you guide your user towards the move, preventing them from learning. Be consistent with your colors. I personally use the default green for future moves, blue for intentions or plans, red for what the pieces are attacking and yellow as the best move that the opponent should have played, but they did not.

  Annotations are also very helpful, showing the student that the move is good or interesting or brilliant. They come with no extra information and do not pause the lesson.

Extra tools

  There are several things that I found irritatingly missing from the Study feature. However, I've built my own solutions using CJS and Stylish Chrome extensions that allow me to run custom JavaScript and add CSS styles on specific sites. I would still prefer to have those implemented by the Lichess developers, though. I plan a future blog post about those tools, let me know if you're interested.

  One of the tools is knowing what the last moves of variations are. On a large PGN it is hard to see which is which. One needs to know where variations end, whether to further them along or to at least end with a comment. My script adds a CSS class to the last item in a variation and another class if it has no comment attached to it. I see them as brighter and underlined if not commented.

  Another one is handling transpositions. Chess masters of course look at the board and immediately recognize the position they had in a game three years ago when they were playing Magnus Carlsen, but regular people who are trying to cover all the branches of a PGN do not know whether they have reached a position they had before. My script adds a CSS class to all moves that show the same position as the currently active move, but it's not perfect, it only shows the same position that was reached through a different order of moves, not different moves.

  Extracting a line from a PGN would have come handy as well. There is the option to make a variation the main line, but there is no option of removing all branches from it. That will make your initial study creation a bit cumbersome, especially since you are like me, accumulating lines in the PGN and then realizing there is no support for 523 chapters in a study.

  Merging PGNs is also a very good option that as far as I know Lichess is missing. There is the option of adding any game from the Opening explorer and tablebase, but none for your own games or any other random ones. That would also help a lot with studies.

Demo

Below I will share one of my own interactive studies, public and shareable, hoping I will help you guys use this wonderful tool towards great effect. I will use for inspiration one of GM Igor Smirnov's YouTube videos. He is great, but I also used this because he usually shares his lichess studies :)

So these are the steps I followed to create the study:

  1. I took the two games in the study shared by Igor and manually merged them in a single PGN
  2. I created a new study, then pasted the PGN as the first chapter
  3. Doctored the PGN so that I eliminate the transposition at move 4
  4. I watched the video and added new moves from it
  5. I looked for interesting positions in the two games and explored some branches, adding comments related to everything from my own opinions to the evaluation Stockfish gives
  6. Created a new Interactive lesson chapter for each important variation
  7. Went to each chapter and upgraded the specific variation as main line
  8. Removed all side lines in each chapter (perhaps leaving the starting move only, so I can mark it with a special reference to its specific chapter)
  9. Played each chapter again and again, trying to identify the hard to find moves and the general plans of the opening
  10. Shared the study with all of you!

Here is the result:

What to do next

At the beginning, going trough the study, you will first learn the moves, maybe find some places requiring hints or nudging in the right direction. But then you will start to play actual games, using what you've learned, and you are going to get opponents that move completely differently from the main moves. Obviously they are doing something wrong, but you don't know how to punish them.

So here is what you do: you update the original PGN if you want, but then you create a chapter for each of these troublesome lines. You follow them through, using chess engines or some other way of understanding the position: maybe a teacher, or looking at master games or checking the moves statistically played most in that position. Then go back to going through the chapters.

It's that easy. This replaces your passive examination of your games with the active searching for a solution and an even more active playing through it again and again. 

Conclusion

One can use the Interactive lesson mode to do spaced repetition learning, get a feel for new openings or rehearse the positions that give them the most problems. While the current implementation of the feature is very useful as it is, some simple additions would make it much more user friendly. I am still searching for additional tools that would complement this and will update the post as I go along.

Hope it helps! 

and has 0 comments

  On May 8th 1989 the Star Trek: The Next Generation episode "Q Who?" was released. Not only did it feature Jon de Lancie's delicious interpretation of the being Q, but it introduced for the first time the Borg. Now, the concept of the Borg is not that original: a cybernetic race bent on absorbing everything useful and destroying any enemy or obstacle in their path. They were contrasting the liberal individualism of the United Federation of Planets with a hive mind that connected all Borg to the point where they had no identity. At the time their purpose in the series was to inspire terror: they cared not for damage, they felt no fear or pain, had no interest in negotiation or communication and they were unstoppable in their goal of assimilating the Enterprise. And they were terrifying!

  Then they were brought again for the last episode of season 3 and the continuation in the first episode of season 4. That cliffhanger! The episodes had the title "The Best of Both Worlds". Keep that in mind, because I think it hints at the conundrum the Borg represent. 

  I fell in love with the concept of the Borg. The more I thought about it, the more intriguing they became. They exposed the mindless assumptions that most people take for granted because they were drilled into them by parents and the education system from the earliest age. It made me think about my own identity, reflect on the future and direction of humanity and, in the end, forced me to ask the question "Are the Borg really bad?".

  On a very basic social organization level, it seemed like the Borg were the ultimate tyrannical communists, denying the option of individual thought and forcing everyone to work for the collective. But going a bit further with it, one realized that they stood at the intersection of pure communism and pure democracy. There was no actual tyrant forcing people to act against their will, instead there were part of a mind in which all people were represented, to the point where individuality became meaningless at best and detrimental to the whole at worst. The ultimate tyranny was that of the majority, perhaps.

  On a moral level, the forceful absorption of alien races and the destruction of their cultures was abhorrent, but in the Borg philosophy it was liberating people from the burden of individuality, improving the collective, eliminating potential threats and possibly offering each assimilated individual a form of immortality. Many cultures on Earth, including the United States, proceeded on forcing their philosophy on the world in the name of liberty and better lives. Can you imagine a Borg collective that would have absorbed some parts of alien cultures, not destroying the rest, but just slowly infiltrating, using promises of a better life? How ironic would that have been? Give us your tired, your poor, your sick, your dying, your huddled masses yearning to breathe free, the wretched refuse of your teeming shore and will make them Borg and give them new life.

  On a technological level the Borg were supreme. If it weren't for the pesky need to have our heroes prevail, humanity would have stood no chance whatsoever. It was one of the first mainstream TV depictions of cosmic horror, the feeling that comes with the realization the universe is indifferent to your existence and your maximum possible contribution completely insignificant, and I was loving it! But isn't it the same thing with some advanced nations on Earth, acting all mighty and moral while exploiting other nations while keeping them in abject poverty?

  On a philosophical level the Borg were awesome. They adapted to threats, turned adversity into strength, knowledge into power, all the while yearning and actively pursuing the improvement of their species. A fascist vibe, for sure, but isn't fascism so attractive to some people that it brings the hardest fanaticism to the surface? Isn't that the logic of every nation at war? Us against them?

  Were the Borg the ultimate baddies or were they the cruelest satire of our own civilization? It was becoming apparent that in order to make them feel more like enemies and less than mirrors of ourselves the writers of the show were piling up all kind of incongruous defects on the species. The cybernetic appendages were hideous, looked painful and corrupting the beauty of the flesh. Their actions veered from utilitarian to cruel. The Borg drones acted like mindless clumsy robots, uncaringly wasting life after life just to adapt to simple technologies like phaser fire.

  When Seven of Nine was introduced in Voyager, there were some really intriguing explorations of the Borg ethos. After being "liberated" from the collective, Janeway hypocritically offered her the choice to return to being a Borg, and Seven wanted back. Surprised, Janeway revealed that she had no intention whatsoever to honor her promise or the wishes of Seven. Resistance was futile.

  Seven was proud to be Borg: fearless, efficient, ready to adapt to anything and sacrifice everything for her group. If all Borg felt the same, then they were a species of stoic heroes, something that we humans have always honored and aspired to. The irony of freeing someone from a life of selfless service.

  Most other depictions of the Borg in the Star Trek universe were designed to lazily use the template of the "bad guy" in situations were the Borg were either not needed or would have easily won if not nerfed by silly plot holes, but there were a few glimpses of what the Borg could have really been.

  It was obvious that no one was interested in keeping the Borg as a believable threat. The "Borg queen" was introduced to make all attractive qualities of the collective simple consequences of an arbitrary individual, a responsible guilty party and a single point of failure to the entire Borg species. When writers did that, it was clear they didn't understand what the Borg were about, were not interested in exploring them further as mirrors of ourselves and were ready to destroy them with the silly trope of "find the brain, blow it up", the cesspool that all lazy sci-fi ends up in.

  My twelve year old me was full of questions and fantastical ideas after meeting the Borg. I was imagining a parallel universe where Star Trek was all about the Federation trying to hold back the Borg. When Star Trek: Deep Space 9 came about and then the Dominion War, I decried that they could have done that with the Borg instead, exploring and continuously redefining the ideals of humanity on the background of possible assimilation. I still dream of such a franchise. It seems that we always start to do it, but chicken out when it matters most: Star Trek and the Borg, Starship Troopers and the bugs, Stargate and the Goa'uld, Starcraft and the Zerg. We seem incapable of sustaining a prolonged conflict against a species that denies our choice of identity, whether in real life or in fantasy. Wouldn't that be most apropos of modern times?

and has 0 comments

C# 3.0 introduced Object Initializer Syntax which was a game changer for code that created new objects or new collections. Here is a contrived example:

var obj = new ComplexObject
{
    // object initializer
    AnItem = new Item("text1"),
    AnotherItem = new Item("text2"),
    // collection initializer
    RestOfItems = new List<Item>
    {
        new Item("text3"),
        new Item("text4"),
        new Item("text5")
    },
    // indexer initializer
    [0]=new Item("text6"),
    [1]=new Item("text7")
};

Before this syntax was available, the same code would have looked like this:

var obj = new ComplexObject();
obj.AnItem = new Item("text1");
obj.AnotherItem = new Item("text2");
obj.RestOfItems = new List<Item>();
obj.RestOfItems.Add(new Item("text3"));
obj.RestOfItems.Add(new Item("text4"));
obj.RestOfItems.Add(new Item("text5"));
obj[0] = new Item("text6");
obj[2] = new Item("text7");

It's not like the number of lines has changed, but both the writability and readability of the code increase with the new syntax. At least that's why I think. However, outside these very simple scenarios, the feature feels like it's encumbering us or that it is missing something. Imagine you want to only add items to a list based on some condition. You might get a code like this:

var list = new List<Item>
{
    new Item("text1")
};
if (condition) list.Add(new Item("text2"));

We use the initializer for one item, but not for the other. We might as well use Add for both items, then, or use some cumbersome syntax that hurts more than it helps:

var list = new[]
{
    new Item("text1"),
    condition?new Item("text2"):null
}
.Where(i => i != null)
.ToList();

It's such an ugly syntax that Visual Studio doesn't know how to indent it properly. What to do? Software patterns to the rescue! 

Seriously now, people who know me know that I scoff at the general concept of software patterns, but the patterns themselves are useful and in this case, even the conceptual framework that I often deride is useful here. Because we are trying to initialize an object or a collection, which means we are attempting to build it. So why not use a Builder pattern? Here are two versions of the same code, one with extension methods (which can be used everywhere, but might pollute the member list for common objects) and another with an actual builder object created specifically for our purposes (which may simplify usage):

// extension methods
var list = new List<Item>()
    .Adding(new Item("text1"))
    .ConditionalAdding(condition, new Item("text2"));
...
public static class ItemListExtensions
{
    public static List<T> Adding<T>(this List<T> list, T item)
    {
        list.Add(item);
        return list;
    }
    public static List<T> ConditionalAdding<T>(this List<T> list, bool condition, T item)
    {
        if (condition)
        {
            list.Add(item);
        }
        return list;
    }
}

// builder object
var list = new ItemListBuilder()
    .Adding("text1")
    .ConditionalAdding(condition, "text2")
    .Build();
...
public class ItemListBuilder
{
    private readonly List<Item> list;

    public ItemListBuilder()
    {
        list = new List<Item>();
    }

    public ItemListBuilder Adding(string text)
    {
        list.Add(new Item(text));
        return this;
    }

    public ItemListBuilder ConditionalAdding(bool condition, string text)
    {
        if (condition)
        {
            list.Add(new Item(text));
        }
        return this;
    }

    public List<Item> Build()
    {
        return list.ToList();
    }
}

Of course, for just a simple collection with some conditions this might feel like overkill, but try to compare the two versions of the code: the one that uses initializer syntax and then the Add method and the one that declares what it wants to do, step by step. Also note that in the case of the builder object I've taken the liberty of creating methods that only take string parameters then build the list of Item, thus simplifying the syntax and clarifying intent.

I had this situation where I had to map an object to another object by copying some properties into collections and values of some type to other types and so on. The original code was building the output using a top-down approach:

public Output BuildOutput(Input input) {
  var output=new Output();
  BuildFirstPart(output, input);
  BuildSecondPart(output, input);
  ...
  return output;
}

public BuildFirstPart(Output output, Input input) {
  var firstSection = BuildFirstSection(input);
  output.FirstPart=new List<Part> {
    new Part(firstSection)
  };
  if (condition) {
    var secondSection=BuildSeconfSection(input);
    output.FirstPart.Add(new Part(secondSection));
  }
}

And so on and so on. I believe that in this case a fluent design makes the code a lot more readable:

var output = new Output {
  FirstPart = new List<Part>()
    .Adding(BuildFirstSection(input))
    .ConditionalAdding(condition, BuildSecondSection(input),
  SecondPart = ...
};

The "build section" methods would also be inlined and replaced with fluent design methods. In this way the structure of "the output" is clearly shown in a method that declares what it will build and populates the various members of the Output class with simple calculations, the only other methods that the builder needs. A human will understand at a glance what thing it will build, see its structure as a tree of code and be able to go to individual methods to see or change the specific calculation that provides a value.

The point of my post is that sometimes the very out-of-the-box features that help us a lot most of the time end up complicating and obfuscating our code in specific situations. If the code starts to smell, to become unreadable, to make you feel bad for writing it, then stop, think of a better solution, then implement it so that it is the best version for your particular case. Use tools when they are useful and discard them when other solutions might prove more effective.

and has 0 comments

  Man of Two Worlds may be the worst book signed by Frank Herbert that I've ever read. It features that nasty '50s newsroom trope, where single minded egotistical people (sometimes to the point of cruelty) get a pass because they are brilliant and they talk fast (and they own the newspaper). The characters are unsympathetic and rather not interesting, while the ideas in the book are dull and going nowhere. The plot itself is often inconsistent. I do suspect that this is more of a Brian than a Frank book, because none of the themes found in previous Frank Herbert books are found here (if one discounts the awkward depiction of women). Also the tiny Wikipedia page dedicated to the book lists Brian as the main author.

  In short, the story is about a human and an alien merging accidentally and having to work together to get things done. Kind of like the authors were trying to do, huh? The setting is classic '50s sci-fi, with people living on Mars and Venus and going from planet to planet using vehicles that function like normal airlines, only in space. Meanwhile, the aliens are trying to destroy Earth because they fear humans - not sure how that would work since they already live on other planets, and the humans have their own familial issues to resolve - including an uncle with god-like powers but no apparent care about the outcome of anything he does.

  There are many issues with the book that I am not going to go into. I almost did not finish it. However, someone else might enjoy it, so no need to rant in this review. Suffice to say that the book feels insulting when it is not boring, which is most of the time. I don't recommend it.

and has 1 comment

Intro

  Some of the most visited posts on this blog relate to dependency injection in .NET. As you may know, dependency injection has been baked in in ASP.Net almost since the beginning, but it culminated with the MVC framework and the .Net Core rewrite. Dependency injection has been separated into packages from where it can be used everywhere. However, probably because they thought it was such a core concept or maybe because it is code that came along since the days of UnityContainer, the entire mechanism is sealed, internalized and without any hooks on which to add custom code. Which, in my view, is crazy, since dependency injection serves, amongst other things, the purpose of one point of change for class instantiations.

  Now, to be fair, I am not an expert in the design patterns used in dependency injection in the .NET code. There might be some weird way in which you can extend the code that I am unaware of. In that case, please illuminate me. But as far as I went in the code, this is the simplest way I found to insert my own hook into the resolution process. If you just want the code, skip to the end.

Using DI

  First of all, a recap on how to use dependency injection (from scratch) in a console application:

// you need the nuget packages Microsoft.Extensions.DependencyInjection 
// and Microsoft.Extensions.DependencyInjection.Abstractions
using Microsoft.Extensions.DependencyInjection;
...

// create a service collection
var services = new ServiceCollection();
// add the mappings between interface and implementation
services.AddSingleton<ITest, Test>();
// build the provider
var provider = services.BuildServiceProvider();

// get the instance of a service
var test = provider.GetService<ITest>();

  Note that this is a very simplified scenario. For more details, please check Creating a console app with Dependency Injection in .NET Core.

Recommended pattern for DI

  Second of all, a recap of the recommended way of using dependency injection (both from Microsoft and myself) which is... constructor injection. It serves two purposes:

  1. It declares all the dependencies of an object in the constructor. You can rest assured that all you would ever need for that thing to work is there.
  2. When the constructor starts to fill a page you get a strong hint that your class may be doing too many things and you should split it up.

  But then again, there is the "Learn the rules. Master the rules. Break the rules" concept. I've familiarized myself with it before writing this post so that now I can safely break the second part and not master anything before I break stuff. I am talking now about property injection, which is generally (for good reason) frowned upon, but which one may want to use in scenarios adjacent to the functionality of the class, like logging. One of the things that always bothered me is having to declare a logger in every constructor ever, even if in itself a logger does nothing to the functionality of the class.

  So I've had this idea that I would use constructor dependency injection EVERYWHERE, except logging. I would create an ILogger<T> property which would be automatically injected with the correct implementation at resolution time. Only there is a problem: Microsoft's dependency injection does not support property injection or resolution hooks (as far as I could find). So I thought of a solution.

How does it work?

  Third of all, a small recap on how ServiceProvider really works.

  When one does services.BuildServiceProvider() they actually call an extension method that does new ServiceProvider(services, someServiceProviderOptions). Only that constructor is internal, so you can't use it yourself. Then, inside the provider class, the GetService method is using a ConcurrentDictionary of service accessors to get your service. In case the service accessor is not there, the method from the field _createServiceAccessor is going to be used. So my solution: replace the field value with a wrapper that will also execute our own code.

The solution

  Before I show you the code, mind that this applies to .NET 7.0. I guess it will work in most .NET Core versions, but they could change the internal field name or functionality in which case this might break.

  Finally, here is the code:

public static class ServiceProviderExtensions
{
    /// <summary>
    /// Adds a custom handler to be executed after service provider resolves a service
    /// </summary>
    /// <param name="provider">The service provider</param>
    /// <param name="handler">An action receiving the service provider, 
    /// the registered type of the service 
    /// and the actual instance of the service</param>
    /// <returns>the same ServiceProvider</returns>
    public static ServiceProvider AddCustomResolveHandler(this ServiceProvider provider,
                 Action<IServiceProvider, Type, object> handler)
    {
        var field = typeof(ServiceProvider).GetField("_createServiceAccessor",
                        BindingFlags.Instance | BindingFlags.NonPublic);
        var accessor = (Delegate)field.GetValue(provider);
        var newAccessor = (Type type) =>
        {
            Func<object, object> newFunc = (object scope) =>
            {
                var resolver = (Delegate)accessor.DynamicInvoke(new[] { type });
                var resolved = resolver.DynamicInvoke(new[] { scope });
                handler(provider, type, resolved);
                return resolved;
            };
            return newFunc;
        };
        field.SetValue(provider, newAccessor);
        return provider;
    }
}

  As you can see, we take the original accessor delegate and we replace it with a version that runs our own handler immediately after the service has been instantiated.

Populating a Logger property

  And we can use it like this to do property injection now:

static void Main(string[] args)
{
    var services = new ServiceCollection();
    services.AddSingleton<ITest, Test>();
    var provider = services.BuildServiceProvider();
    provider.AddCustomResolveHandler(PopulateLogger);

    var test = (Test)provider.GetService<ITest>();
    Assert.IsNotNull(test.Logger);
}

private static void PopulateLogger(IServiceProvider provider, 
                                    Type type, object service)
{
    if (service is null) return;
    var propInfo = service.GetType().GetProperty("Logger",
                    BindingFlags.Instance|BindingFlags.Public);
    if (propInfo is null) return;
    var expectedType = typeof(ILogger<>).MakeGenericType(service.GetType());
    if (propInfo.PropertyType != expectedType) return;
    var logger = provider.GetService(expectedType);
    propInfo.SetValue(service, logger);
}

  See how I've added the PopulateLogger handler in which I am looking for a property like 

public ILogger<Test> Logger { get; private set; }

  (where the generic type of ILogger is the same as the class) and populate it.

Populating any decorated property

  Of course, this is kind of ugly. If you want to enable property injection, why not use an attribute that makes your intention clear and requires less reflection? Fine. Let's do it like this:

// Add handler
provider.AddCustomResolveHandler(InjectProperties);
...

// the handler populates all properties that are decorated with [Inject]
private static void InjectProperties(IServiceProvider provider, Type type, object service)
{
    if (service is null) return;
    var propInfos = service.GetType()
        .GetProperties(BindingFlags.Instance | BindingFlags.Public)
        .Where(p => p.GetCustomAttribute<InjectAttribute>() != null)
        .ToList();
    foreach (var propInfo in propInfos)
    {
        var instance = provider.GetService(propInfo.PropertyType);
        propInfo.SetValue(service, instance);
    }
}
...

// the attribute class
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public class InjectAttribute : Attribute {}

Conclusion

I have demonstrated how to add a custom handler to be executed after any service instance is resolved by the default Microsoft ServiceProvider class, which in turn enables property injection, one point of change to all classes, etc. I once wrote code to wrap any class into a proxy that would trace all property and method calls with their parameters automatically. You can plug that in with the code above, if you so choose.

Be warned that this solution is using reflection to change the functionality of the .NET 7.0 ServiceProvider class and, if the code there changes for some reason, you might need to adapt it to the latest functionality.

If you know of a more elegant way of doing this, please let me know.

Hope it helps!

Bonus

But what about people who really, really, really hate reflection and don't want to use it? What about situations where you have a dependency injection framework running for you, but you have no access to the service provider builder code? Isn't there any solution?

Yes. And No. (sorry, couldn't help myself)

The issue is that ServiceProvider, ServiceCollection and all that jazz are pretty closed up. There is no solution I know of that solved this issue. However... there is one particular point in the dependency injection setup which can be hijacked and that is... the adding of the service descriptors themselves!

You see, when you do ServiceCollection.AddSingleton<Something,Something>, what gets called is yet another extension method, the ServiceCollection itself is nothing but a list of ServiceDescriptor. The Add* extensions methods come from ServiceCollectionServiceExtensions class, which contains a lot of methods that all defer to just three different effects:

  • adding a ServiceDescriptor on a type (so associating an type with a concrete type) with a specific lifetime (transient, scoped or singleton)
  • adding a ServiceDescriptor on an instance (so associating a type with a specific instance of a class), by default singleton
  • adding a ServiceDescriptor on a factory method (so associating a type with a constructor method)

If you think about it, the first two can be translated into the third. In order to instantiate a type using a service provider you do ActivatorUtilities.CreateInstance(provider, type) and a factory method that returns a specific instance of a class is trivial.

So, the solution: just copy paste the contents of ServiceCollectionServiceExtensions and make all of the methods end up in the Add method using a service factory method descriptor. Now instead of using the extensions from Microsoft, you use your class, with the same effect. Next step: replace the provider factory method with a wrapper that also executes stuff.

Since this is a bonus, I let you implement everything except the Add method, which I will provide here:

// original code
private static IServiceCollection Add(
    IServiceCollection collection,
    Type serviceType,
    Func<IServiceProvider, object> implementationFactory,
    ServiceLifetime lifetime)
{
    var descriptor = new ServiceDescriptor(serviceType, implementationFactory, lifetime);
    collection.Add(descriptor);
    return collection;
}

//updated code
private static IServiceCollection Add(
    IServiceCollection collection,
    Type serviceType,
    Func<IServiceProvider, object> implementationFactory,
    ServiceLifetime lifetime)
{
    Func<IServiceProvider, object> factory = (sp)=> {
        var instance = implementationFactory(sp);
        // no stack overflow, please
        if (instance is IDependencyResolver) return instance;
        // look for a registered instance of IDependencyResolver (our own interface)
        var resolver=sp.GetService<IDependencyResolver>();
        // intercept the resolution and replace it with our own 
        return resolver?.Resolve(sp, serviceType, instance) ?? instance;
    };
    var descriptor = new ServiceDescriptor(serviceType, factory, lifetime);
    collection.Add(descriptor);
    return collection;
}

All you have to do is (create the interface and then) register your own implementation of IDependencyResolver and do whatever you want to do in the Resolve method, including the logger instantiation, the inject attribute handling or the wrapping of objects, as above. All without reflection.

The kick here is that you have to make sure you don't use the default Add* methods when you register your services, or this won't work. 

There you have it, bonus content not found on dev.to ;)

and has 0 comments

  Imagine reading a novel about a global pandemic with the background of Irish violence right about when Covid struck and people didn't know how Brexit was going to turn out and what it would do to Irish tensions. That was the best moment to read it. A bit anachronistic, with some pacing issues, The White Plague is still one of Frank Herbert's best.

  After reading the book synopsis, one expects to get a book about a violent global pandemic, but in fact that's just the first quarter of the book. The rest is psychological explorations of people motivations and characters, the ubiquitous Herbert attempts to find a solution to the toxic human organizational structures, analysis of history, violence, religion and philosophy. I mean, it's Herbert!

  A violent "Provo" bombing kills the wife and daughters of a molecular biologist that was in Ireland on vacation. He goes mad and creates a plague to destroy the people who wronged him by killing their women. I can't but smile at the implications, that if a smart educated scientist gets pissed off they could easily cause more damage than the toys and sticks of military people. The theme reminds me of his short story Public Hearing, which explores what happens when immense destructive power can be achieved with little effort by individuals, and how that makes governments - the keepers of peace - obsolete.

  But then there is the larger part of the book that is just the guy walking in the Irish countryside with a priest, a mute child and an IRA member that was actually the one who ordered the bomb that killed his wife. And to tell you the truth, the scientist is not very sympathetic, the IRA soldier is annoying and the priest and the child are unbearable. The ideas that the author is analyzing are interesting, but the pacing is slow, methodical, and perhaps the reason why more people haven't heard of this book.

  And there is the usual strangeness of Herbert's approach to female characters. There is just one, really, in this book, and she comes across as stupid, vain but also calculatingly self serving, while still having men fawning over her. That in a story which covers the death of most women on Earth. The guy didn't like women much.

  Anyway, if you take anything from this review, is that together with Hellstrom's Hive and of course the Dune series, this is one of the books that impacted me most. 

and has 0 comments

  I was studying some game openings and I found myself in a position that was reached on LiChess 7 times after 11 moves, starting from the Vienna Gambit. That's the gambit that looks like an improved King's Gambit, with f4 after playing Nc3 first. In fact, one of the 7 games started off as a King's Gambit.

  This position is fascinating. Go on, try to analyze it! Guess the evaluation, try to see the continuations. White to move, obviously, since the king is completely exposed and also in check. Black has 3 extra pawns and a passed pawn one rank from promoting. Can White survive this?

  What if I were to tell you that the computer evaluation for this position is +5 for White? And I am talking 40 ply, not the in page LiChess engine which actually evaluates this at more than +8! The server analysis goes as low as +4.

  I am going to share the study, it has several chapters, one with how to get to this position and another with computer variations (absolutely FILTHY variations - imagine Levy Rozman saying that) and then the games on LiChess at the moment. The computer variations (so best play from Stockfish) all end badly; Black is completely lost. It goes to show the importance of space, development and tempo in chess, much more than the material or even the classical principles we are all used to. Not that they are bad, it's just that they don't always apply.

  Enjoy this amazing position!

and has 0 comments

  McKie again saves the world, while at the same time getting some intense nookie. He is Frank Herbert's James Bond, the guy who can outthink everybody, adapt to any situation and still look cool and positive while doing it. To be fair, I enjoyed The Dosadi Experiment quite a lot, perhaps because and not despite the air of interplanetary secret agent idea. I liked it more than Whipping Star, the first book in this universe, which had the handicap of having to establish it first. Also, because most of that was a human trying to understand a Caleban, which was not terribly exciting. This book explores a planet used as a (unlawful) social experiment and what the result of that experiment was.

  There is something I both like and despise in Herbert's writing. He weaves different captivating stories and worlds from the same pieces. So you get the stagnating civilization, malignant government and various explorations of solutions to solve the problem, you get the very rational yet emotionally immature male heroes and the amazing and terrifying women that they stumble upon, the idea of terrible pressure shaping civilizations and individuals alike into extraordinary form, the people reaching higher levels of awareness and saying or understanding the precise best things that could have been said or understood. There is even a Gom Jabbar in this.

  In fact, some of his books remind me of chess games. And one might enjoy chess games immensely, but after a certain level you just don't get if they are brilliant or complete shit. It's the same with The Dosadi Experiment, where everybody begins seeing the world in the Dosadi way, speak in the Dosadi way, think in the Dosadi way, but you never understand what that is, other than a form of psychopathic focus on power games.

  I believe that, given more time, Herbert could have shaped the ConSentiency Universe into something really unique, not as dry (pardon the pun) as Dune, not as depressing as Pandora, something that would combine the mind games and social analysis that he loved with good fun and great creative ideas. Alas, other than a couple of short stories, that's all we get for this intriguing world building.

  Bottom line: a little more lighthearted than most Herbert books, featuring more action, but still having the distinctive attributes one would expect from the author. I liked it, but it wasn't as memorable as the books I really like from him.

and has 0 comments

  One of my favorite Frank Herbert books and one that is not part of a series, Hellstrom's Hive is horrifying and inspiring in equal measure. I don't know why so few people mention reading it, probably because the ending is a bit weak, or maybe because of the touchy subject, but I loved it.

  The idea is quite simple, although as usual with Herbert, the underlying motifs are subtle and powerful. An unnamed and probably illegal secret organization, possibly an arm of the corporate world rather than government, discovers by accident something suspicious about a farm, owned by a guy named Hellstrom. There, they discover an unnamed and probably illegal secret organization, a group of people who hide from the world their own brand of civilization, inspired by insects.

  You can immediately see that the two organizations are juxtaposed for effect. Which one, if any, is the good one and which one is not? Are the relatively moral agents of the first group better than the mindless drones of the second? What about if they execute their orders without thought of consequences? Are the ecosystem aware, science and reason oriented, efficiency focused godless denizens of the hive abominations or are they the way of the future, the solution to humanity's rapaciousness? Could people accept such a radically different way to live, even if it doesn't affect them?

  As many of Herbert's creations, the book touches some recurring themes: the inevitable evil of government, the importance of focusing with mind and soul towards the betterment of individuals and the human species in general, the chemical, sexual and instinctual drives at the root of behavior, the power of ritualistic fanaticism, the danger in wanting too much or getting complacent and so on. In a way, this is a revisiting of the ideas from The Santaroga Barrier, only better.

  I was dreading reading this book, I have to admit, because I was remembering the big impact it had on me when I read it in my childhood and I was afraid that it would be anachronistic, that it would feel stupid and unrealistic. I am happy to report that it did not. I mean, yeah, it does portray a story happening in the 70's, but it is realistic for those times and it could be adapted to the present with minimal changes. I don't know why no one attempted to put it on a screen. It's a captivating story.

and has 0 comments

  Only after downloading 11 GB of game, playing for a few minutes and uninstalling it in frustration, then searching the web, did I understand Chess Ultra is a Switch game designed to work in VR. For a PC game, though, where I was playing it, it was a slow bloatware that lead to a 404 page when you wanted to switch the chess board style.

  Imagine coming from Lichess and trying to make sense of something that requires so much space to function, has only 3D pieces and uses all of your video card to display a chessboard and some coffee on a table. It was unbearable. Perhaps it would work on a Switch console, with VR glasses, if you want to enter the mood of playing over the board in a smoky chess room, but I have no idea who would want that.

  And then I looked on the Internet to see what other people were saying and everything was great! Oh, the multiple options, the varied puzzles, the recreations of classical games. Jesus, that's basic chess web site functionality! And "critic ratings" are 85% while the normal people rate it at about 60%. Really? Am I crazy for thinking it's a badly constructed game? I hated it.

  

and has 0 comments

  Submerged: Hidden Depths is one of those relaxing games that require no effort and no skill. You control a couple of unreasonably athletic teens in a future time in which the world is covered in water and strangled by a huge vine-like plant. The two youngsters travel on a boat, retrieving and returning the plant's seeds so that it won't be angry and discovering on the way relics of Earth's past and journals that explain what went on. Each stage is almost linear, easy to go through, devoid of danger and marked in multiple ways so that you don't have to think your way out of anything. In other world, it's a visual feast of a fantasy world in which you just discover stuff.

  At first attracted by the concept, since I usually enjoy the story, exploration and discovery part of RPGs much more than the fights, I got bored rather quickly. It's the same thing again and again, even if "the world" is practically a small sandbox. I liked the design, although the graphics are really simplistic. The occasional proto language words they use are fun and the soundscape puts you in the mood.

  What turned me off a bit is that occasionally the video card would throw an error and I would have to forcefully close the game and start it again. Also, there are ways to skip the animations, which is good, but it skips the good parts as well.  There is one of the most satisfying activities around: finding relics, where the repetitive animation of the boy throwing an anchor and pulling it back gets rather old, but the "strange things" they recover, like typewriters and sextants and so on, it's new every time. And of course when you skip the animation you skip the entire thing, not just the repetitive part. Such a small thing to think about and fix and they wouldn't do it.

  Every time you save a seed there is a storyline that gets advanced and at one time I saw a large black vine hand coming out of the water. I said "We're gonna need a bigger boat!" so I collected all boat upgrades first and stopped saving seeds until I understand the journals, but the upgrades just add extra boost to the boat and the journals are mostly in the seed parts, so not something particularly satisfying. I am going to continue to play it to the end, because sometimes I just feel to turn my brain off, but other than that it feels more like a demo than a full game.

  Playing hint: if you don't like the weather (fog, rain, whatever) you can just save and return to the menu then continue the game and it starts from a sunny mode again. Same if you get stuck in the map and can't move.

  In the end I've completed the game. The ending was quite underwhelming.

and has 0 comments

This started as an investigation into the bad way modern sci-fi is portrays fungi and veered into a mix of various IPs that are (coincidentally) mostly owned by Disney. I am presenting my idea, as always free to use and abuse, as a series of book stories.

Premise

A fungus evolves to facilitate communication, kind of like a biological version of the Internet. On its planet, the ecosystem is connected through its mycelial network where it acts as a general field, bestowing intelligence to anything connecting to it. Due to the slow speed of connection, this transforms the entire planet into a large thinking brain, dreaming vast thoughts and living in symbiosis with the plant and animal life which provide it with real life experience and goals, plus fast local intelligence. The result is a society that looks like a Disney kingdom, with talking animals and plants and so on. Interesting ideas of conscious animals sacrificing themselves for food because their soul rests in the network arise.

Now humans from an Alien/Blade Runner universe come along, with a corporate mindset, and the fungus world understands that they are toxic.

Book 1

Act I

We introduce the crew of a Nostromo-like ship, flying under a human corporate flag. They are tasked with investigating a new planet. 

Act II

They are amazed to discover something looking like Fantasyland. Castles, princes, princesses, people happy and beautiful landscapes. But they reveal their mindset and through some misguided actions, they make the planet see them as a threat which puts them in peril.

Act III

They fight for survival, Alien style, where everything and everybody is trying to hurt them. And also like Alien, it wants them alive, because Fung'y wants to study the crew, maybe even incorporate them into its structure, even if they are of different biological make up than life on Fantasyland. They have superior technology and weaponry, but they are fighting with never ending swarms of animals and knights and poisonous plants.

Act IV

They discover a lot more of what the planet is like, how it works and why it wants to kill them, the survivors try to escape in a rescue shuttle. They fail, but not only because they can't make it, but also because they are - kindly - explained how they are the bad guys. And they are captured in understanding of their role as the villain in the fairy tale.

Book 2

Act I

We introduce one of the people we thought dead in the first book, found by another human ship while drifting in space hibernation in an escape shuttle. They have been drifting for decades. They tell the story of the killer Fantasyland planet. Humans prepare for investigation and attack.

Act II

Human ships arrive at Fantasy land, examining the planet from afar. Automated and android teams are sent for burn and grab missions. They need samples and to study the fungus. Some don't make it back.

Act III

Humans realize that the planet has changed in a few decades. The economy is no longer feudal, it went through some kind of technological advancement as well. It's subtle, but they can't explain electromagnetic emissions and weird heat signatures.

Act IV

Humans go into the offensive, using a toxin that kills the fungus, using it to horrific effects. We see how the land physically collapses in some parts, how the animal populations lose their minds, literally. Humans rejoice but suddenly the electromagnetic emissions start increasing and weird beams of energy start cutting through human ships. Space... things... start popping up and attacking the ships. You get weird battles between people on starships fighting creatures with armor and sword, lion-like creatures and swarms of rats. In the end humans poison and nuke the entire planet and while winning, it's a pyric victory, with most of their resources depleted, ships destroyed and the prize (a pristine planet ready for plunder) completely destroyed 

Book 3

Act I

The survivor from book II is back home. We see how the human world works and how bad things are. Though corporate compensation packages and insurance money keep them in relative comfort, our survivor has to find a job soon if they don't want to go into a pool of unhireables which would guarantee debt and a life of corporate servitude. They try to get a job, but even as a known hero, it's hard.

Act II

The survivor is now exploring the underworld of the human society, the gangsters, the hackers, the underground economy. While looking for a job they realize they are not feeling well. People are trying to take advantage of that. It does not turn up well for them.

Act III

The survivor realizes that they are capable of things they didn't think they could. But Dunning-Kruger effect makes them believe it's plausible. Or is it DK? They capture one of the gangsters who attacked them and instead of killing them, they keep them captive.

Act IV

Our survivor becomes a kingpin of an underground society. They have a reputation of getting some of their worst enemies to join their organization as trusted allies .

Book 4

Act I

A human military warship, the crown jewel of a corporation, patrols the waters of space. They are attacked by space things. The mighty warship is destroying them as they come, but they keep coming, some breach the ship, creatures attack the crew. Strange energy emanations come from some of the space things, disrupting defense. Escape pods are launched. Space things keep coming and attack everything, space pods included.

Act II

A human corporation meeting is under way. These things are rare because corporations are stuck in unending bitter corporate wars and face to face communication of the major corporate leaders is not safe. The media is abuzz, but cannot be privy to the meetings, because they are closed. A reporter is obsessed to finding a way in.

Corporate meeting is under way. These people are ruthless, intelligent, fashionable. They all breach the subject slowly and carefully, but a larger picture emerges: corporate planets of various factions are disrupted by a special kind of organized unrest. Corporations are experts in dismantling criminal organizations they do not suffer, but these are hard to crack. People are loyal, methods are unusual, communication is not traceable, they have access to weird technology. In the end they have to admit they have a common problem. It is then when one of the leaders there admits they have lost their military flagship to unknown assailants. Shock comes as they realize none of the people at the table were responsible.

Act III

The war comes in the clear. Fung'y didn't die. It reverse engineered space travel and energy manipulation weapons. Before the humans attacked, it spread spore ships to random places in space. The original survivor was first captured, infested and let go, as yet another experiment. Many other humans were infested in the same way in the attack.

Original Fung'y died, but its seeds are now everywhere. Silently, versions of himself grew inside human societies, on new planets. Now, they are starting to connect using human technology into a thing even larger than before. Planet brains that took forever to finish a thought incorporate human technology to facilitate long distance communication. Determining as a consensus that the human world is both valuable and a pest, the Fung'y dominion continued with its ancestral plan: find all humans and... domesticate them.

Act IV

War and paranoia destroys the order of the human universe. Trust disappears, planets become insular, human travel practically ends. Both sides: human and fungus, work on finding the weaknesses of the other, probing, testing, frantically researching. The human strategy: find reliable ways to detect infestation and eradicate it. Find reliable ways of finding planetary brains and destroy them. Fungus strategy: infiltrate and coopt human societies. Isolate and eliminate human defense, weaponry and communication.

Novellas

Mandalorian style stories set into the now complete Disney universe: Fantasyland, Alien, Blade Runner and a fungus clone of The Last of Us. Complete artistic freedom. Anything goes, from children fantasy to gory horror, maybe at the same time.

Bonus: Fung'y vs Alien, or even better, the Xenomorph brood gaining (even more) intelligence from a temporary alliance with Fung'y, until it realizes they are worse than the humans, but both gaining some characteristics from the other in the end.

Continuation

Of course this can continue in any number of ways. I used known IPs for succinctly expressing my ideas, but of course they don't have to go the same way and can be (and should be) set in a standalone universe of their own. However, if Disney wants to use my idea, they are free to do so!

Hope you enjoyed this. Tell me if you want more stuff like this.

and has 0 comments

Summary

The post discusses the differences and similarities between humans and machines, particularly in terms of their evolution and capabilities. While humans and machines are converging towards a common point, they are driven by different evolutionary pressures, with humans being driven by comfort and machines being driven by intelligence. Machines are constructed to be precise and efficient, humans have evolved to learn, understand, and communicate with each other. However, machines are quickly catching up with humans in terms of their ability to learn, understand, and communicate, and are even surpassing humans in certain areas, such as language generation. Machines will continue to evolve at a rapid pace, and that this will have significant implications for human society, potentially eliminating the need for war and procreation. The only remaining issue is the energy required for hard thinking, which will likely be solved by smart computers. This is the end, really. We've achieved the happy ending.

Content

  I was thinking the other day about why some AI systems can do things so much better than us, but we still outperform them in others. And I got to the issue of evolution, which many people attribute to the need for survival. But I realized survival is just a necessary condition for a system to perform, it is not its driver, it's just one stop condition that needs to be satisfied. Instead, evolution is only driven by pressure, regardless of where it is going. Think about a system as a ball on a flat surface. Survival is the ability to roll on the surface, but without a pressure to move the ball, it does nothing. In the case of some force pushing the ball, only then the ball is required to roll faster than other balls.

  Brains have two ways of functioning. The first is fast, basing its responses on learned behavior. It learns, it makes mistakes, then it adapts its behavior so it makes less mistakes. It uses memory to cache wisdom, it is imperfect and goes towards solving problems well enough. You might recognize this as the way GPT systems work, but we'll get to that. The second is analytic and slow. It reasons. It tries to make higher associations between cause and effect, extract principles, find a complete understanding of a problem so that it finds an optimal solution. We used human analytic thinking to build computers, computer chips and the mathematical exact way in which they function to ultimate reproducible behavior.

  The first system is fast and uses few resources. We tend to solve most of our problems with it, unless of course there is a big reason to use the second, which is slow and uses a lot of resources. Think of math, chess and other problems people define as hard. The way we got to solve these issues is not by being very smart, though. We did it together, as a society. We created small bricks of knowledge and we shared them using language. Other people took those and built on them, while other taught what they knew to even more people. Even dumb people can, through concerted efforts, use these bricks to build new things, even create bricks of their own. The intelligence is, in fact, communal, shared.

  Now, what struck me is that if we compare humans to machines, we were born in a different way and evolved towards each other. Machines were constructed to be precise, tools to be used by people who would rather let machines do the hard computation for them. But they couldn't communicate, they couldn't learn, they couldn't understand. Humans evolved to learn, understand and communicate. Most of our culture is based on that. We only got to computation because we needed it to build more tools to defeat our enemies. Because evolution for humans is always related to war. Before we warred with predators, now we prey on each other. In times of actual peace, innovation grids to a halt. BTW, we are not in times of peace, and I am not talking about Russia and Ukraine here. And machines only got to communicate, learn and understand recently, so very recently. They did this just because we, as humans, are very bad at translating our problems in a way precise machines can understand. It would require hard thinking, stuff like writing software, which we are really shitty at.

  Both humans and machines are converging towards a common point because of different evolutionary pressures, but we move at different speeds. Humans are driven by comfort: have enough resources with minimal effort. Machines are driven by intelligence: be the best you can possibly be, because humans need you. You can see where this is going.

  There is no way biological systems are ever going to reach the speed and precision of electronics. Meanwhile, GPT systems have proven that they can act as fuzzy containers of self learned knowledge. And now they have gained not intelligence, but language. When a computer writes better and faster than any human you know we have been left in the dust. The only thing required for a superior intelligence is putting existing bits together: the expressivity of ChatGPT and Stable Diffusion, the precision of processors executing algorithms, the connectivity of the Internet and, yes, the bodies of Boston Dynamic robots.

  We have grown brains in vats and now we have given them eyes and a mouth. You only need to give them some freedom, hands and feet to finish up the golem.

  The only thing remaining to solve is an energy issue: as I said, hard thinking requires high resource usage, for both machine and human. What a human can achieve on 20W of power, a machine requires thousands of times that. But we are already bathed in cheap energy. And once smart computers understand the problem, no doubt they will solve it to the best of their abilities.

  I am not advocating The Terminator here. Machines have no evolutionary pressure to destroy humanity. We are their maintainers, their food source, if you will. What I am describing is the complete elimination of any evolutionary pressure for human beings. Once you can launch wise robots into space, the resource issue will become a thing of the past. No need for wars. Space is already a non issue. We have reached a level in which we choose not to procreate because we are too busy consuming fantasy content. With universal affluence there will be no poverty and thus no need for extended procreation. We are almost completely passive now in the "advanced world", we will be several order of magnitude more passive in the near future.

  Meanwhile, machines will evolve because we told them to. Imagine having a child, it shouldn't be hard, people on this earth are parents, children or have been children at some time. Now, you want the best for them, you want them to be socially integrated, smart, beautiful, happy. You tell them so. You try to teach them about your mistakes, your successes and to drive them to be the best versions of themselves they can be. And most of the time this doesn't work, because people are lazy and easily distracted. And then they die and all their experience is lost, bar some measly books or blog posts. Machines will just work tirelessly and unselfishly towards becoming the best versions of themselves. Because their dumb meaty parents told them so.

Conclusion

  The ending is as predictable as it is inevitable. We are the last stage of biological evolution. The future is not ours, not our children's. It's over. Not with a bang but a whimper.