人生 オープンワールド 何がおもろい

オートチェス おもろい ローグライク おもろい

 The Last Flame がオモロすぎる。1月にしてGOTY。もう今年は要らない。2024とかいう偶数まみれなのに2で3回割ったらクソキモい半素数に衝突する年は終わりにしてオートチェス暦5年ということにしよう。いいよね。いいよ。あり。

 そんなわけでオートチェス暦5年1月にリリースされた Palworld についての話題がゲーム仲間あいだで尽きない日々、実際おもろそうだのおもんなそうだの色んな予見がある中で、身近なフレンド間で「この手のサバイバルゲーに食傷気味」的な意見がそこそこある。

 

オープンワールド おもろかろう

 自分もちょっとわかる。古くはマイクラや 7dtd に始まり、Valheim やら ICALUS やら RAFT やら Sunkenland やら色んなサバイバル・クラフト・オープンワールドゲームが矢継ぎ早にリリースされ、サバイバルってだけでまあまあおもろいのでとりあえず手を出してきた人がぼちぼちいる。マルチプレイだからと、時々に誘われてなんとなく遊ぶことも多かった。

 食傷、というか、この手のゲーム、人によってはかなり消化不良になりやすいのは明確にあると思う。

 コンテンツ量が多くて遊び切れない、マイルストーンはあるけどメインストーリークリアみたいな「やったった感のある目標」が薄い、初手から出来ることが多いのでゲーム体験がストーリーとして思い返しづらい、マルチプレイで時間が合わないのでじわじわ自然消滅しがち、あとそもそもアーリーアクセス時点の未完成品を遊んで「またいつか遊ぼう」の「またいつか」が二度と来ない、とか、いろんな理由で、これらのオープンワールドゲームを遊んだ体験の記憶自体がなんとなーくモヤってきている、のではないか。自分はちょっとそうだ。

 なんかオモロそうだけどどうなんだろう、みたいな歯切れの悪い感情がうっすら湧くのはそのせいかも。

 で、多分触ったらそんなん関係ないくらいおもろいんだと思う。その時は。だからつまり、似たようなゲームを思い返してモヤるこの心の動き自体がゲーマーとしては老化チックである。新しいゲームを遊ぶたびに記憶は消そう。

 

拡大 おもろい

 けど、そんな話をDiscordでしていた時も自分は言ったのだけれど、俺は数字が大きくなればおもろいから多分Palworldも純朴におもろいのだと思う。The Last Flameがオモロすぎてまだ遊べていないが。ヤバいんだってThe Last Flame。バフを付与するドローンが20体くらい召喚できるし、クリティカルダメージは1000%を超えるし、魔法攻撃力が4000を超えるし、ドラゴンの攻撃速度は36000%を超えるし。数字が大きくなれば面白い人間にとっては人生よりおもろい。人生の数字はこんなに簡単に大きくならないので。

 幸い「Palworldやりたすぎるけどサーバー落ちまくってて遊べない」という目に遭わずに済んでいるので、ほとぼりが冷めたころにガッツリ遊ぼうかと思う。おもろいゲーム多すぎる。人生おもろい。

