Making a Super Cal if Rage Will Stick Ex Paella Down Us

Something I am not good at

The paella must be possibly the worst national dish ever created, I thought to myself as I looked at the charred remains in my pan. It is as if the mind of some ancient Spanish conquistador, returned from his conquests abroad feeling hungry and unfulfilled, dreamt of bringing byriani to Spain, but in the midst of pillaging had forgotten to take culinary notes.

"How difficult can it be, Jose?" the weary warrior muses,
"Yeah, yeah, its just rice and meat, innit", says his Catalan colleague coming from the Spanish equivalent of Birmingham.
"We could use something flavourless, amorphous and chewy, like mussels, instead of meat",
"Whoaaah, nice,",
"And langoustines...",
"langa-what?",
"I know, right? Just throw them all in, don't bother shelling them",
"Raphael has some tomatoes he doesn't need for pelting passing pedestrians",
"Ahh...the flavours", fanning the flames as the smell of their concoction cooking brings back fond memories of far-away burning villages.

As I proudly presented my still smouldering efforts on the table, I am met with quizzical glances.

"What is it?" asked Mrs Saif, "I mean I can see what it is, but what is meant to be?",
"Its Spanish! Paella!", I exclaimed, "It's what Nadal, Ballesteros, and Ronaldo eat, guys. Come on, tuck in!",
The kids were not too sure, "Looks like your byriani" said one, encouragingly.
"Ronaldo is Portuguese," said another hoping to distract while passing her food to the dog who knew better.
"Look, why don't we order Mexican" said Mrs Saif kindly, "and you can try something you are goo.. err.. not so bad at."

Something I am not as bad at

Failure, I am used to. Under appreciation, I accept as the condemned accepts the noose. If I can divert my attention to coding instead of cooking, I may perhaps have less cause for despondency. But for me, the two streams of activity, cooking or coding, have the same triggers, and very often the same outcomes. Some one says: "You can't cook", outcome: paella. "You can't do this in Perl", outcome: more burnt offerings, sacrificing time and sanity, yielding an unrecognisable, unconsumable concoction for presentation to a community that never wanted it in the first place.

So when one person on Reddit presented a gist to use bash, ncal and Perl to create a week counting calendar on a terminal, I thought, hey this could be done in Perl alone.

calendar.gif

What's the point?

Here-in lies the problem with the irresponsible, belligerent coder, unsatisfied with mere re-implementation of another's code, who has to add his own flavours into the profusion of existing successful recipes. After all, MetaCPAN has no shortage of Calendar Modules, including Manwar's collection of excellent exotic calendars. EDIT: In fact Dave Cross' Calendar::Simple has an example which does exactly this.

I have started yet another project, this time a Calendar Application for the Terminal, which will (eventually) be interactive, customisable, use terminal colours for highlighting, allow adding and removing of events, will import, export and use standard .ics files, and create crontab lines. Or it might end up an exercise that once again reveals how inadequacies overcome aspirations.

Similar things exist (CalCurses, uses curses library) and (khal in Python) as well as cal and ncal, for those interested in such tools. Of course, I know my limitations, and this project will be Pure Perl. Pure Madness. Of course, if someone gets the title of this blog, somehow, it will prove to me that there are such other mad people around.

When Saif Met Sarah

The Perl and Raku Conference 2023

The Perl and raku Conference 2023 in Toronto was an event I was really looking forward to. A chance to rub shoulders with the giants of Perl and Raku, absorb insights and innovations of the nerdy Perly community...everything they said in the blurb. It was very well organised thanks to Alex, Sawyer, Makoto, Amber and Peter, herding an army of volunteers. Such a knowledge-intensive event should be recorded for posterity, trapping the wisdoms and inspirations from the wise and inspiring in the container that is YouTube.

Amber the jolly secretary also brought two additional support workers in tow. Logan, a bright, engaging young sprog immediately announced two critical facts when I first shook his hand. 1) that his younger sibling, Oliver, was extremely mischievious, and 2) he was an expert in drawing and making videos. He had in fact made 4 while I had to admit I had made none. Not wishing to be outdone by an 8-year-old, it was inevitable that I should volunteer to join the video committee; no sooner had I done this did I realise the complexity of the task at hand and my devastating lack of competence.

