Graphics? Check. And simple, top down, tilesheet or character maps work just fine.
Battles? Check. You can leverage anything from purely functional, object oriented, websocket, long polling, SQL, you name it. Whether you use 3 elemental types or flesh out everything from multiturn, semivulnerable, exp/leveling, it's all up to you.
Wanna just build an REST/GraphQL/gRPC API? Or a UI? PokeAPI is an opensource database of nearly all game data from moves, items, and species.
Pokemon is an endless, any-scope, extremely documented, opensource-rich field of exploration.
I'm not gonna write a compiler in Rust, and I'm not gonna write a web server in Haskell (reading between the lines the opposite is true).
So just for example
Kotlin => a quick web app or a mobile app
Python => rewrite some bash script I've been meaning to improve, or write some statistical analysis with numpy
In the process I get to learn a new domain at the same time, and get to see what that looks like when an ecosystem actively tries to make it easier.
Of course sometimes it's good to try to use a language for something it's not commonly used for, and find out how much programming can suck when no-one has worked on smoothing out the edges.
It's far from a true comprehension of the language, but it is really helpful to tackle problems that I've already done a few times in languages I am more familiar with to help relate concepts and highlight the differences.
It's also a nice touchpoint to look at general personal improvement at programming, since it's right at the point where it makes reasonable sense to use organizational schemes like design patterns and needs adapting for whatever language you're in. The first time I made it in high school was an utter nightmare that somehow printed to over 20 pages (I know better now), ended up multithreaded (early 2000s Java multithreaded), lacked many features like pause/titled screens, and had a memorable race condition where explosions could only start in pairs if they were both visible (so reserved top left of screen for that second explosion).
I’ll pick the popular web framework, database library, json library, etc. and try to build it. I might even look at logging. This will help me expose all their popular libraries and features that’s relevant for my day job.
Has a backend that consumes RSS feeds and builds a database of articles, a REST API that exposes articles, a web frontend that shows them, an iOS frontend that shows them, and an android frontend that shows them.
I've rebuilt every part of it multiple times in many languages - it's a project with reasonably constrained scope so you can usually implement any part of it inside a day or two, but it solves a real problem - I use it day to day to keep up with F1!
edit: I think the scraper is currently a .NET core 6 console app, the REST API is I think python, the frontend is pure JS, the iOS app is swift+swiftui, etc. Lots of variation.
- What can I use to display? Is it a native app interface, TUI, web based display?
- What do the collections look like in the standard lib and what operations can I do on them?
- How good is the multithreading/multiprocessing?
- What paradigm is the language in? (OOP, FP, procedureal, etc)
- What developer tooling exists for the language? Is there an LSP available if I want to use emacs/vim/vscode? Is there a plugin for IntelliJ? What's the debugger situation look like, or am I going to have to use print debugging?
- How does project/package management work with the language?
- What is the echo system like for the language
All of that is in service to building out the first bits of the game.
(also I am a backend dev)
It also helps to practice breaking a problem into steps as an AST is structured in such a way as to encapsulate distinct behavior within a node. Often this will result in using something akin to the Visitor pattern and this helps you further separate behavior from form.
I am a full stack senior dev, work often in Go or Node/JS when building services and React/JS when building front ends.
https://github.com/Sebazzz/Return https://github.com/Sebazzz/PokerTime
1. Find an interesting project that suits the language/framework and keep the scope very minimal so I can complete it in 2 days (weekend). I can always learn more doing a second or third project. But I find that I can maintain my motivation when I see results and complete a project.
2. Restrict the number of new technologies for the project to maximum two (best if it is one). When there are many new things, I find that it can be exhausting and I give up after just a couple of hours. So for ex: When I initially learned React, I didn't know GraphQL, so even if I see a case where GraphQL might be the best fit, I will use REST API. This way I'm not stuck on all fronts.
To answer the first question, there is no single project I build to learn every language because that becomes boring for me. I try to build different projects every time.
For ex: When learning React, I built a HN reader, Foreign exchange meme reaction, and an app where I can see the time of all my teammates spread across the globe (all completed and live). When learning ReactNative, I built a small Twitter clone (haven't published it).
[0] https://raytracing.github.io/books/RayTracingInOneWeekend.ht...
It’s quick but it covers string handling including some weird stuff, sockets, and networking pretty well.
I even do this with GUI programming as it involves callbacks.
My "hello world" project is almost always Conway's Game of Life, and I try pretty hard to follow the idioms of the language when I do it.
I like Conway's Game of Life because it's easy enough to not be too frustrating, but challenging enough to where you actually have to think about the problem a bit, at least if you're planning on following language idioms. Usually I just "render" to the command line, though occasionally I will get ambitious and figure out SDL or OpenGL bindings.
Admittedly most of my projects involve servers in some way, so after I've done the Game of Life, I usually start playing with the networking libraries like ZeroMQ and the libraries to call command-line programs, and I make a distributed video processor using ffmpeg.
This is how I started my career in the first place as a software engineer and this is how I continue learning new languages w/o the feeling to artificially build something useless
I usually start like that:
- add a mouse/keyboard emulator library, on the way you usually find out how good native system integrations are and how to integrate dependencies into your project
- write a brutally easy script of some mouse clicks/movements or similar to have something in place you can build on
- generalize the script
- make use of basic code features like functions, code logic, abstractions
- maybe add some math for screen resolution independent mouse movements ore more natural movements or typing events
- have some basic idea of concurrency by waiting a random time before input events
- how about adding openCV or a similar screen capture tool? now you can capture a single color indicating a specific event to make things more interactive- get more creative in what you want to detect
- figure out what are the limitations of the language of your choice, how many fps can you archive and what are the bottlenecks?
- when you are at this point you opened the door to an endless journey of adding more and more features and optimizing your code
the first steps are often just c&p from stackoverflow + some basic lookup from the documentation. with this approach you have a working prototype rather quickly and you are in full control on how fast and in what direction you want to go
by the time everything feels repetitive in what you are doing you probably already have a basic idea of the language and can decide on how or if to continue.
needles to say, don't spoil yours and others fun by applying this approach to PVP oriented games. also you will probably have a hard time since there are way more efficient ways + anti cheat tool will detect you
1. An implementation of Fisher's exact test for 2x2 tables. This adapts the algorithm from R's fisher.test() function, which was implemented with function closures for optimisation, which does not always map well to other languages.
2. A foreign function interface to the Rmath library. I have now done this for Standard ML (MLton, Poly/ML, Moscow ML, MLkit, SML/NJ, SML# and Manticore), OCaml, Ur/Web, Mercury and MonetDB. Code generation sometimes uses cpp, m4 or the language's tree and string facilities.
3. Discrete event simulation using message passing with an application to cost-effectiveness analysis. Someday, I'll get this published.
Both stacks are totally great and enjoyable btw, would recommend.
When I first meet a language I usually crack open the docs and then write a single micro project, like a BFS maze solver or a knapsack problem solver or something Advent of Code-esque, just to get to know all the primitives quickly -- different kinds of variables, arrays, dicts, control flow, closures, error handling.
Until I do that, and I mean truly do that, I am prone to all sorts of surprises when running my code and have little confidence.
Most recently I’ve done this with fp-ts (a functional programming library for typescript) and a wrapper around hledger (a plain text accounting app). Because the later is Haskell, I figured I might open myself up to a rewrite at some point in the future.
The goal is to learn how to create abstractions and how control flow works, once you got that down you can think freely and just code whatever you need.
When learning a new API just implement some basic program in it, taking input in some way and creating output in some way. Like click button to display a text, or take command line argument and write a file saying hello world etc.
Take for example Git. If you understand its internals well enough to build it yourself, then rebuild git in the new language. In the future, when you want to pick up yet another language, rebuild it again.
One of the reasons that I think it's extremely useful for a programmer to have at least one complex system that is well understood and implemented under their belt.
Every once in a while, I'll think "it would be nice if I could do X" and that's perfect project material that will keep me motivated.
Being older, for me this has the benefit of refreshing some compsci fundamentals while exploring the new language.
If you're a good pianist and you have to learn the violin, I think it's best to start with scales and arpeggios just like any other beginner, except you go faster because your existing knowledge transfers to the new instrument. Trying to make your way through Beethoven's violin concerto starting on your first day with the violin seems to me like a ridiculous approach.
e.g. I wanted to move from Flutter and Firebase to Fullstack JS. So I rewrote a 20k lines app in NextJS ( typescript and everything I wanted to try out ).
Not the best way to go if all you want to learn is 1 piece of technology though.
2. Implement ‘reduce’ from scratch.
3. Write a static site builder. This means I need to learn how to bring in libraries / packages, do some Markdown processing, do some templating.
4. Use a web app framework for the language to build a simple site with minimal interactivity, just to see how the language helps support the framework. I avoid client side (JavaScript) where possible as I don’t like working in that area.
5. Try building a couple of simple non-web GUIs. Buttons and lists, callbacks etc. Learning Swift meant doing quite a bit of this. Learning Python - just some messing around with PyQt to see if it’s fun and easy.
Not a dev, but used to be. These days I play with dev tools for fun, to spike stuff that might be good at work (mostly AWS based) and the occasional personal project.
Rewrote it in at least Java (applet and standalone), Z80 assembler, Pascal, PHP, Python, JavaScript, C - and from memory gave up and failed to get it working in 486 assembler and 68k assembler.
It's been at least 10 or 15 years since I tried. Maybe I need to see if I still have the chops to get it working on Arduino or RP2040 or something...
Having a young kid helps to keep me focused while I'm coding as I know my free time is very limited :)
When that fails, because there's no non-exploity solution ... I drop it.
Otherwise, next, I look for easy multithreading.
Then I look for ways of plotting pixels on an easily available canvas.
Then I code an effect.
The last new language I've learned was python. For that one it was different. With no experience in python specifically, I've asked the friend, who recommended it to me, to give me a problem and I'll code him a solution.
I'm an autodidact and generally don't like using tutorials, papers and whatnot. Google is all I need. He wanted a webscraper ... and two hours later, after lots of fiddling around figuring out how the language works, I was done.
Then I made an effect. It was slow. D'uh. :-)
I learn a new language/framework while trying to solve a specific problem. The latest I picked was Nodejs/Vuejs/Electron while building https://nocommandline.com. A year ago, I basically had zero to little knowledge about them but now I know a whole lot more.
Also, I'm not a professional developer. I'm a Product person who basically writes code to solve specific problems I encounter (at work and outside of work).
For a project though, I think anything that you know the domain of really well and are interested in so that you are happy to complete it/go back to it makes sense. I find I often like to build some sort of crawler (APIs or page data) that can then be consolidated and distilled into concise information.
I have a CLI app that I make that calculates microtonal pitch lattices. In a lot of languages, it ends up being a few hundred lines. I’ve done it in Rust, Clojure, CL, Scheme, Python, C#…
As far as frameworks go, I’ll reach for one if I feel like I need one. With web frameworks, I’ll do a GET and POST route to get a feel for the mechanics.
After several years of going in deep on the JS hamster wheel, I’m kinda done with it. I’ll jump into a SPA framework if I need one.
Then I move on to more complex parsing of text in the file.
I try to get this building cleanly and working on Windows, Mac and Linux.
I mostly learn domain-specific languages where the use-case is more given.
With Ansible I created scripts for bootstrapping VPS'es and laptops with dot-files and some suite of default programs, scripts for hardening OpenSSH. For jq I went to IRC and StackOverflow and tried to solve other people's jq problems. Many years ago when learning regex, I'd solve a regex quiz.
For front-end web-frameworks I usually create a tamagotchi or a questionnaire.
(I mostly do back-end, compilers and DevOps, but I'm full-stack.)
It also lets you evaluate any database drivers, which are one of the top 10 things I want out of any language I use.
I write 2...3 things over time: a photo copy tool that organizes photos off a camera card, a simple TCP server that spits out "Perhaps bonghits will fix my make file" or something similar, and then some kind of library, usually something that involves another library.
When exploring a library or domain, I generally go for something I can glean from examples, usually gluing two of them together.
That strikes me as an excellent idea: it’s a pretty small tool, but it is useful and has just enough complexity to test the language and its standard library. Note, however, that I have not done so myself!
My project of choice, for the last ten years, has been this little "toy" app: https://littlegreenviper.com/portfolio/nacc/
When I finally start learning SwiftUI, for real, I'll do a version of that.
I find that it is a good idea, for me, to always be writing for ship.
But yeah, 'hacker' exercises are a great way to get acquainted with low level code.
Hoping to try out Elixir for this year.
I also sometimes build Conways Game of Life in a new language for fun.
I usually build something that'll be easy and can be built in a weekend. Like with Phoenix, I'm thinking of building a multiplayer app since that's the best usage for this specific framework.
If it's a new language, I create a small CLI poker game. It allows me to feel out most of the important parts of a language, as well as how ergonomic it is.
New framework, usually a small wiki with a custom markdown parser. It lets me get dirty with routing, the database, rendering, user state, and injecting custom code.
I'm pretty old so I've been lots of different kinds of devs, last 7 years generally full-stack - heavy frontend focus.
What I try is to solve a small piece of the problem I am trying to solve to get more familiar with it before committing.
I've got pretty good experience with both, so knowing the algorithms is helpful. Where it gets harder isn't the language itself, but usually the idioms for expressing certain concepts.
For example, Rust doesn't have default parameters, so the builder pattern is pretty common.
https://ronreiter.medium.com/how-to-write-a-memcached-server...
For example, I had some ideas for adding interactions/animations to some charts and used it as a chance to try out Svelte
If it's server i usually do something related to the actual project though.
I'm an embedded dev.
First learning languages is both hard and easy. Mastering the syntax is typically easy, with the exception of languages that are just really complicated (Rust, C++, Scala) and "weird" in the sense that they just are very different from what you might know. But what is hard is absorbing the idioms and familiarizing yourself with enough of the frameworks and libraries that you need to get stuff done. That requires investing a lot of time.
Rust is the one that got away for me. I'm interested in it and appreciate what they are trying to do with it. I definitely sacrificed some time trying to shoot through tutorials, and tinker with it. But it just never happened. It took too long to get productive with it and I had no real business reason to pursue it.
All the languages I did master, there was a business reason and opportunity combined with an attitude of "how hard can it be?". That's my default attitude and you get surprisingly far with it. It's a naive form of deliberate arrogance. If you allow yourself to get intimidated by other people's code, it becomes an obstacle. I'll typically get dragged into some project with existing code and I'll just start making small changes and google my way through solving basic issues and try to figure out what the existing code does. The more you do this, the easier it gets. Just figuring out how the code works, how it is structured and why it is the way it is means you absorb things quickly. Ironically, bad code bases are easier to deal with as you don't get stuck assuming things are correct or even done properly. Just tinkering and fixing code like that is usually not that hard. Make a small thing a little better, repeat.
Some examples:
I learned Kotlin by simply using the Java to kotlin converter in intellij for a backend project. I had read about the language and had liked it enough that I just sat down and started doing it on a Friday afternoon. I started with my main Java project and converted a few tests. Two hours in I was sold on this. It was just too easy and I liked the code that came out a lot better than the original Java code (less verbose) and my tests still passed. A week in I just decided to go all in and convert any Java code I dealt with to Kotlin. Being able to go file by file and class by class really helped me here. It barely slowed me down. 3 months in I had tens of thousands of lines of code converted and I started getting good at it. That's now five years ago and I no longer deal with Java and maintain several kotlin OSS libraries. It's my main language.
Example 2: I inherited some frontend project written in Javascript. It was a messy code base and it was now my problem to sort out. After mastering enough Javascript to work with the code base to make simple UI changes (it's basically just Java minus a lot of features), it dawned on me that I needed to up my game to be productive enough to do some major feature work on that project. When you have a nice code base, doing more of the same is a good way to do this but this code base was so messy that that was just not a viable path. It needed to be fixed, and I just needed to figure it out properly and I could not start from scratch and had to keep the UI alive at the same time.
So, I started upgrading it to typescript to fix it properly and introduce some level of sanity. This was a really messy JS project (as a lot of these projects are) and I needed to get past the constant "WTF does was this even supposed to do" stupid hacks that I was constantly fixing and dealing with. This was an iterative process of figuring out what the original javascript did and why and then doing it properly in typescript. So, I was effectively learning two languages at the same time.
Typescript is very easy to master. Like Kotlin, this is by design and as mentioned, I like things that have a compiler. So same process: just start converting existing code by changing the file extension to .ts. The typescript compiler helped me fix numerous obvious issues by simply chasing down warnings and annotating things with types and introducing some structure. Over the course of six months most of that js code base got converted and fixed, rewritten, or discarded and I got quite productive with it and was able to add major new features. It was still messy but at least it was my mess and I could work with it. Typescript and kotlin are very similar of course. Would use it again but I actually prefer kotlin-js lately.
I've dabbled with Php, Go, Scala, Python, and Ruby projects as well with different customers and while not my main languages I can work with code-bases for any of those languages and have done some productive things with all of those.
And in the distant past I came across C, Gopher (a haskell predecessor), Self, Smalltalk, AspectJ, prolog, lisp, and a few other languages. Basically, the hardest part is not the syntax but wrapping your head around different paradigms like logical programming, functional programming, imperial, and OO. It's not about things being better but about things being different and appreciating different ways of doing the same things.
redis client
msgpack implementation
things like that