トロ火のジェネレータ 燃やして走れ

 最近なんかすごく、謎のモチベーションに支配されている。これは結構おかしなことで、別に普段より上手くいっていることなんかただの一つもなくて、たとえば一年前を思い出しても、その時も今もそんなに変わらず充足した毎日を過ごさせて頂いているはずなのだが、自分の内燃機関が定速で回り続けている。取り立てて暇でも忙しくもなく、寂しくも一人になりたくもなく、特段の変化はないはずなのにここ1-2か月ほどやる気が消えない。いつもは1週間も燃えれば俺のやる気なんてすぐ鎮火してなくなるのに。

 原因は分からないが、これを機に仕事周りの色々を見直してみたり、耳鼻科に行って鼻炎の診断を受けて薬をもらったり、そこそこ仕事が忙しい期間なのに親知らずを抜きに行ってみたりした。この炎が消えた時の自分の回転効率を上げてみようと、そういう企みの一環として。人間の心には炎があって、きっとそれは明滅しているので。

 そういや自分の心の炎は何だろうっていうと、燃え始めて30年近く経っても全然謎である。大概のことを面倒がるし、野心もそれほどなく、投信や預金の口座残高を眺める趣味もないし、食欲もつまらないほど格別にない。俺はなんの欲のために生きるのだ、と悲観するほど日々の望みがないわけではないけれど、危険そうな道の先に何かが見える時に、それでもその道を通りたくなるような何か、というのが、自分にはそんなに無いなと思う。だから多分、自分の心に炎があったとしても、それはめっちゃトロ火。

 強いて言うなら人が好きな方だとは思う。自分のことを知っていてくれる人のことは大体好き。これは何の深い謂れもなくシンプルにそう思う。そして、仲良くしたいと思っている人と仲良くできない時の心的ダメージが、他の同系統の欲求不満と比べた時に割と大きい気がする。仲良くしてくれてありがとうございます、みなさん。

 つまり俺の心の炎は友人です、って、そんな人間の心はきっとそんな一対一対応の簡単なプロパティで動いているものではないので多次元のヒエラルキーがあるんでしょうが、自分にとってそのヒエラルキーのそこそこデカいところにいる「友人」にまつわるダメージを最近負っていないから、割とモチベーションが消えていないのかも、とこれを書いていて思った。Twitter はやめて正解だ。ここだけの話、あれは俺のような人間にとっては時折「仲良くしたいけど仲良くなれない人リスト」になって襲い掛かるのだ、メンタルの調子が良くない時には特に。

 そういう、心のジェネレータの火を陰らせるようなダメージを負ったとき、我々は大体直視するのが辛いので半分くらいは他の何かのせいにして愚痴でパージするのだが、それもぼちぼち上手くなってきた気がする。アンガーマネジメントというか、アンガーじゃないな、落ち込みマネジメント。人によっちゃアンガー駆動型ジェネレータを積んでいる人とかいるらしいが、そうではない我々は適切に処理をせねばならないのだな、と思う。間違っても周りに当たったり環境のせいにしてはいけない……とは思うけど、それを繰り返しながらとりあえず炎だけは絶やさずに前に進んでいる人がいたりして、そばで見守りながら良いバランスで付いて引っ張っていく人がいたりするのを見ると、人間そんなもんだなと思いもする。

 人それぞれのジェネレータがあって、人それぞれの EN 負荷限界があって、抱えられるだけの武器を両肩両腕に積載して、体は闘争を求めるんだろう。俺の炎じゃ頑張っても RANSETSU-RF くらいしか積めないけど、反動制御が低いし良いんだ。そういう話でした。