An operation run with military precision by Sawyer with extremely fine-grained attention to detail (he had 4 pages of narrow typed instructions labelled "Rough Instructions", just for pressing a button the video recorder), the mission objective being reliably capturing 3 days of talks running in 3 parallel streams, each talk in two separate media. The media would have to swapped and rushed off after each talk to the waiting hands of Alan with a production line efficiency that would put Henry Ford to shame, for uploading to various local and cloud storage systems. These would then be picked up by Josh our media manipulating moghul. Sarah, a trained nurse and naturally able to handle critical, life and death scenarios, absorbed the position of lieutenant and took charge. This is going to be easy, I thought.

IMG_5526.jpg

Do you ever get the feeling that perhaps you shouldn't have tried to compete with an 8-year old? I learnt the hard way. You'd think that as attendee and speaker at a computer programming conference, I would know how to use a laptop. I fumbled, panicked, had no clue how to handle the alien device that was Bruce's laptop. Bruce was Sarah's husband. Alan, ever structured in thought and deed, had developed a "system" and had to take over as I approached hysterics, unable to figure out the two finger click, drag, twist, and tumble that might do the trick without the macbook exploding into flames. It was at this point that Sarah put my hand in hers.

When Sarah took me by my hand, it could logically only have meant one thing. I knew Sarah wasn't blind, I mean she wasn't bumping into walls or anything. I also knew she wasn't a poor judge of character, after all she managed to snag Bruce. I must be dying I thought, and Sarah's nursing instinct must have taken over. Instead she reassured me, gently dragged me away from the computer and let Alan do what he did better than I could. It was agreed I would ferry the media back and forth, and try and minimise the damage I could inflict on the operations. She also discretely ushered in Jonathan who literally saved the day sacrificing himself by taking on the task of Sisyphus at the computer transporting hundreds of gigabytes of data, his fashionably manicured fingers a magical blur over the laptop.

Defeated, this change of plan worked out in my favour. I managed to meet some of the super-brains of the Perl community. Curtis "Ovid" Poe, was a quiet, wise man who listened more than he talked and quietly absorbed my incoherent mumbles as I spoke to him. David Rolsky was there towering over everyone in both stature and his comprehensive expertise in multiple languages, giving a powerful and compelling talk about Rust; he looked around wondering where the sound was coming from as I attempted to speak to his navel. Ingy, the eccentric entertainer, demonstrated his ability to speak in tongues, having memorised the entire Rosetta Code website. The energetic Will "The chill" Braswell was there with his super-chilled partner Bennie. He had menacingly trained his pet workstation to replace all other Perl programmers, at least after we found batteries for the remote control. We even had a remote talk by Paul Evans, who presented the most eagerly awaited feature of new Perl...a new way to do things even more differently than before. The White Camel award went to Mohammed for his magnificent project he had humbly created, The Weekly Challenge. Zaki demonstrated how cleverly he had ported his own cerebral connections into PDL. Sawyer, former Pumpking, gave talks to a full house, standing-room-only, which were personal, thought-provoking and insightful. There was even a quiz, I managed to get 4/30, beat that suckers! Indeed, everyone of the attendees and speakers were celebrities in their own right but unable to split myself in three, I was unable to interact with all. Listing all the talks and interesting delegates would be impossible; the meeting was packed, exciting and managed to deliver a rare combination of education, social awareness and fun.

After 3 solid days I left exhausted, satisfied and proud of being a part of this glorious community. As I type this blog, I realise how easily this group of strangers welcomed me, made me part of their family. I felt blessed.

Inevitable Improbabilities

