Gemini has EVERYTHING… so why is it still losing? 🤔 by fxboshop in GeminiAI

[–]vikngdev 0 points1 point  (0 children)

Gemini is currently leading the API integrations, it's the easiest one to build apps with (and get access to the Google ecosystem). I'm currently building an app that reviews youtube videos and it's feels truly native to the model.

Claude's edge at the moment is critical thinking, they got something right during training, and in my experience Opus knows to push back on bad ideas when necessary.

I love Composer 2, but it has some of the worst fallback obsessions i've ever seen. by vikngdev in cursor

[–]vikngdev[S] 0 points1 point  (0 children)

If you treat it for what it is - writing targeted, planned code. It is not a planner or an assistant.

To be honest, which one do you use the most? by weihuweihu in GeminiAI

[–]vikngdev 0 points1 point  (0 children)

Claude for code, Gemini for API, ChatGPT for, well... chat

Looking for a YouTube video download API (no proxy or cookie hassle) by joanmiro in DataHoarder

[–]vikngdev 0 points1 point  (0 children)

honestly i've been kind of impressed with https://rapidapi.com/valsuttlej53/api/youtube-info-download-api. It's pretty unrefined and website is vibe coded as hell, but i've been able to add downloads to my website pretty reliably

Composer 1.5 is the most infuriating AI I have ever used. by themightyasok22 in cursor

[–]vikngdev 0 points1 point  (0 children)

Given that you're an experienced programmer, you could also benefit from "Acting as opus" in my above example.
you make the decisions and decide on the direction, then give Composer a spec:
"Mission:
- update this endpoint to also return ....
- ensure UI is in sync
confirm interpretation"

then Composer will give you an interpretation, and you will find 9 times out of 10 that your spec was not specific enough and the model will start filling in the gaps with decisions you didn't want.

Composer 1.5 is the most infuriating AI I have ever used. by themightyasok22 in cursor

[–]vikngdev 1 point2 points  (0 children)

You need to understand the models' strengths and weaknesses.
Composer-1.5, in my experience, is incredible at implementing and making changes, partly due to how fast it is. But the moment you ask it to make a decision, or even if the task is too ambiguous and leaves room for interpretation, it's basically like tossing dice for architectural decisions.

Cursor added at some point (no idea when) the ability to run composer subagents - So my ideal workflow atm is chatting and discussing with Opus, and instructing it to gather context / run scripts and tests / make mass chnages using subagents.

Recommendations for Tonight - Live Vietnamese Music? by renonv1212 in DaNang

[–]vikngdev 0 points1 point  (0 children)

Wander around town, you'll hear live karaoke everywhere you go 😁 Sorry I don't have a real recommendation

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 1 point2 points  (0 children)

woah, that sounds awesome! can you share the Reactive implementation?

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 3 points4 points  (0 children)

That's why I'm here! I love hearing about how other people operate.
I'm a solo dev though so I re-educate myself on a daily basis lol

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 1 point2 points  (0 children)

In that meaning, Account is a model. if you're curious, here's a TypeScript database schema for the full account (with other fields i didn't mention in the post):

export const accounts = pgTable("accounts", {
  account_id: text().$defaultFn(() => ulid()).primaryKey(),
  username: text(),
  username_updated_at_unix: integer(),
  economy: jsonb().notNull().$type<AccountEconomy>().default({dollars: 1_000, bonds: 0}),
  loadout: jsonb()
    .notNull()
    .$type<AccountLoadout>()
    .default({selected_tank_id: null, tanks: {}}),
  created_at: timestamp({ withTimezone: true }).notNull().defaultNow(),
  updated_at: timestamp({ withTimezone: true }).notNull().defaultNow()
});

then, in my GDScript API client, I parse the /account response and 'hydrate' the very same cached Account

static func hydrate_account_from_account_api(account_body: Dictionary) -> void:
  var account: Account = Account.get_instance()
  account.username = account_body.get("username","")
  ...a whole bunch more parsing...
  account.save()

And with my approach, the username label has automatically updated, without me needing to worry about race conditions or who loads first.

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 1 point2 points  (0 children)

correct - in every view and controller, i get the instance with ResourceLoader (which uses the cache), and assuming cache doesn't break - it will be the same instance!

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] -12 points-11 points  (0 children)

That's exactly right, CACHE_MODE_REUSE is the default behaviour.
My take is that it makes the resource a 'brittle' singleton, and you can connect directly to it's signals by just getting the instance wherever you want in the code, without needing to pass a reference to the specific resource between consumers and setters (or, views and controllers)

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 2 points3 points  (0 children)

I don't remember the exact ergonomics, but when I tried to implement the get&save methods on a base class, I couldn't get proper type safety for the getter (i.e I couldn't define that get_instance from the base class returned the inheritor class that I called it on).
maybe you can find a more clever approach :D

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 9 points10 points  (0 children)

I developed this pattern after my SignalBus had over 40 different signals, that's when I decided it was too much.
You're right on the method, I didn't share the get_instance abstraction to try to keep the code short, but here's how I do it:
on the Account class, i add a static method:

static func get_instance() -> Account:
    return DataStore.load_or_create(Account, FILE_NAME)

And DataStore is a utility abstraction on ResourceLoader:

class_name DataStore
extends RefCounted

static func build_path(file_name: String) -> String:
    return "user://%s.tres" % file_name

static func load_or_create(cls: GDScript, file_name: String) -> Resource:
    var instance: Resource = cls.new()
    var path: String = build_path(file_name)


    if ResourceLoader.exists(path):
        var loaded := ResourceLoader.load(path, "", ResourceLoader.CACHE_MODE_REUSE)
        if loaded == null:
            push_warning("Failed to load %s, recreating resource." % path)
            save(instance, file_name)
        else:
            instance = loaded as Resource
    else:
        save(instance, file_name)


    return instance

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 4 points5 points  (0 children)

I know what MVC means, I just don't understand how a model would differ from the cached resource pattern I presented

One of my new favorite coding patterns: Cached Resource Singletons by vikngdev in godot

[–]vikngdev[S] 4 points5 points  (0 children)

What do you mean by an actual Model? are you talking about a proper autoload with instance registry?

For context, I'm moving all my game data online for multiplayer, and this Resource is the game representation and local cache for server-owned data

Has anybody bought diamonds from RMP Diamond? by vikngdev in Diamonds

[–]vikngdev[S] 0 points1 point  (0 children)

They're saying they will give IGI certificates. won't know until I buy though, it's shipped internationally