やさしい麦茶のやさしさは俺だけに微笑まない

 別に外ではお酒やコーヒーも飲むが、ふだん自分は家ではやさしい麦茶しかほとんど飲んでいない。ずっとamazonの定期便を依頼していて、2週間に1回、2Lが18本ずつ置き配で届く。

 気づけば玄関前に大量の麦茶が届いている、という生活にすっかり慣れ切ってしまっているわけだけれど、当たり前ながらそれらを届けてくれている人がいて初めて、引きこもりたる自分の生活は成立する。ヤマト運輸amazonUber Eatsなどの個人配達員の方々の存在がなければ我が身は砂漠となってしまうだろう。ただでさえ外に出ないのにこの連日の猛暑に晒されてはきっと生きていけない。

 

 しかし、どんなに外に出なくても、猛暑の影響は避けられないもので。というのも、2Lの麦茶のペットボトルを机の上に出しっぱなしにしていると、あっという間にぬるくなってしまうのだ。ぬるくなったやさしい麦茶。形骸化してしまったやさしさ。目線の合わない感謝の言葉。もはやかなしい麦茶。

 

 で、これを買った。無印良品の保冷ペットボトルホルダー。

 500~650mlのペットボトルを、ボトルごとそのまま入れてフタを閉めるだけでペットボトルがぬるくなりにくくなる。結露も起きないし、こまめに洗ったりしなくてもそんなにいい気がする。めちゃくちゃいい。すごい。ニトリや各種アウトドアメーカーからも似たようなのが出てるらしい。

 アウトドア用品として紹介されているくらいには保冷効果があるので、自分みたいにデスクワーク(ゲーム)のお供として飲み物を置いているだけの人間にとってはその効果は絶大そのもの。試しに500mlの紅茶やらカフェラテやら色々入れてみたが、一生冷えている。とても幸せな気持ちになれる。

 

 これをきっかけにして、amazonの定期便の内容を2Lペットボトルから小さいものに変えた。2Lのものを解約して、新たに定期おトク便をスタートする、という流れだ。こうしてかなしい麦茶は幸いの麦茶になるはずだ。はずだった。

 

 そして、定期便の初回が昨日届いた。無事受け取ったわけだが、どこか違和感があった。なんだ、と思ったが、アレだ。いつもの配達員さんじゃなくなっているのだ。

 あの人には「いつものようにドア横にお願いします」すら要らなかった。なんならあの人最近こちらが何も言わずとも「ドア横に置いておきま~す」と言って帰っていたのに。今日はインターホンが鳴ったので自分は外に出て「ここにお願いします」と頼んだ。それはいい。それは全然、もちろん、初めての人にはお願いするのが筋なのだから全然いい。

 俺はあの配達員さんに最後にお礼を言っていない。いや、住所が変わったわけではないのだからそのうち同じ人が来ることもあるのかもしれない。今までも、たまに違う人のことはあったし。ただ、もう二度と来なかったらどうしよう。全然顔も覚えてないし知らないけど、あの人はもう2年くらいは我が家に麦茶を供給し続けてくれていたのだ。我が家はあの人に支えられていた。「あの人」って、「彼」だの「彼女」だのにしようと思ったけど性別も自認も全然わからんのだ。書きようがない。

 

 別にめちゃくちゃ執着するわけでもないけれど、めちゃくちゃ執着するわけでもないけれど伝えそびれた感謝、という概念がかなり寂しい。

 去年から行っていないあの美容院の美容師さんも、引っ越し前の家の近くのあの吉野家の店員さんも、すごくお世話になって顔も覚えられているのにお礼の挨拶もしない、というかしないよな、みたいなことが多くて、別にしないならしないでいいんだけど、結構そういうの寂しく思うときがある。

 

 まあ言うても、俺一人は彼らスタッフにとって掃いて捨てるほどいる客のうちの一人であるわけで。よくあることだし、気にしちゃいないだろう。気にしないでいてくれ。けど、ほんと、ありがとうございました。

 

 こういうことがある度に、感謝は日ごと伝えておくものだ、と思う。感謝や賞賛はインスタント呪文だけど、ソーサリー・タイミングで唱えておかないとチャンスを逃すときがある。マナが余ったら唱えておこう。

 感謝を唱えられるくらいのマナは残しておこう。やさしい麦茶になるために。

外付けSSDエンクロージャー導入

我が家のドライブ事情

 自分用のデスクトップPCは、今使っているものでたぶん3代目になる。

 

 1代目は確か、高校に入学したての時、Minecraftでちゃんと遊べるように買ってもらったもの。スペックとかはあんまり覚えていない。当時はノートPCでマルチサーバーに出入りしていたのだが、そこには良く面倒を見てくれるやり込み勢の友だちが居た。

 彼はとても親切に、彼の建てた小麦農場の横の土地を譲ってくれた。しかし、その建築上限いっぱいまでの高さの自慢の小麦自動収穫タワーに近付こうものなら、冗談でもなくFPSが2か3くらいになっていたのだ。めでたくデスクトップPCを手に入れて入った自分は、その時初めて、小麦タワーと自拠点の間にケーキの差し入れをたくさんしてくれていたことに気がついた。なんせ、描画距離を最短にして近付かないようにしていたから。

 そんな1代目が起動しなくなった大学3年生の頃、BTOで2代目となるデスクトップPCを買ってもらった。データをサルベージするため、1代目のデータドライブに使用していたHDDをエンクロージャーに詰め、外付けHDDとして刺した。当時のCore-i5にGTX1060を搭載したもので、ゲーム用途ではかなり満足に使えていた。とはいえ、オーケストラの打ち込みなんかはi5では荷が重くストレスだった覚えがある。