Guys anything can happen. There is literally no way of avoiding something that you haven’t prepared for. So in the face of mounting anxiety over the huge number of unexpected scenarios that may be around the corner, what can you do? You can contemplate insulating yourself, try and minimise the hazards, control your environment to a fine level of detail so that the surprises are infrequent and hazards are mitigated. At work I am drowned in Health and Safety Guidance, IT security protocols, Fire Safety Training. This means that work is to a large extent a somewhat boringly protected environment for me, my colleagues and my patients. Yet, even this can not avoid surprises. So what about your home, sitting in front of your computer. All the protection provided by protocols here are more vague, less policed, seen more as guidelines rather than mandatory.

The worst enemy

Being left to your own devices is perhaps one of the most dangerous situations to find yourself in. I find it difficult to imagine there to be a more extreme difference between the personal perception of safety and the severity of potential calamities in these circumstances. It is therefore incumbent upon those with idle time, to utilise that time to create simulations to prepare for the unexpected apocalypse around the corner. The probability that one may find one’s self having become lost, ending up 400,000km away in an experimental lunar lander may be extremely small, but possibly not zero. There may be small risk that the lander’s automatic attitude and thrust controllers have become inoperative requiring manual control to land the craft in terrain that is not generally flat. Even if it is extremely unlikely, one might find this endeavour to be made more hazardous by previously undetected vacuum breathing aliens, also orbiting the moon. Got to be ready.

The right attitude

Rocket science this ain’t.

An orbiting landing module may have a transit roughly parallel to the surface of the satellite. In order to descend the lander would need to use thrusters to slow the craft facing away from the direction of travel; this decreases the forward motion, the craft descends to a lower orbit adding a motion vector in the direction of the surface of the planet, and gravitational forces start the acceleration towards the ground. to fast an approach makes the next burst of thrust directed at both slowing the forward velocity as well as the rate of descent. Once the forward velocity is reduced enough the loss of centripetal forces means the vehicle is now experience the full force of lunar gravity, and the right amount of downwards thrust is now required the safely land the vehicle

Earth’s last hope

The initial landing may hopefully avoid the orbiting space monsters; the craft is unarmed, as one might expect from rocket engineers who failed to consider the evidence from countless movies on this subject.. Whilst on the lunar surface I would need to build a regolith cannon to fight the aliens, whose next target would potentially be earth. Humanity would be counting on me to suppress this invasion or die trying. Wish me luck, guys, I am getting ready.

My Family and Other Fish (PerlayStation Part 2)

Faced with any problem, there are many potential approaches. This, I have realised, is amply illustrated by the members of my own family, further reinforcing the educational value of having one. I shall anonymise them for my own protection, and as a disclaimer also state that everything I say about them or anything at all is probably wrong. In fact I have already issued my daily, pre-emptive, unspecified apology to my wife. For me, game coding in Perl is no different.

Identify Problem

Take the aforementioned Mrs S, for example. Faced with a mildly unacceptable state of affairs, her approach is reliably consistent. A detailed root-cause-analysis invariably identifies the source of disquiet: it often comes down to something I did, occasionally something I didn't do, and on serious situations something I was possibly thinking of doing. Her problem can be retrospectively solved if only she had picked any of the better looking and supremely solvent alternatives available to her. My fault then, for choosing the terminal to program Perl Games in. This “blame someone” approach never solved anything, but in difficult situations diverts attention, explains failure and justifies expenditure on jewellery, home decorations, the plumber, or in the case of software development, discarding previous knowledge and using a more popular, fancier, methodology like the neighbours.

Consider Ignoring It

My rather chilled-out older daughter on the other hand handles difficult problems with eminent ease. Her energy-efficient solution is simply to ignore them, saving her time, expense and effort. "Dad, it is only your problem if you see it as your problem." In reality, many problems have always existed; they are not created de novo. They don't have to be your problem, and the world will keep turning, and you will find ways of doing without. Who needs your games? Why do you do open source? Why in fact, do anything strenuous at all, one might say. Perl was never a powerhouse gaming tool, and terminal is not where one looks for arcade thrills given technologies offered by graphical tool-kits and modern browser engines. But one makes games for many reasons. In making games you discover how things work, you learn strategies, transferable skills, and who knows, maybe give fun to others. Critically you develop tools that allow you to make games and practical utilities easier. Indeed, game coding is a diversion, not the end-game for me. The tools one creates to help game development may also help in other projects.

