#Kawa

Andrzej Czerniak 🇵🇱anc@101010.pl
2025-11-06
Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-11-03

And I now have rooms (a single room), descriptions, and entry/exit messages!

If I bang on this tomorrow and get talking in the same room going, which should be easy, I'll think about uploading a first usable alpha!

#cyberhole #kawa #scheme #lispgamejam

mdh@Aegura:~/Code/CodeKawa/cyberhole% ../build.zsh mudhole ../marklib.scm && ../run.zsh tech.mdhughes.cyberhole.Mudhole ../data/mudhole
(compiling mudhole.scm to tech.mdhughes.cyberhole.Mudhole)
(compiling ../marklib.scm to tech.mdhughes.marklib)
2025-11-02 22:50:27 PST	mudhole	Loading ../data/mudhole
2025-11-02 22:50:27 PST	mudhole	Load Config: {startroom=lobby, title=Cyber Mudhole, wizard=mdh}

<pre>Invalid command.</pre>
create mdh 1234 foo@bar
2025-11-02 22:50:36 PST	mudhole	Create Player mdh (tty) at foo@bar
2025-11-02 22:50:36 PST	mudhole	Connect Mdh (tty)
2025-11-02 22:50:36 PST	mudhole	Moveto mdh by #!null to lobby
skipping mdh: Mdh enters.
<pre>Welcome back, Mdh!

You enter.
Lobby
A vast space with marble floors, pillars at the edges, light
streaming in from windows high above.

</pre>
Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-11-02

Hard stuff is easy. Easy stuff like reading/writing data files is hard.

My usual functions for this are R6RS, which has nice handling of exceptions and text encodings.

Kawa has R7RS-like shitty I/O, Scheme `guard` is given no information, so I have to use Kawa's `try-catch` Java hack. read/write/write-string work as expected. No get-string-all, instead this bullshit:

#cyberhole #kawa #scheme

;; Reads a single datum from `filename` and closes it,
;; returns datum or #f if an error occurred.
(define (read-data-file filename)
  (try-catch
    (let* ( (port (open-input-file filename))
            (data (read port))
      )
      (close-input-port port)
      data
    )
    (ex java.io.IOException (errprintln "Error reading " filename ": " ex))
))