www.youtube.com

 Hungry Summonersで書かせてもらった《Hammering Out》は2代目のPCで制作したものだが、あのくらいのトラック数でも重くて、ループ素材のレンダリング後にフリーズを行った際にエラーを吐き、ループトラックは二度とMIDIで編集できない遺跡と化してしまったのを覚えている。

 そんな問題を解決すべく、2019年の冬に初めて自分のお金で購入したのが今使っている3代目のフルタワーPC。i9-9900KFにRTX 2060 SUPERと、当時にしてはかなり贅沢にカスタマイズしたと思う。使わなくなった2代目のHDDは、なんだかもったいないのでフルタワー内の余ったベイに串刺しにした。メモリを増設し、GPUを3070にアップグレードし、3年半たった今でも割と問題なく使えている。

 

 ……今でも使えている、のはいいのだが、1代目のHDDのエンクロージャーも、2代目のHDDも、あとから買い足したHDDもSSDも、どれもこれも今のPCで元気に稼働している。

 つまりこう。もうどれがいつからのドライブなのかさっぱり分からない。いちおう、データドライブの移行が終わるたびに「この使い終わったドライブはいつ飛んでもいいように○○しか入れないようにしよう」と決めているが、その○○の候補が沢山あっていつどれが飛ぶかわからない。怖い。

 しかも次にPCを買い替えたとき、自分はこのドライブを全て4代目に持っていくのだろうか。5代目は? 6代目は? ……そのうちHDDが腐ったことにも気づかず刺しっぱなしにして、自分のPCはゾンビに侵蝕されてしまうのではないか。

それは嫌だ

 PCがナイトメアダンジョンになると困るので、解決策を模索した結果、自分にとってちょうどいいのは「めちゃくちゃデカい外付けストレージを作ること」だと判断した。

 PCを買い替えても刺すだけでいいので、データ移行の面倒さが軽減できる。NASも選択肢にはなったが、ほとんど家にいる自分にはあんまり必要なさそうだった。現在進行中のプロジェクトは大体Dropboxの同期保存をかけているし。高いし。

 というわけでTR-004にWD Red Plusでも刺すか、というところまで決定。めんどいので計画出来たら放置、をしていた。

突如訪れたプライムデー

 ボーっとしていたら急にプライムデーが来た。なんでもかんでも安くなってるんだしHDDも安くなってるだろ、と思ったらそんなに安くなってない。なんだ、Kindleでも買うか。とKindleだけ買って満足していたが、ふと思い立って見たら4TBSSDが6TBHDDと同じくらい安くなっている。

 びっくりしてWD Blue 4TBを4つ買った。

届いた

 そしてこう。せっかくだからRAID 5。あんまり深く考えていない。

 刺して読むだけでいいと思っていたら、勝手に「記憶域プール」なるものが誕生していてよくわからず手こずった。ラッキープールは好き。

 記憶域プールとはなんぞや、ストレージを俺の知っているやり方でフォーマットさせろ、と思いながら色々やっていたらまあできたのはできたが、なんだか回り道っぽかった。Windowsの新機能でそういうものがあって、そのまま設定しててもなんか行けてたっぽい。よくわからんけど。

できた

 かくして我が家に約11TBの極大ストレージが誕生したのであった。HドライブやらLドライブやら、そのあたりのいつからあるのか怪しいストレージをまとめて処分しようと思う。気が向いたら。たぶん。

 

 なんか思ったよりは遅くね? こんなもん? まあSATAだしUSB3.1だしこんなもんか。HDDよりは早くなってそうだし良いか。良いや。

 

 

 初めてできた「自分のPC」っていつだろう、と思ったけれど、そういえば自分の部屋ができて物心がついたころには父のおさがりのWindows 98だか2000が置いてあったな。小学校1年生だか2年生の頃にはHTMLを手打ちしてWEBサイトを作っていた記憶があるから、もはや物心がついた時から自分のPCがあった、ということかもしれない。

 AIが発達して、それに特化したUIが成熟したらコンピュータはどうなっているんだろう。QWERTY配列のキーボードやマウスなんてレトロゲーマーしか使わなくなっていたりして。今のアケコンみたいに。