Unexpected Benefits

I do have another hare-brained offspring, a delightfully positive and more energetic individual whose attention is devoted to exclusively herself and her friends. There is seemingly nothing she can not solve by merely fluttering her eyelids and exuding praise, and at the same time getting a profitable outcome. “Oh daddy, those socks go so well with your sandals, but I have nothing to wear for the par… study-session this evening, can you please buy me a <insert-any-item that-could-not-conceivably-improve-grades>, PLEASE???". In reality coding without feedback, whether positive or negative, is difficult. One needs motivation, a second pair of eyes to affirm or maybe redirect thoughts, and recognise connections that may not at first glance be apparent, and that motivation is by definition outward looking. Certainly that motivation factor may be driving secondary gains for other people, but that by no means diminishes its value. Who knew that roller skates actually help effective group-learning?

So the resultant path that Term::Graille has taken is this. It avoids the fancier toolkits that rely on libcurses or libtickit. It starts off as a graphical tool for a non-graphical interface. For practical applications it emulates real-time interactivity (instead of using things like libev) for an environment that is principally asynchronous using Term::Graille::Interact. This is inevitably weak and has to be to be stressed to to become optimised, and game development perhaps allows this stress, highlighting failures in other existing code. Just developing one game is a dead end, however and the diverse set of problems one might face requires more specialised assets. Term::Graille::Sprite, like my daughter’s roller skates, does not outwardly have any of the features that will be required for serious, useful applications. But who knows, it might reasonably stress the platform and may offer secondary entertainment for others.

Term::Graille::Sprite