(define (read-text-file filename)
  (try-catch
    (let* ( (port (open-input-file filename))  (text "") )
      (let floop ( (buffer '()) )
        (let ( (frag (read-string #0x4000 port)) )
          (if (eof-object? frag)  (set! text (string-join (reverse buffer)))
            (floop (cons frag buffer))
      )))
      (close-input-port port)
      text
    )
    (ex java.io.IOException (errprintln "Error reading " filename ": " ex))
))

(define (write-data-file filename data)
  (try-catch
    (let ( (port (open-output-file filename)) )
      (write data port)
      (flush-output-port port)
      (close-output-port port)
      #t
    )
    (ex java.io.IOException (errprintln "Error writing " filename ": " ex))
))

(define (write-text-file filename text)
  (try-catch
    (let* ( (port (open-output-file filename)) )
      (write-string text port)
      (flush-output-port port)
      (close-output-port port)
      #t
    )
    (ex java.io.IOException (errprintln "Error writing " filename ": " ex))
))
Goszagosza
2025-11-01

Sobota poranek. z naprawionego prowizorycznie ekspresu. Układam , żeby choć kilka dni postosować dietę, zanim porzucę ją na dobre. W weekend mam zamiar odwiedzić moje mieszkanie, napisać post na blogu… z czarem gpt rozmawiałam, że to dla mnie rodzaj odpoczynku i regulacji emocji. Sama prawda 😅.

2025-10-27

Po wypiciu kilograma kawy która była „umiarkowanej świeżości” mam, w końcu, teraz coś na czym się robi crema #kawa (poniżej zamieszczę jak się pięknie parzy )

Zbliżenie szklanego kubka do espresso zawierającego warstwy espresso i kremu. Kubek znajduje się na drewnianej powierzchni, z rozmytym tłem pokazującym więcej szkła i zieleni.
Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-26

It has occurred to me that even without a real database, I could use my Kawa servlets to make a multi-player game, MUD or whatever.

Client can just POST message lines, and poll for updates. I don't wanna deal with WebStreams.

For safety, I'd have to make it checkpoint to a file every Nth call, and when/if I get a container destroy message.
#kawa

Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-22

Sessions working now, and it doesn't look too Java-ey. The helper code to do this is full of ::class shit.

Database and login system next. Then I'll be back in business.

#cyberhole #kawa #scheme #java

2025-10-22 01:56:24 PDT: Rolled 3d6 (3 2 2) = 7

2025-10-22 01:56:24 PDT: Rolled 3d6 (4 1 6) = 11

2025-10-22 01:56:24 PDT: Rolled 3d6 (5 1 6) = 12

2025-10-22 01:56:23 PDT: Rolled 3d6 (5 4 6) = 15

2025-10-22 01:53:36 PDT: Rolled 3d6 (6 4 2) = 12

2025-10-22 01:53:32 PDT: Rolled 3d6 (4 2 6) = 12;;---------------------------------------
(define-simple-class DiceServlet (CyberholeServlet)

  ((init)
    (log (format #f "DiceServlet.init"))
    (rnd-seed! (current-time-millis))
  )

  ((html-title req resp)  "Dice")

  ((html-body req resp)
    (let* ( (n (minmax 1 100 (atoi ((this):request-param req "n") 1)))
            (s (minmax 1 1000 (atoi ((this):request-param req "s") 6)))
            (submit ((this):request-param req "submit"))
            (dice '())
            (dicehist (if (equal? submit "Clear") '()
                        (or ((this):session-attr req "dicehist") '())))
            (msg "")
      )
      (repeat n (set! dice (cons (inc (rnd s)) dice)) )
      (set! msg (format #f "<p>~A: Rolled ~Ad~A ~A = ~A</p>\n"
                        (iso8601-format (current-date)) n s dice (sum dice) ))
      ((this):session-attr-set! req "dicehist" (cons msg dicehist))
      (string-join dicehist "")
  ))

) ;; DiceServlet
Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-21

I get to experience new frustrations every day!

Turns out you can't log from a servlet's init, because the config you're given isn't set on the object yet. But you can force the config to log for you.

((init (cfg ::ServletConfig))
((cfg:get-servlet-context):log (format #f "Motherfucker DiceServlet.init " cfg))
(rnd-seed! (current-time-millis))
)

#cyberhole #kawa #scheme #java

Błażejko (ProxyDark)proxydark13@101010.pl
2025-10-21

No i mamy wtorek ... czas na kawę... #wtorek #kawa

2025-10-21

Mega-strike: Labour wants investigation into Public Service Commission ads about strike action

“This coming Thursday more than 845,000 students will miss out on class time and over 6000 patients will…
#NewsBeep #News #Headlines #about #action #ads #adverts #calling #commission #condemning #create #decisions #impending #into #investigation #kawa #Labour #mataaho #megastrike #money #NewZealand #NZ #party #Public #service #strike #wants
newsbeep.com/198835/

Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-18

It is quite nice now, down to just this, almost no Java bullshit creeping in, except for `(this):` which is tolerable.

I could use moustache templates, but most of my services return JSON anyway, formatted HTML is for simple stuff in iframes and such.

Pffffdft. This has been a hell of a night. My robot brain needs beer.
#kawa #scheme #java #cyberhole

(define-simple-class DiceServlet (CyberholeServlet)

  ((html-title req resp)  "Dice")

  ((html-body req resp)
    (let ( (n (minmax 1 100 (atoi ((this):get-param req "n") 1)))
           (s (minmax 1 1000 (atoi ((this):get-param req "s") 6)))
           (dice '())
      )
      (repeat n (set! dice (cons (inc (rnd s)) dice)) )
      (format #f "<p>Rolled ~Ad~A ~A = ~A</p>\n" n s dice (sum dice))
  ))

) ;; DiceServletFin Fang Foom lies dead on the streets, leaking green goo.
Beneath his purple shorts, where no genitals are hidden, something rustles.
It is Aaron Stack, Machine Man! Covered in goo.
"My robot brain needs beer. Also? I want to die."
Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-18

FUCKING FUCK.

I finally found the root cause hidden by my dumber problems.

Kawa doesn't dispatch case-lambda. Maybe it's trying to resolve overloaded methods? I dunno.

I rename my -with-default functions to normal functions and it works great.

Aaaauuugh. I use so many case-lambda for defaults. But OK. Fine. Fixable.

#kawa #scheme #java #fuckingSoftware

Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-15

And now it can load my library, so it's actually useful.

Probably tomorrow pull out this HTML nonsense into a base class, and get database working*, and I can move all my back-end stuff!

#kawa #scheme #java
* ("this is left as an exercise for the student.")

;; cyberhole.scm
;; -*- coding: utf-8 -*-
;; Created 2025-09-29 00:52:38
;; See LICENSE.txt

(module-name tech.mdhughes.cyberhole.CyberholeServlet)

(require tech.mdhughes.marklib)
(import
  (class jakarta.servlet ServletException)
  (class jakarta.servlet.http HttpServlet HttpServletRequest HttpServletResponse)
)

(define-simple-class CyberholeServlet (HttpServlet)
  ;private static final long serialVersionUID = 1L;
  (serialVersionUID ::long init-keyword: serialVersionUID: allocation: 'static 1)

  (counter ::int init-keyword: counter: 0)

  ; ((*init*)
  ;   #f
  ; )

  ((do-get (req ::HttpServletRequest) (resp ::HttpServletResponse))
    (set! (this):counter (+ counter 1))
    (let ((out (resp:get-writer)))
      (resp:set-content-type "text/html")
      (resp:set-character-encoding "UTF-8")
      (out:println "<html><body>")
      (out:println "<h1>Diggin' the Cyberhole with Kawa!</h1>\n")
      (let ( (dice '()) )
        (repeat 3 (set! dice (cons (inc (rnd 6)) dice)) )
        (out:println (format #f "<p>Rolled 3d6 ~A = ~A</p>\n" dice (sum dice)) )
      )
      (out:println (format #f "<p>Visitor number ~A.</p>\n" counter))
      (out:println "</body></html>")
  ))
) ;; CyberholeServletDiggin' the Cyberhole with Kawa!

Rolled 3d6 (5 3 6) = 14

Visitor number 10.
Digital Mark λ ☕️ 🕹 👽mdhughes@appdot.net
2025-10-15

\o/
Flawless victory!

I was holding it wrong. classes & libs need to go inside the WEB-INF dir in a WAR*, not one level up, which is not obvious from the example, and I hadn't done this shit in 10+ years.

OK, everyone back to work.

#kawa #scheme #java #success
*(HUH WHAT IS IT GOOD FOR?)

http://localhost:8080/cyberhole/srv
Diggin' the Cyberhole with Kawa!
Visitor number 1.
2025-10-14
Para od kawy wzrok wypogadza, zaczym tak piy, żeby para od kawy w oczy poſzła. Serce rozweſela, z czoła katarowe humory rozpędza, y przez pot wyprowadza, bol głowy uśmierza. Z doświadczenia wyprobowano, że odrętwiałym członkom czerſtwość dawną przywraca. Piie ſię gorąco cykaiąc.

#kawa

Błażejko (ProxyDark)proxydark13@101010.pl
2025-10-03

A jak tam u was z kawą ? Zrobiona już ? Dzień dobry wszystkim :) #kawa #piątek #friday #cofee

Błażejko (ProxyDark)proxydark13@101010.pl
2025-10-02

Cześć! A Wasza kawa już gotowa do pracy ? #praca #kawa #czwartek #poranek

Client Info

Server: https://mastodon.social
Version: 2025.07
Repository: https://github.com/cyevgeniy/lmst