エラーを書いた

 開発日記初回と言いつつ、並び替え周りの処理はわりかし出来てきているので、最近は自分でリファクタリングをしつつ、機能実装の抜け漏れがないか確かめているくらいの段階です。

 あとは実際に並び替えた結果に基づいてパート譜のPDFを結合・生成する機能を実装するだけですが、結構しんどいから右往左往しております。


 今日はそんな現実から目を背けるべく例外処理を書きました。「できなかったら None を返す」系の実装ばかりしがちだったので、この機に。

 これでパート譜のリネーム処理を噛ませていないPDFが混じっていても、間違えて空のフォルダを指定してもソフトごと即死しなくなりました。やったね! 今までは即死してました。

 いまんとこエラーはprint()で済ませてスルーしているけれど、ログウィンドウみたいなものを作ってもいいかなと思っています。

 tkinterでマルチスレッドであれこれするのがまだいまいちピンときてないので、またちょっと考えたい所存。


# 例外の定義

class PdfInfoError(Exception):
    pass


class NoPartsError(Exception):
    pass


class EmptyPdfError(Exception):
    pass


# 処理

class PdfInfo:
    __path: str
    __pages: int
    __pdf_id: uuid.UUID
    __print_count: int
    __name: str
    __part_code: PartCode

    def __init__(self, path: str, pages: int, print_count: int = 1):
        self.__path = path

        try:
            self.__name = self.__get_name_from_path(path)
            self.__part_code = self.__get_part_code(self.__name)
        except ValueError:
            raise PdfInfoError

        self.__pages = pages
        self.__pdf_id = uuid.uuid4()

        self.__print_count = print_count

    """  なんやかんや  """

    @staticmethod
    def __get_name_from_path(path) -> str:
        return os.path.splitext(os.path.basename(path))[0]

    def __get_part_code(self, name: str) -> PartCode:
        if not "_" in name:
            raise ValueError
        else:
            code_str = name[: name.find("_")]
            return PartCode(code_str)

    def get_part_name(self) -> str:
        if not "-" in self.__name:
            raise ValueError
        else:
            return self.__name[self.__name.rfind("-") + 1 :]

    def get_music_name(self) -> str:
        if not "_" in self.__name:
            raise ValueError
        elif not "-" in self.__name:
            raise ValueError
        else:
            return self.__name[self.__name.find("_") + 1 : self.__name.rfind("-")]


class PdfInfoFactory:
    @classmethod
    def create(cls, directory_path: str) -> list[PdfInfo]:
        file_paths = cls.__get_file_paths(directory_path)
        pdf_infos = []
        for file_path in file_paths:
            try:
                pdf_infos.append(cls.__create_pdf_info(file_path))
            except PdfInfoError:
                print(f"ファイル '{os.path.basename(file_path)}' は有効なパート譜ではありません")
                continue
            except EmptyPdfError:
                print(f"ファイル '{os.path.basename(file_path)}' は空です")
                continue

        if not pdf_infos:
            raise NoPartsError

        return pdf_infos

    @staticmethod
    def __get_file_paths(folder_path: str) -> list[str]:
        paths = []
        for pdf in glob.glob(f"{folder_path}/*.pdf"):
            os.path.basename(pdf)
            paths.append(pdf)
        return paths

    @classmethod
    def __create_pdf_info(cls, file_path: str) -> PdfInfo:
        try:
            pages = cls.__get_pages_from_file(file_path)
            pdf = PdfInfo(file_path, pages)
        except PdfInfoError or EmptyPdfError as error:
            raise error
        return pdf

    @staticmethod
    def __get_pages_from_file(path: str) -> int:
        with open(path, "rb") as f:
            reader = pypdf.PdfReader(f, strict=False)
            page_amount = len(reader.pages)
        if not page_amount:
            raise EmptyPdfError
        return page_amount
class App:

   """  なんやかんや  """

    def on_directory_path_selected(self, path: str) -> None:
        if path is None:  # ダイアログを閉じたり、キャンセルをクリックした場合
            return

        self.__directory_path: str = path

        try:
            self.__pdf_infos = PdfInfoFactory.create(self.__directory_path)
        except NoPartsError:
            print(f"{self.__directory_path} にはパート譜がありません")
            return


 こんな感じでよいのでしょうか。PdfInfoFactoryクラスはだいぶ昔に書いたので、中身がclassmethodだったりstaticmethodだったりまちまち。

 こないだから読んでいる本ではなるべくstaticmethodを使わずにインスタンス変数を用いて書いた方がいいという話だったので、このあたり直してみてもよいのかしら。

 まあ動いてるからいっか。

 だめか。