So what is a $sprite? A Term::Graille::Sprite object which can have a {shape} , a {pos}ition on a screen, and a {vel}ocity. {vel}olicity is a matter of displacement over time, and Term::Graille::Interact, the time is represented by the refresh cycles for the keyboard read routine. The updating of the sprites may be prolonged by skipping a number of updating events. Motion is simulated by blank->()ing a sprite current position and re-blitting the image on the screen. It may interact with other sprites, e.g. collide->($another_sprite) or the environment e.g. edge() or with the user (via an addAction() on Term::Graille::Interact. We may have multiple sprites and these can be handled as a group of sprites, and a SpriteBank object is also provided, that keeps a store of these groups of items, updating them automatically each cycle as needed, or removing them if set to be {destroyed}.

my $spriteBank=Term::Graille::SpriteBank->new(); # store sprites
my $dir="./sprites/";   # path for predefined sprite shapes
my $bat=new Term::Graille::Sprite(data=>[[("█") x 6]],pos=>[20,0],
   bounds=>[1,14,60,0]);   # creating a bat
my $ball=new Term::Graille::Sprite(pos=>[20,3],vel=>[1,1],
   bounds=>[1,14,70,-1],skip=>6);    #  default shape is ⬤ 
$spriteBank->addSprite("player",$bat);  #  Adding $bat to  spriteBank
$spriteBank->addSprite("ball",$ball);    #  Adding a ball

One imagines in the future, one would include animations, physics (e.g. mass, acceleration and gravity). But what is clear is that in developing games, we find multiple failures in Term::Graille. Glitches as the drawing application plots off screen or experiences an error in data supplied. These should be cleanly handled, and one gradually makes adjustments for this, all the time hoping that these changes don’t break previous applications. Breakout is a prototype game that uses Sprite.pm

Inconclusion

My goldfish, Goldzilla, on the other hand has a much wiser outlook to my life’s difficulties. She recognises my flaws and chooses to ignore them. She appreciates my problems, sympathises, listens calmly to my rants, but only ever offers advice when asked. She never showers me with praise to get a new aquarium ornament and appears to mouth out Perl code to herself, if only I could hear this stream of wisdom. Here is the mainstay of problem solving. You are either provided with the tools to solve them or you make the tools yourself. The majority of useful tips will remain unheard, but they do exist and you have to listen closely…and use your imagination.

Done before, Done better, Done again differently.

A Fool's Errand, and Quantum Theory

It is my firm belief that every thought or idea that you or I have, has been had before. On the balance of statistics, the chances are that those that had these ideas handled it better, and have developed more powerful utilities to exploit these innovations. One therefore has a few possible options, when thinking of creating a solution to a problem. The first probably is to look for other published solutions and use them; these may be more mature, tried, tested and optimised. The second is to go ahead and implement another idea, foolishly perceived as an innovation, leading to a proliferation of methods duplicating, triplicating existing work, in the end producing a half-baked distraction.

Statistics indicate that someone will take that path of the fool. I am not going to argue with Quantum Programmodynamics; if it has to be someone, let it be me. Interaction in console applications may involve the ping-pong between a script and STDIN. It may be more sophisticated using Curses::UI. This is established, used for heavyweight applications and has a superb feature set. It could be more modern using Tickit by Perl's resident genius and author of over 235 Perl modules, Paul Evans; powerful, versatile, event-aware and handled in a Perlish way, Tickit is the API for the future of Perl console applications. Or one could try and invent something different. Not better, not more powerful, not more elegant. Just different. Why? Quantum, that's why.

There may be reasons other than pure bloody mindedness or foolishness for doing something differently. Indeed, perhaps the only way to learn to appreciate the right way, is to do the wrong thing. Honestly.

Interactive Applications with Term::Graille

Term::Graille offers pseudo-pixel graphics to the standard ANSI console, now is acquiring interaction tools. Interaction is handled primarily by the Term::Graille::Interact tries to to remain as "Pure Perl" as possible, and minimise reliance on external libraries. Interaction is via a keyboard, and thus uses Term::ReadKey. Rather than using libev/EVent, it relies on querying the keyboard every so often (default every 50 milliseconds) and dispatches predefined actions depending on the result...a rather old-fashioned way of doing things

One adds key-triggered actions, using addAction(), for each key of interest, passing it a subroutine reference and a description. One can also add various widget objects which temporarily override these actions when they are active using addObject(). There may be actions that occur when without a key press. These can also be added using updateAction().

The best way to demonstrate this is through game development. Term:: Graille's graphical capabilities combined with interaction equals a simple gaming platform. Games may need Sprites, and a Sprite Maker application can also demonstrate interacting capabilities. A glimpse of an early version of such an application was seen in a previous blog post, and discussed in more detail later.

Invading My Space

One simple game is Space Invaders. Shapes are loaded. Sprites are created with shape, location and velocity, and stored in an array. Some move by themselves, others move on user key-presses, others are generated, do their thing and vanish. Our defender's motion uses arrow keys. The aliens and the rockets move autonomously and the graille canvas is updated at regular intervals. (Fonts, Sound and collision detection can be subject of later scrutiny).

One creates an interaction object, adds actions addAction() triggered either by a key, or spontaneously every cycle (updateAction()), and then gets it running.

my $io=Term::Graille::Interact->new(); # a new Interact Object
$io->{debugCursor}=[22,45];            # output for debugging

$io->addAction(undef,"[D",{note=>"Move Left ",proc=>sub{
$defender->{x}=$defender->{x}>=1?$defender->{x}-1:1 }} );

$io->addAction(undef,"[C",{note=>"Move Right ",proc=>sub{
$defender->{x}=$defender->{x}<=65?$defender->{x}+1:65 }} );

$io->addAction(undef,"[A",{note=>"Fire      ",     proc=>sub{
push @missiles,{sprite=>"patriot",x=>$defender->{x}+4,y=>1,dy=>1};
$beep->playSound(undef,"A#1");}}  );

$io->addAction(undef,"p",{note=>"PAUSE ",     proc=>sub{
    $stopUpdates=$stopUpdates?0:1;}}    );

$io->updateAction(\&update);  # this action is executed every read key cycle
$io->run();              # this starts the interaction.

This can yields the interaction component of a simple test 1st game for the PerlayStation Terminal Games Console. There is prior art, of course: these are better than mine. Here is one by a Perl Monk called domm who also did a version using SDL and one in Tk by CECALA

invaders.gif