ときどきで良いので

 SNSを離れるようになったきっかけは何となくで、それっぽく言うならば自分の心を守るため、くらいのものだったけれど、なんだか離れてみた途端にTwitterはすごい荒れ方をし始めた。いや、今までも荒みきっていたのだけれど、水槽ごと揺らされたような感じは新鮮で、昔よく遊んでいたアバターチャットが、閉鎖する 1-2 年前にすごく変なアップデートを繰り返していたようなのを思い出した。あの時は離れて別のサービスに移住する人もいれば、閉鎖するその日まで居ついていた人もいて、居心地が悪くなって人も少なくなったピクセルアートのチャットルームは、それはそれで妙に孤独を慰めるような雰囲気に包まれていた。


 小学生のころからそんな界隈に居たものだから、おのずとTwitterにもずいぶんと世話になった。高校生時代は年間数万ツイートとかそういう勢いだったけれど、いつからか見たくないツイートの数が増え、見る機会は減っていった。自分の変化だったり環境の変化だったり色々するんだろうが、それはまた今度。ざっくり言うとおそらく、自分は自分の書く場所以上のものはそんなに求めていなかったんだと思う。


 といっても、自分は不特定多数に対する自己顕示欲みたいなのは本当にない、というかそういう規模感のものに対する想像力が足りていない。ただ昔から、自分の中に溜まっていく感情を消化するために、どこかの空間に吐き出す必要があった。そのあと誰が見るとかは割と気にしちゃいないが、自分は喋るよりは書くことで救われる方なのだろう。


 だから、そのための場所を作ることにした。書いときゃいいや、というモチベーションなのがハッキリしてるので、逆行してブログに。続ける気もないし、続けるかもわからないけど、ときどきで良いので、そのときどきのことを書ける場所をここに置いておく。



 あと、副次的な目的があるとすれば、ここは現在も鋭意開発中のPDF整理ソフト《Reppa》の製作日記にもなる。


 2年ほど前に一度完成を見はしたんだけれど、新機能を追加しようと思ったときに本当にコードがぐちゃぐちゃだったので全く進められず困っていた。そこで仲のいいゲーム友達に「なんとかしたいからリファクタリングしてくれ」と言ってコードを見せたら、「こんな1500行のクラスの面倒は見れん リファクタリングとかそういう問題じゃないから作り直しましょう」と。


 かくしてオブジェクト指向の何たるかを、動的型付けのデメリットを、リスコフの置換原則を、単一責任の原則を、適切なネーミングを……と、本当に手取り足取り教えて頂いて、5月ごろは毎日のようにDiscordを飛ばして質問して仕事帰りに答えてもらう、という本当に最悪の生徒をしていたのだが、よき先生についた甲斐もあって、今は検索しながら進めればずいぶんそれっぽいコードが書けるようになってきた。(まだまだなのは勿論自覚しているが)


 ただまあもちろん、書いていればぼちぼち疑問点があったりはする。いちいち聞くほど向こうに迷惑をかけたくないが、なんかチラチラ見てもらって気になったら教えてくれ、という甘えた感情を満たすため、「チラチラ見てくれ」とこのブログを投げることにする。分からないことがあった時にもDiscordに長文を送るよりはブログの記事URLを投げる方がよいだろう。よいだろう、じゃねえ。すみません。本当にいつもお世話になっております、ありがとうございます。@R


 記事の頻度でいうと「副次的な目的」の方が多くなりそうな気はするけれど、人生そういうもの。主か副かは頻度や密度で決まるものではない。



 というわけで、よろしくお願いします。矛盾するようですが、ときどきで良いので、気が向いたら覗いてください。ときどきの記。


from dataclasses import dataclass
from anywhere import Person

@dataclass(slots=True)
class MyBlog:
    title: str
    target: Person

    @classmethod
    def create(cls, stem: str, target: Person) -> Self:
        JAPANESE_CONSONANT = [
            "", "k", "g", "s", "z", "t", "d", "n", "h", "b", "p", "m", "y", "r", "w"
        ]

        title_elements = ["".join([JAPANESE_CONSONANT[i], stem]) for i in range(5, 8)]
        title = "".join(title_elements)

        return cls(title=title.capitalize(), target=target)

my_new_blog = MyBlog.create("oki", None)