#development

1 messages Β· Page 288 of 1

stark kestrel
#

Well that will take some time considering I'm on 4G x)

radiant kraken
#

i can't believe it's already at 1.17 GiB wth πŸ’€

stark kestrel
#

speed is random

radiant kraken
#

uhhh i'm sure you can make it faster by adding --depth 1

stark kestrel
#

It's a 70ish percent, probably not worth it anymore

radiant kraken
#

😭

#

i should change the readme example

#

ppl shouldn't fetch the entire repository lmao

stark kestrel
#

at least i have unlimited mobile data KEKW

#

What are the requirements exactly?
It's trying to fetch libs in /usr/local/lib but that's not on macOS

#

it just wanted that folder to exist all good

radiant kraken
#

that's all

#

you need to build it

stark kestrel
#

looks all good

radiant kraken
#

YOOOOOOOO

#

MY CODE WORKS

stark kestrel
#

πŸ”₯

radiant kraken
#

i've tested it only in windows 😭

stark kestrel
#

Can have a try on a linux vm, have one set up

radiant kraken
#

okay

#

this time

#

dont clone the entire repo

#

😭

stark kestrel
#

Yeah KEKW

#

Yeah that was just a tiny bit faster KEKW

#

Yeah works also fine, I just had to manually move the lib to the folder

#

Not sure if that can be changed, but the binding works so πŸ”₯

radiant kraken
#

WHAT 😭😭😭

neon leaf
#

/home is on a different mount point

#

you need to copy the file instead of moving

radiant kraken
#

alright alright

#

will fix

#

never knew that's a thing as i don't use linux ia_lul_haha

stark kestrel
#

Yeah I did a cp and solved it so was all good

#

Maybe you can also create the folder if it doesn't exist, considering it's ran as sudo either way?

#

I had to create it myself

radiant kraken
#

create the folder?

stark kestrel
#

/usr/local/lib

radiant kraken
#

oh it does not exist? 😭

stark kestrel
#

I didn't have the lib, it's not per default

radiant kraken
#

that's crazy

stark kestrel
#

Yeah, had some issues with carbon as well with that

sharp geyser
#

Back on my motivation to learn C++

radiant kraken
#

based

#

C++ is super fun

#

C is even more so

#

fix pushed

stark kestrel
stark kestrel
#

Honestly didn't expect you to do it so quickly

radiant kraken
#

the new release is not out yet lmfao 😭

#

but thanks so much ❀️

#

i definitely did not use chatgpt

stark kestrel
radiant kraken
sharp geyser
#

@radiant kraken ever used clang for c/c++?

radiant kraken
#

yes

#

not often tho

sharp geyser
#

I am having troubles setting it up

radiant kraken
#

what is your OS?

sharp geyser
#

win 11

#

clion can't find the RC compiler

radiant kraken
#

how did you install it?

sharp geyser
#

even though I have the win 11 dev kit installed via vs

sharp geyser
radiant kraken
#

ohhhh

#

i don't use clion so plump_pain

sharp geyser
#

If this helps idk

radiant kraken
#

i mostly work with vscode

sharp geyser
#

Ah okay

#

There we go

radiant kraken
#

oh i was about to tell ya ia_lul_haha

sharp geyser
#

I set the -DCMAKE_RC_COMPILER to be the llvm-rc

radiant kraken
#

nice!

sharp geyser
radiant kraken
#

what are you working on?

sharp geyser
#

Right now, just learning C++

#

but I want clang setup cause clang = better errors typically

radiant kraken
sharp geyser
#

Lot easier to read them at least

#

Dk if linker errors are better

#

ahaha

radiant kraken
#

if you struggle with it, don't hesitate to hmu!

#

do you use cmake?

sharp geyser
#

I will be using cmake yeah

radiant kraken
#

ayyyy!

#

now we're talking

sharp geyser
#

Right now just following The Cherno's guides and just updating myself on what C++ basics are like though I anticipate they will be familiar

radiant kraken
sharp geyser
#

Anyone wanna explain what this asm does

#

I vaugely understand it

#

but after googling what eax and such mean I don't really get it

#

eax is some sort of register?

#

@radiant kraken

#

Question

#

In C++ or even C, headerfiles can just be declerations right?

#

like

#
void Log(const char* message)
radiant kraken
sharp geyser
#

and then you'd have a cpp file that defines what Log is

radiant kraken
#

yes!

#

that's the standard way we do in C/C++

sharp geyser
#

But I also know you can literally just do it all in the header file

#

So why make a cpp file for that header file

#

like Log.h and Log.cpp

#

Granted this is such a super basic example

#

but I am wondering why even have cpp files if you can do everything in header files

#

minus your main cpp file

radiant kraken
#

if you split them into two files, header and source, you can make use of the advantage of linking, keeping them all intact and reducing duplicated code when linking and compiling

#

that's what i know

sharp geyser
#

I see

radiant kraken
#

since #include essentially just pastes the header contents

#

like A would include C and B would include C, if you compile and link A and B together you would have two instances of C

sharp geyser
#

Right

#

but if you build for release, wont it see those 2 includes and combine it into just 1 ?

#

Like say A and B both need iostream

#

surely it won't include iostream twice right?

radiant kraken
#

unsure

#

i don't think the C++ standard library is header-only

#

sure there are inline and templated functions/classes, but some of it shouldn't be written in headers

sharp geyser
#

I see

#

I just know you do #include <iostream>

radiant kraken
#

i'm sure the C++ standard library has its own library file

#

like .so/.dll

#

so unless you're writing templated/inline functions/classes, there are not much reasons for you to write everything in a header file (especially if it's being used across several source files)

sharp geyser
#

Gotcha

#

So
.h = declerations
.cpp = definitions

radiant kraken
#

exactly!

sharp geyser
#

I only ask because when I made the vector implementation I did it all in a h file

radiant kraken
#

that's fine!

#

your vector implementation is templated, right?

#

so it's fine

sharp geyser
#
#ifndef VECTOR_VECTOR_H
#define VECTOR_VECTOR_H

#include <stdexcept>

template <typename T>
class Vector {
  T *array;
  size_t capacity;
  size_t length;

  void resize_to_fit(size_t index) {
    int newCapacity = capacity;
    while (newCapacity <= index) {
      newCapacity *= 2;
    }

    T* temp = new T[newCapacity];

    memcpy(temp, array, sizeof(T) * capacity);
    capacity = newCapacity;
    delete[] array;
    array = temp;
  }

 public:
  Vector() : capacity(1), length(0), array(new int[1]){};
  explicit Vector(size_t size)
      : capacity(size), length(1), array(new int[size]){};

  size_t size() const { return length; }

  inline void push_back(T element) { insert(length, element); }

  void insert(size_t index, T element) {
    if (index >= capacity) {
      resize_to_fit(index);
    }

    if (index >= length) {
      length = index + 1;
    } else {
      length++;
    }

    array[index] = element;
  }
  T &operator[](size_t index) const {
    if (index >= length) {
      throw std::range_error("index out of range");
    }
    return array[index];
  }
  ~Vector() { delete[] array; }
};

#endif  // VECTOR_VECTOR_H
radiant kraken
#

yeah

sharp geyser
#

you mean templated like this?

radiant kraken
#

templated functions are written in headers

sharp geyser
#

I forgot what templates are tbh

#

Sure I will learn it eventually

radiant kraken
sharp geyser
#

109 cherno videos to go through

radiant kraken
#

don't hesitate to ask!

sharp geyser
#

Thanks

#

Off to work for now

radiant kraken
#

bai bai!

wheat mesa
neon leaf
#

??????????????????????????

#

thank you eslint

acoustic bough
#

me after I add a new rule

patent bramble
#

hmm, interesting. Still, a bit outside my scope for this, but good to know nonetheless.

sharp geyser
#

Is there still like method/func generics?

wheat mesa
sharp geyser
#

Gotcha

sharp geyser
#

@radiant kraken Love finding out about clang-tidy and clang-format

#

πŸ™

sharp geyser
# radiant kraken yuuuhhhh!!

Made a transpiler from C++ to luau

class Player
{
  public:
  int health;
  void takeDamage()
  {
    health = health - 10;
  }
}
local Player = {}
Player.__index = Player

function Player.new()
        local self = setmetatable({}, Player)
        self.health = 0 --[[ int ]]
        return self
end

function Player:takeDamage(self)
        self.health = self.health - 10
end

return Player
#

Transpiler is made in ts granted

#

so no actual C++ skill

#

Honestly was just bored

radiant kraken
#

you're fine!

#

don't worry!

#

i often feel bored too

haughty otter
#

i need ideas for my bot

#

i need a vote reward after my bot gets accepted

#

what should be the reward

deft wolf
#

Something worth voting

long marsh
#

I guess there's a fortunate side effect for the bot approval process taking 2 - 3 weeks. Those that submit bots then abandon them typically happen in that time frame haha

long marsh
# haughty otter what should be the reward

That's highly subjective to you and your bot's niche. For example, I have several commands that people can use that earn virtual currency. Then I have another command that allows premium players to execute them all at once rather than individually. When my bot is approved, I'll allow those with a certain vote streak to be able to use that command as well.

vagrant notch
#

oh man i made another mistake while updating my service 😭 it uses sveltekit and i just switched to bun from node, and tried using a bun adapter for sveltekit not knowing the adapter was unmaintained and so it had issues

#

this made it so when doing stuff like post, put, patch etc requests give a forbidden error

#

i didnt experience this issue during development, it was only in production

#

and this buggy version of the service was up for 8 hours πŸ™ πŸ™

#

so cooked

#

and the worst part is i saw someone trying to log in through my analytics

#

and they never were able to login because of this issue

haughty otter
#

i need ideas for commands (theme is fun, games, useful)

quartz kindle
#

why the switch though? just curious, i use node myself

#

im first timing sveltekit as well and its been pretty awesome so far

lament rock
#

honestly not a fan of bun

vagrant notch
#

also i saw using a bun adapter allowed for implementing websockets directly

#

which was kinda cool and couldve been of use in my app

vagrant notch
spark flint
lament rock
#

no idea who u are but also not a big fan of you
jk

long marsh
#

I used Bun to power my last API and it worked really well with zero memory problems (unlike what I've seen in node)

#

Totally acknowledge that it's not always about the runtime, but the memory consumption of node seemed elevated when compared with bun.

vagrant notch
#

tbh i care a lot about dx so im just gonna say deno is probably my favorite runtime

#

i wouldve loved to use deno for everything but the support just isnt there yet 😒

lament rock
# long marsh Just curious: why?

A lot of the claims of bun about performance are typically not representative of real world scenarios and even within its own web server (using uws.js), its performance is worse than on node

loud canopy
#

you cant make a SKU purchasable more than once?

loud canopy
#

didnt have function to consume the SKU for single purchases

#

and also bc my dumbass would insert the entitlment info AFTER the bot handles it in the database

#

so i had to swap them

frosty gale
#

deno quite literally exists because rust πŸš€πŸš€ but dont know what motives bun has

vagrant notch
#

less memory consumption or something

#

i have a friend that hypes bun up because of this

#

probably because he doesnt have much memory to spare during development lol

sharp geyser
#

dk if that was the main reason or not

haughty otter
#

yay my bot got approved

lyric mountain
#

It amazes me how segmented js ecosystem is

old whale
#

Can anyone help me related to the voting webhook....

old whale
#

So I am hosting it on my friends cloud hosting

quartz kindle
# old whale So I am hosting it on my friends cloud hosting

first you find the ip address or url that the could hosting assigned to your instance
then your bot needs to run a webserver to receive the webhooks (top.gg libraries can do this for you)
then in the top.gg website you input the url where your bot can be reached, for example the bot's ip address plus webserver port plus any path you configured

vagrant notch
lyric mountain
#

yk, I'm kinda liking generating procedural maps

#

the gen rules are mostly finished, it's fun going down and seeing how it generates each floor

neon leaf
#

@quartz kindle 1:100 map incoming

#

if I freed up some space I could barely get 1:67 too

#

but thats it lol

#

1:10 is like 140TB

quartz kindle
deft wolf
#

Holy

stark kestrel
#

pov you set up renovate 🧌

sharp geyser
#

pov: what is renovate

stark kestrel
digital swan
stark kestrel
stark kestrel
#

Quite good and honest comparison

quartz kindle
#

ip is defined by the host, port and path are defined by the application

#

although some hosts limit which ports you can use

#

for example, using a regular VPS:
host gives you ip 999.999.999.999
you install and configure topgg sdk for your prefered programing language
you set it to port 3000 and path "/topgg"
in your top.gg bot page, you will use the following url: http://999.999.999.999:3000/topgg

#

depending on your hosting provider, you may also need to configure its firewall to allow that port

lyric mountain
#

aight done, I think

queen needle
#

No clue what I'm looking at it but seems awesome

lyric mountain
#

players descend node by node, one of the dungeons is an infinitely deep one

queen needle
#

Holy cow that is awesome

lyric mountain
#

so I made a procedural generator for it

#

next step is integrating into the game, every yellow node will generate a random event

#

green nodes are rest spots, kinda like a savepoint

#

oranges will be dangerous encounters, and reds will be bosses

prime cliff
#

You probably dont want to make that many paths for a floor 1 xD maybe gradual increases

lyric mountain
#

Maybe every 10 floors, idk

prime cliff
#

Depends how long your game is, how many unique events/tiles you have and other special content

lyric mountain
#

There's no length, progress os persistent across sessions

prime cliff
#

You could look at other floor based games for ideas too

#

Pretty sure inscription had a mini game of that at one point?

lyric mountain
#

I'll take a look

prime cliff
lyric mountain
#

I also need to decide whether I'll allow more than 5 nodes per sub-area or keep it low

#

More nodes mean more events per floor

#

But the travel per floor is always N or lower, with N being number of sub-areas

prime cliff
#

You could also give like buff tiles per-floor

lyric mountain
#

Oh I will, that's why I rewrote it to be floor-based instead of free nodes

#

Also plan on adding visual penalties like "you can only see in a small area around you" or "room types are unknown"

lyric mountain
#

also +1 to minimum every 20 (capped at half max) so you dont get a single room connecting to more than 5 and to make branch choice more impactful

sharp geyser
#

I assume this is non-specific enough to roblox that anyone who knows ts / programming could answer. I have an ECS and in my systems I sometimes need to listen to events thrown by the roblox engine.

Problem is systems run every frame AKA listening to events spawn a new RBXScriptConnection every frame AKA bad performance AKA no good

import { RunService } from '@rbxts/services';

type InferSignalParameters<T> = T extends RBXScriptSignal & { Connect(fn: (...args: infer U) => void): unknown }
    ? U
    : never;

interface EventData {
    queue: unknown[][];
    idx: number;
}

const dataBySignal = new WeakMap<RBXScriptSignal, EventData>();

RunService.Stepped.Connect(() => {
    for (const [_, data] of dataBySignal) {
        data.idx = 0;
        data.queue = [];
    }
});

export function useEvent<I extends Instance, E extends InstanceEventNames<I>>(
    instance: I,
    event: E,
): IterableFunction<LuaTuple<[number, ...InferSignalParameters<InstanceEvents<I>[E]>]>> {
    const signal = instance[event] as RBXScriptSignal;

    let data = dataBySignal.get(signal);
    if (!data) {
        data = { queue: [], idx: 0 };

        signal.Connect((...args: InferSignalParameters<InstanceEvents<I>[E]>) => {
            data!.queue.push(args);
        });

        dataBySignal.set(signal, data);
    }

    const iter = (): LuaTuple<[number, ...InferSignalParameters<InstanceEvents<I>[E]>]> | undefined => {
        data.idx++;

        if (data.idx <= data.queue.size()) {
            return $tuple(data.idx, ...data.queue[data.idx - 1]) as LuaTuple<
                [number, ...InferSignalParameters<InstanceEvents<I>[E]>]
            >;
        }

        data.idx = 0;
        return undefined;
    };

    return iter as IterableFunction<LuaTuple<[number, ...InferSignalParameters<InstanceEvents<I>[E]>]>>;
}

I have this, and seemingly it does add everything to the map I make, but the issue is when I use this function, the RBXScriptSignal is never actually fired, thus none of the args/data from said signal are ever returned in the tuple

#

RunService.Stepped for reference runs every frame prior to physics simulation

#

Correction the args are not added to the map

#

For whatever reason

prime cliff
#

Working on status pages/monitor service for Dev Space.
Does this look good?

I was thinking of adding support for sharded data like discord bot shards using an array or key based shard id.

hybrid ingot
#

Does anyone know a bot that can be used to kick people that haven't chatted within a certain time period from servers?

slender wagon
#

question, is there a way i could add members that aren't verified yet to a section of the server where they can't fetch any members? (Trying to prevent mass scraping)

deft wolf
#

I'm not sure if that's possible. Things like server members and channels are sent via the API regardless of whether you have access to them in the client or not. This is why it's possible to use plugins that show you "hidden" channels

dusk pebble
#

the Member object has Verified property

#

depending on what lib you are using

stark kestrel
dusk pebble
#

true

#

if the member isn't verified , add a role with little to no permissions, would that hinder scraping member data?

deft wolf
#

The problem is that scraping isn't done with clients, but with self-bots that utilize Discord's API. Anything you can do with a bot, you can do with a self-bot pretty much

#

If a bot without any permission is able to fetch server members, then selfbot will be able to do it too

dusk pebble
#

hmmm, I guess that is a Discord API issue

wicked hazel
#

Ci sono italiani qua dentro?

stark kestrel
#

A few years ago they worked on a way to return the channels you don't have access to as something like "no_access" or whatever else, don't remember

#

Never got actually implemented, but more irrelevant things did

dusk pebble
#

thats a discord theme

desert lynx
hybrid ingot
#

There used to be a bot called booty bot that would do that but it stopped working like a year and a half ago

desert lynx
#

Have to deal with other things first though

#

Last major changelog was er

#

12K characters big LMFAO

hybrid ingot
#

I have no idea what you’re talking about but sounds cool 😭

desert lynx
#

Still have to work out the kinks now that it's out in prod

desert lynx
#

result:

#

change a shit load of things = a shit ton of things will break

slender wagon
#

like people wont be able to dm eachother?

#

Im facing some serious issue with mass-dms its really annoying

vagrant notch
#

and pause DMs

slender wagon
#

oh okay thanks

pearl trail
#

guys, should i be worried about this error, because it runs fine when i execute it

delicate zephyr
slender wagon
#

made my own alt identifier as well

shell tundra
dusk pebble
#

works for me

slender wagon
#

question, will i lose my early verified badge or will my bot lose the verified status if i change the name of it?

long marsh
#

When you all send your stats to topgg, do you send both user installs and guild installs? Or just guild installs?

#

Meaning, do you add the two together and send it?

vagrant notch
stark kestrel
#

no

zenith flame
prime cliff
#

It says status and uptime where did you get it was hosting bots xD

zenith flame
#

@prime cliff ahaa its just say how time the bot was online ?

prime cliff
#

Yea its a status checker/monitor

zenith flame
prime cliff
#

Although this project does have an app creation system, you would need to self host it though

desert lynx
#

i hate discord mobile so much

#

on desktop that button DOES scroll to the top of the message

stark kestrel
#

that's what you deserve for using the light mode /s

desert lynx
#

i can't read shit if it's in dark mode

#

not sure why

honest fox
slender wagon
#

is cloudlfare + nginx rules good enough to prevent damage from ddos attacks

median axle
prime cliff
#

Ddos dosent cause damage though it's essentially a stun xD

slender wagon
#

well it could bottleneck the db which will have result on the users performance

slender wagon
#

this is what i mean by damage

prime cliff
#

Also you should setup a firewall that can block incoming connections and you can whitelist cloudflare and your own ip

slender wagon
#

okay

arctic kernel
#

if you have the proxy off it won't. As well as if people attack the IP itself it won't

harsh nova
#

No

slender wagon
#

Thank you!

desert lynx
slender wagon
#

why does my vps have such a heartbeat?

humble gyro
#

@slender wagon do you run a bot on there/

slender wagon
#

im literally feeling bad for my vps

#

its handling very well for a $5 vps

humble gyro
#

probably user update spam from discord

#

i see that a lot too

slender wagon
#

in one of the bots im using discordeno, that one is very calm

#

the other is running discord.js

#

that's where the problem starts ig

stark kestrel
sharp geyser
#

@wheat mesa now I know you said you didn't use an ECS much, but I wonder if you could think of a way to get player data inside of a system.

#

I have tried several ways and they just seem hacky

#

like they work but it seems to defeat the point of an ECS

#

Since systems run every frame, trying to access player data inside them without a bunch of null checks which can derail the system seems impossible

sharp geyser
#

Figured it out

#

:p

lyric mountain
#

global variables for such stuff is fine

stark kestrel
#

@radiant kraken so looked over the code, looks all good honestly

A few things I've noticed:

On line 402 of the bots.go file, there is an unnecessary authorization header , it's already set in the c.createRequest method

Also the rest is mostly how we (i guess) tend to code in Go, not really like

res, err := c.httpClient.Do(req)

if err != nil {
  return 0, err
}

But more

res, err := c.httpClient.Do(req)
if err != nil {
  return 0, err
}

Go's error handling is already a mess, no need to artificially make the files longer because of it


Comments are sometimes correctly written as

// HTTPClientOption allows for customizing the HTTP client used.
func HTTPClientOption(httpClient HTTPClient) OptionFunc {
  // ...
}

Sometimes they're

// Information about your bot's server count
func (c *Client) GetServerCount() (int, error) {
  // ...
}

Sometimes non-existent

I think it makes sense to keep the comments always the same and as godoc wants them to be, so like the first one


For the webhook.go file, there's

type wVotePayload struct {
  Bot       *string `json:"bot"`
  // ...
}

func NewWebhookVotePayload(data []byte) (*WebhookVotePayload, error) {
  p := &wVotePayload{}
  if err := json.Unmarshal(data, p); err != nil {
    return nil, err
  }
  // ...
}

Considering wVotePayload is just used there, I think it makes more sense to do something like

func NewWebhookVotePayload(data []byte) (*WebhookVotePayload, error) {
  var p struct {
    Bot       *string `json:"bot"` // even lowercase is fine, no need to export it
    // ...
  }
  if err := json.Unmarshal(data, &p); err != nil {
    return nil, err
  }
  // ...
}
quartz kindle
#

how about global kuuhakus

radiant kraken
#

thankies! ❀️ granted i am not that proficient in go hahaha!

lyric mountain
neon leaf
#

@quartz kindle world generation still running btw (I shouldve used a prefiltered osm pbf instead of filtering it myself)

long marsh
#

Is anyone here actually building the discord activities?

smoky fractal
#

hey anyone knows how to detect slash commands given to other bots ?
and how fibo does that?

deft wolf
#

As far as I know, they listen to the embeds that are sent in response

#

You check the author of the message whether it is disboard, check the embed content whether it indicates that a bump was made and set a timer for your bot to mention someone there in two hours

#

Theoretically, the messages probably have information about what command the response was made from, but you are not able to check whether the vote was made correctly based on this, so you check the content of the embed

smoky fractal
#

break down of embed doesn't have that info

#

fibo is doing smth that I don't know abt

deft wolf
#

Interaction reply should have interaction_metadata field which should contain this info

smoky fractal
#

thanks a lot

stark kestrel
#

TL;DR
Bitnami (aka VMware aka Broadcom) is money hungry and moving off open source. They will now use a subscription model for their images and charts

quartz kindle
#

does that mean its ok to pirate vmware?

#

:^)

small tangle
#

Money hungry or trying to be sustainable? HMM

stark kestrel
#

Official pricing verification confirms the $50,000-$72,000 annual subscription costs through AWS Marketplace listings and Arrow Electronics distribution agreements. Bitnami Premium costs $50,000 annually and provides unlimited access to 500+ applications, while Bitnami Secure Images requires $72,000 yearly for 280+ hardened applications with advanced security features.

#

Money hungry

#

It's been perfectly maintained and sustainable for years

small tangle
stark kestrel
#

Especially that now it pretty much cannot be used by hobbyist

#

Unless someone wants to put in the money for that subscription πŸ™ƒ

crystal wigeon
#

anyone using ahrefs with SPA?

arctic kernel
#

and like he said above pull metadata to find the user who ran it

#

problem is you need approved for message intent. Still unsure if my use case will be approved :/

quartz kindle
crystal wigeon
quartz kindle
#

usually you want an SPA hyhbrid, that can render the correct page both by browser navigation and by direct url access

crystal wigeon
#

well the framework just creates a index.html and then loads script, there no content in that .html

quartz kindle
#

bots usually get the page content by direct url, not by client side navigation

crystal wigeon
#

hmm

#

right

#

but google loads the script tags in the .html files so there's no problem with seo there

#

any way to have the same behavior for ahrefbot?

quartz kindle
#

bots dont follow hrefs by clicking on them

#

they follow them by accessing the url they point to

#

as a separate request

#

so they should see whatever you see if you type the full url directly

crystal wigeon
#

yeah but ahref is not seeing that

#

here's what it sees

#
<html lang="en">
        <head>
// stuff
 <script type="module" crossorigin src="/assets/index-BEETA0A1.js
"></script>
                <link rel="stylesheet" crossorigin href="/assets/index-BlJif3eR.
css">

        </head>
        <body class="h-dvh">
                <noscript>
                        <p>You need to enable JavaScript to run this app.</p>
                </noscript>
                <div id="root" class="h-full"></div>

        </body>
</html>
quartz kindle
#

you're talking about this? ahrefs.com

crystal wigeon
#

yeah

#

lol

quartz kindle
#

ah then idk, you need to check their docs or something

crystal wigeon
#

ahrefbot, it doesnt seem to be loading the script tags

#

i read their article, they claim to load js for SPAs

#

anyway thanks

quartz kindle
#

guys

#

i never used vercel before

#

i created a project from their basic nodejs template

#

and it always returns 404

#

how do i get it working? deployment says its deployed in production

#

the template has an api/hello.ts file, i tried renaming it to index.ts since some answers online said to do that, but still only get 404 lol

#

nvm figured it out, i had to create a vercel.json file and add routes there, why dont they include this in the damn template? ffs

lament rock
#

I'm needing some high frequency, decent core count CPUs for a server I'm gonna be running while being decently cheap. Anyone got any suggestions? This will be for a modded MC server

neon leaf
#

ryzen servers

lament rock
#

I'll take a look if I can't manage to find something laying around my house

deft wolf
#

Clever affiliate link pogey

neon leaf
#

have it since 2023

quartz kindle
#

your affiliate link is "index"?

#

lmao

neon leaf
lyric mountain
prime cliff
#

Nice you doing Discord components too

lyric mountain
#

now all that remains is making floors gain random mods depending on their seed

#

the global mods, player pos and player hp are saved across sessions

neon leaf
#

@quartz kindle progress after 76h

#

not even a single region file generated yet πŸ™

quartz kindle
neon leaf
#

well, atleast region generation should be multithreaded

#

for some reason with a 16 thread hard cap but whatever

#

no

knotty night
#

@solemn latch too

dusk pebble
#

I dont get out of bed for $2000 a month

sharp geyser
#

Cap

dusk pebble
#

must be part time

sharp geyser
#

?

sharp geyser
#

@quartz kindle can you tell me why

const orig = { a: 5, b: [1,2,3] }
const deepCopy = structuredClone(orig);
const deepCopy2 = JSON.parse(JSON.stringify(orig))
const shallowCopy = {...orig}

console.log(orig.a === deepCopy.a) // false
console.log(orig.a === shallowCopy.a) // true
console.log(orig.a === deepCopy2.a) // false
#

What exactly is structuredClone (or even other methods such as using JSON.parse + JSON.stringify) doing to make it so its not equal anymore

#

Is it different signatures or whatever its called ?

neon leaf
#

memory addresses

sharp geyser
#

Really?

#

Is that how equals works in ts/js?

#

It compares memory addresses?

neon leaf
#

also ur example is wrong

neon leaf
#

all of those are true

sharp geyser
#

They aren't true

neon leaf
#

if you compared b they wouldnt be

sharp geyser
#

Wrong

neon leaf
#

a is a number, that can be compared directly

sharp geyser
#

I literally just did it in google chrome console

#

Only one that returned true was shallowCopy

quartz kindle
#

obj1 === obj2 means obj1 equals obj2 in terms of reference, the entry point of the object in memory is the same

neon leaf
#

if you check with b then you get the results you showed

#

because its an object

sharp geyser
neon leaf
#

console.log(deepCopy2)

sharp geyser
#

Ah wait sorry I used the wrong example, the one here differs

#

orig is a object with a nested object and array

#
const orig = { a: { x: 1}, b: [1,2,3] }
neon leaf
#

yes, objects are compared via reference, primitives via value

sharp geyser
#

Sorry my fault

quartz kindle
#

also, structuredClone is slow af

#

dont use it

sharp geyser
#

Ah I wouldn't

#

I just didn't know what a deep copy vs a shallow copy really was tbh

#

πŸ’€

#

Someone yapped at me for doing a deep copy of something when they said a shallow copy was fine

quartz kindle
#

shallow copy = obj inside obj will keep being the same, because only the reference is copied

sharp geyser
#

Gotcha

neon leaf
#

its such a weird concept that everything is a mutable reference without telling you

sharp geyser
quartz kindle
#

for example

sharp geyser
#

Then I am confused, cause someone said I needed to make a shallow copy because modifying the original is unsafe (in context this is for a datastore library for roblox where the returned data is supposed to be readonly)

quartz kindle
#
a = { primitive: 1, object: { test: 10 } }
b = { ...a } // b is a shallow copy of a
b.primitive // this is a full copy of a.primitive and it belongs solely to object b and changing it wont affect object a
b.object // this is a reference to object { test: 10 }, it exists only once, and is accessible from both a and b, changing it from either a or b will change it for both
neon leaf
#

*changing data inside it

sharp geyser
neon leaf
#

modifying the property value itself wont affect the other object

sharp geyser
#

Then what are these people yapping about

wheat mesa
#

A shallow copy is when every primitive of an object is copied, but the objects within are not copied. They are references internally, so when you do a shallow copy, you’re just copying over the reference of the object to the new object. A deep copy means truly copying each and every property, including nested objects

sharp geyser
#

This is what these people said when I was modifying the state directly

wheat mesa
#

One object that is shallow copied that has a nested object inside of it will point to the same memory as the object it copied (For the nested objects, not the primitives)

sharp geyser
#

They said make a shallow copy, but if modifying the copy also modifies the original if its an object (which most of the data is) then whats the point ofm aking a shallow copy

neon leaf
#

probably just a mix up

sharp geyser
#

I don't know anymore, im confused

wheat mesa
#

Aren’t you working with a ts -> lua transpiler?

#

So the rules of the js engine don’t apply, it’s Lua’s runtime isn’t it?

sharp geyser
#

Nah im not

wheat mesa
#

Ah

sharp geyser
#

Also lua has similar rules in terms of modifying objects from what I recall

quartz kindle
#

why doesnt js have a native way to make a deep copy of an object

sharp geyser
#

JSON.parse(JSON.stringify()) according to google is a way to make a deep copy

quartz kindle
#

a simple recursive function is orders of magnitude faster than any js "recommended"method

wheat mesa
sharp geyser
#

Right

#

I am not sure what I should do now

quartz kindle
#

call the police

#

oh wait

#

you are the police

sharp geyser
#

lmao

neon leaf
#

call the irs

#

they always know everything

quartz kindle
#

oh no

#

they will find out i dont pay taxes

neon leaf
#

they already know

#

they also know your expiry date for living on earth

quartz kindle
#

i have a good reason for not paying them though

#

not living in the US :^)

neon leaf
#

still waiting for u to try rust

quartz kindle
#

something funny

#

i tested netlify today, because of an issue someone reported

#

netlify is like an aws lambda, it does edge functions and stuff

#

but

#

they build your app in ubuntu 24, and then they deploy it to an aws instance running amazon linux 2

#

and if your app has native code, it wont work lmao

neon leaf
#

didnt u already talk about this before sir

quartz kindle
#

no? not today at least

#

i talked about vercel

neon leaf
quartz kindle
#

well yeah

#

it was for that reason, but i wanted to investigate further

neon leaf
#

i c

quartz kindle
#

and the issue is, native apps built with gcc wont run on older linuxes

#

which is counter intuitive

#

instead of being backwards compatible, they are forward compatible

neon leaf
#

ye

#

thats why musl exists

quartz kindle
#

lmao

neon leaf
#

200kb more for full compat

#

i was able to run a musl rust app compiled on ubuntu 22 on ubuntu 14

#

also its not directly because of gcc

#

its because of ldd

#

it links your binary to glibc

quartz kindle
#

ye

neon leaf
#

ye

#

u can configure

quartz kindle
#

i need to figure out how to setup prebuilds

#

so annoying

wheat mesa
quartz kindle
#

ew

#

no me gusta el dockero

wheat mesa
#

porque

sharp geyser
#

I was looking at the internals of a game's server side code

#
  public bool Insert(Item item)
  {
    if (this.itemList.Contains(item) || this.IsFull())
      return false;
    this.itemList.Add(item);
    item.parent = this;
    if (!this.FindPosition(item))
      return false;
    this.MarkDirty();
    if (this.onItemAddedRemoved != null)
      this.onItemAddedRemoved(item, true);
    ItemContainer parent = this.parent?.parent;
    if (parent != null && parent.onItemContentsChanged != null)
      parent.onItemContentsChanged(item, true);
    Interface.CallHook("OnItemAddedToContainer", (object) this, (object) item);
    return true;
  }

Why the heck are they stopping the insert if the itemlist already contains the item

#

I understand if its full

#

Like what if they are allowed to have multiple stacks of said item

wheat mesa
#

I mean it might be a unique list? Like a set structure of some sort

quartz kindle
#

isnt the item amount a property of said item?

#

its much more efficient having a map of unique items and their quantities than having multiple copies of an item in an array

sharp geyser
#

iara_shrug I honestly have no idea

#

There's a lot of code in this game's server side that makes no sense

#

A lot of unused functions

quartz kindle
#

is it roblox?

sharp geyser
#

Some that are increadibly terribly coded

#

Nah

wheat mesa
#

A lot of game dev is horrendous

sharp geyser
#

Its a unity game

wheat mesa
#

I would take everything with a grain of salt

quartz kindle
#

league of legends spaghetti code says hi

sharp geyser
#

This is the code behind Rust's server

wheat mesa
#

I would definitely not look at the code standards for a large game like Rust

#

90% of the code is probably β€œoh yeah I’ll write this for myself, then 5 junior devs will come along later and fuck with it until it’s awful”

sharp geyser
#

Lmao

#

I wanted to mimic the same principal of having an ItemContainer and PlayerInventory classes

#

Seemed like a good way to organize things

quartz kindle
#

i imagine most early access games have bad code in them

#

they literally started as an experiment

sharp geyser
#

But I honestly have no idea how the magic of this code works because that Insert function simingly oesn't support stacked items (unless the itemList just keeps increasing the amount and then splits it up in UI based off the amount and some maxStackSize)

#

That's honestly smart though

#

hm

sharp geyser
#

I hate working with data

#

I can never seem to get it right on how to ensure the data exists before doing anything else

#

copilot to the win. See I thought about making a recursive function that calls itself if need be, but I wasn't sure if that was smart.

quartz kindle
#

:^)

queen needle
#
if(!dataExists) return;
//do stuff with data```
sharp geyser
#

So I had to keep fetching it until it was no longer undefined

arctic kernel
quartz kindle
#

you dont have anyway to check when the data you need is available to be fetched or what?

sharp geyser
#

It’s a bit weird to code that in this environment

#

Since the data is loaded on the server, the client isn’t guaranteed to have it

sharp geyser
#

I’d still end up needing to fetch at a later date anyway

quartz kindle
#

if you have to "keep fetching until its no longer undefined" you're doing something very wrong

#

kinda like trying to make a timer by repeatedly checking in a loop whether enough time has passed

sharp geyser
#

Cause I find myself questioning how to write something because a lot of the data is dynamic

#

Especially since it could be down to whether enough time has passed for it to be loaded into cache

#

Since data isn’t loaded instantly

#

Only when PlayerAdded event is fired is data for the player loaded into their state

sharp geyser
#

Well I got it working in a way that doesn't repeatedly check

#

Instead I subscribe to the getter so that way it will rerun the callback if any changes to the state are made

#
public static get(player: Player): Promise<EchoesPlayer> {
        const existing = this._instances.get(player);
        if (existing) return Promise.resolve(existing);

        const pending = this._pending.get(player);
        if (pending) return pending;

        const promise = new Promise<EchoesPlayer>((resolve) => {
            const unsubscribe = effect(() => {
                const data = getPlayerData(player.UserId);

                if (data) {
                    const wrapper = new EchoesPlayer(player, data);
                    this._instances.set(player, wrapper);
                    this._pending.delete(player);
                    unsubscribe();
                    resolve(wrapper);
                }
            });

            if (!player.IsDescendantOf(Players)) {
                this._pending.delete(player);
                unsubscribe();
            }
        });

        this._pending.set(player, promise);
        return promise;
    }
#

I found this method

#

Not sure what the point of the pending map is if instances already exists but apparently it's for "deduplicating" promises or some shit

quartz kindle
#

if the same player is requested multiple times while its pending, the same promise should be returned

#

once the promise is resolved, the result is delivered everywhere equally

#

when it comes to async, you always need to think in terms of "what should i do if this function is called again while the previous call is still waiting?"

warped sierra
quartz kindle
#

they had a broken recursive load function that would reload every single already-loaded item every time it would load a new item

#

it caused the game to take 20-30min to start

#

some dude got awarded 10k for reporting/fixing it

warped sierra
#

some of gta's comments are wild too

#
// dont know what this does but it broke when i removed it. will check soon - update 5 years later, never checked```
lyric mountain
#

basically a data wrapper that only initializes when requested

sharp geyser
sharp geyser
# quartz kindle yes

How does it work though, it just returns the same promise if it already is there, but what if it's not resolved yet?

#

It'd basically be returning a EchoesPlayer with no data

#

I am ashamed to say that all my years of coding i never took the oppurtunity to truly learn what promises are

lyric mountain
# sharp geyser No idea what that means
class Lazy<T> {
  private final Supplier<T> loader;
  private T obj;
  private boolean loaded;

  public Lazy<T>(Supplier<T> loader) {
    this.loader = loader;
  }

  public T get() {
    if (!loaded) {
      obj = loader.get();
      loaded = true;
    }

    return obj
  }
}
#

something like this

#

it doesnt have a value until you call it the first time

sharp geyser
#

Not quite sure how this would work for me

lyric mountain
#

in your case you'd fetch the server value only when you were going to use it, without re-fetching every time

sharp geyser
#

I already do that

#

I think

#
import { EquipSlot } from 'shared/util/types';
import { IItem } from 'shared/data';
import { PlayerInventory } from './PlayerInventory';
import { getPlayerData } from 'shared/charm/datastore';
import { Players } from '@rbxts/services';
import { effect } from '@rbxts/charm';

export interface IDataTemplate {
    currency: ICurrency;
    inventory: IInventory;
    equipment: IEquipment;
}

export interface ICurrency {
    copper: number;
    silver: number;
    gold: number;
}

export interface IInventory {
    main: Array<IItem>;
    belt: Array<IItem>;
    wear: Array<IItem>;
}

export type IEquipment = Record<EquipSlot, string>;

export class EchoesPlayer {
    private static _instances: WeakMap<Player, EchoesPlayer> = new WeakMap<Player, EchoesPlayer>();
    private static _pending: Map<Player, Promise<EchoesPlayer>> = new Map<Player, Promise<EchoesPlayer>>();

    public readonly profile: IDataTemplate;
    public readonly inventory: PlayerInventory;
    public readonly userId: number;

    private constructor(
        public readonly player: Player,
        data: IDataTemplate,
    ) {
        this.userId = player.UserId;
        this.profile = data;
        this.inventory = new PlayerInventory(this, this.profile.inventory);
    }

    public static get(player: Player): Promise<EchoesPlayer> {
        const existing = this._instances.get(player);
        if (existing) return Promise.resolve(existing);

        const pending = this._pending.get(player);
        if (pending) return pending;

        const promise = new Promise<EchoesPlayer>((resolve) => {
            const unsubscribe = effect(() => {
                const data = getPlayerData(player.UserId);

                if (data) {
                    const wrapper = new EchoesPlayer(player, data);
                    this._instances.set(player, wrapper);
                    this._pending.delete(player);
                    unsubscribe();
                    resolve(wrapper);
                }
            });

            if (!player.IsDescendantOf(Players)) {
                this._pending.delete(player);
                unsubscribe();
            }
        });

        this._pending.set(player, promise);
        return promise;
    }
}
lyric mountain
#

you can make it more elaborate by making it loop as many times as needed until a valid value is returned

sharp geyser
#

Is this what you mean?

#

or do you mean abstracting the profile even further

#

so that only when .profile is accessed is it ever fetched

#

btw effect is a way of subscribing to state aka getPlayerData any time the value in state changes getPlayerData is called again

#

aka profile loaded it goes from null -> profile

lyric mountain
#

it's almost the same thing yeah

quartz kindle
#

it is a reference like any other object, it can be passed around, anywhere you want

#

you can assign it to multiple variables, in multiple places, it will all reference the same Promise

#

for example

let promise;
function a() {
  if(!promise) {
    promise = new Promise(...)
  }
  return promise;
}

const x = a();
const y = a(); // y contains the exact same promise as x

x.then(...); // both can be awaited or .then()ed
y.then(...); // both will receive the same value at the same time once the promise resolves
#

it is recommended to do this kind of promise caching to avoid duplicating tasks, for example:

const requestCache = new Map();
function getResource(someParameter) {
  if(requestCache.has(someParameter)) return requestCache.get(someParameter);
  const promise = fetch(someParameter).then(result => {
    requestCache.delete(someParameter); // delete it from cache once its received
    return result;
  });
  requestCache.set(someParameter, promise);
  return promise;
}
#

this way, if getResource is called multiple times in a short time period, it will only actually fetch the resource once, and the result will be shared with all the calls

#

its basically like "oh we are already fetching what i need? cool, ill join the waiting list for it"

thorn shell
#

Heya quick question
Can i make a public channel where all the votes are displayed?
or is there some privacy concerns and i shouldnt do that

sharp geyser
#

Should be fine, though I don’t see the appeal behind it

lyric mountain
lyric mountain
#

and I'm not the one to praise AI

thorn shell
#

instead of in a public channel

sharp geyser
#

No I mean there is nothing wrong with putting it in a public channel

#

I just dont see a reason to do either

#

They already know they voted, top.gg tells them so when they are done

thorn shell
sharp geyser
#

They should be able to re=run whatever command that needed them to vote to be able to tell that

#

Need vote to run said command? Let them know

#

Is it some reward for voting? Tell them about the reward

#

Either way its fine to put it in a public channel

thorn shell
#

hmm oke thanks for the ideas ❀️

sharp geyser
#

What's the difference between

    public containerVolume(): number {
        return this.slots.reduce((sum, item) => {
            return (sum += item.quantity);
        }, 0);
        // let total = 0;
        // for (let i = 0; i < this.capacity; i++) {
        //     const s = this.slots[i];
        //     if (s) total += s.quantity;
        // }
        // return total;
    }

Using reduce and the commented out portion

#

Does reduce do a loop under the hood as well?

#

I also realize in the commented out portion that if check is useless

#

a slot will never be undefined

#

As the inventory grows dynamically since its not a fixed size

queen needle
#

i mean the commented out is faster, even though reduce uses a for under the hood there are additional checks done, as well as calling the function, but @quartz kindle can give better than i can

sharp geyser
#

Gotcha

#

I figured the for loop was faster

#

but this begs to question

#

Why is it just about everything implemented in js is slower compared to doing it yourself

#

I also just realized

#

It doesn't really matter what I use, since it's transpiled into luau which could be slow cause idk how roblox-ts handles reduce

lament rock
#

Not everyone is Tim

quartz kindle
#

lmao

quartz kindle
#

so using the core js directly will always be faster

sharp geyser
#

gotcha

#

It looks like reduce is transpiled int oa for loop anyway

#
    function ItemContainer:containerVolume()
        local _exp = self.slots
        -- β–Ό ReadonlyArray.reduce β–Ό
        local _result = 0
        local _callback = function(sum, item)
            sum += item.quantity
            return sum
        end
        for _i = 1, #_exp do
            _result = _callback(_result, _exp[_i], _i - 1, _exp)
        end
        -- β–² ReadonlyArray.reduce β–²
        local num = _result
        -- My for loop
        local total = 0
        do
            local i = 0
            local _shouldIncrement = false
            while true do
                if _shouldIncrement then
                    i += 1
                else
                    _shouldIncrement = true
                end
                if not (i < self.capacity) then
                    break
                end
                local s = self.slots[i + 1]
                if s then
                    total += s.quantity
                end
            end
        end
        return total
    end

resulting code

#

What in the fuck is this, why is my for loop so massive compared to the reduce πŸ’€

quartz kindle
#

does lua not have for?

#

half of it is simulating a for using while lol

lyric mountain
#

I think it does

sharp geyser
#

but for whatever reason the official roblox dev who made roblox-ts transpiles loops into while loops

#

πŸ’€

#
function ItemContainer:findSlotByItemId(itemId)
        local index = nil
        do
            local i = 0
            local _shouldIncrement = false
            while true do
                if _shouldIncrement then
                    i += 1
                else
                    _shouldIncrement = true
                end
                if not (i < self.capacity) then
                    break
                end
                local item = self.slots[i + 1]
                if item.itemId ~= itemId then
                    continue
                end
                index = i
            end
        end
        return index
    end
#

As you can see

#
    public findSlotByItemId(itemId: ItemId): number | undefined {
        let index = undefined;
        for (let i = 0; i < this.capacity; i++) {
            const item = this.slots[i];

            if (item.itemId !== itemId) continue;

            index = i;
        }

        return index;
    }
#

This gets turned into the above

queen needle
#

There is probably a reason

sharp geyser
#

Maybe

#

It could be that a while loop is faster

queen needle
#

or semantics or something

sharp geyser
#

or that translating JS/TS for loops to lua is just harder

queen needle
#

"everybody else does it this way so"

sharp geyser
#

I could ask

queen needle
#

btw how is the game going

sharp geyser
#

Oh uhm

#

:)

#

Right so

#

Going to be a single player game making multiplayer games hurt my brain

queen needle
#

yayy

#

how is progress on it

sharp geyser
#

@quartz kindle @queen needle

#

This is apparently why it uses a while loop in some cases instead of a native for loop

queen needle
#

ohhh

sharp geyser
#

I’m trying to make it as extendable as possible so if I want to add more to the game later on it’s not a headache where I have to refactor a bunch of shit

#

So I’m taking a lot of consideration into designing the api

queen needle
#

that's fair

sharp geyser
#

Right now I have my own player class that I wrap around Roblox’s

#

It also stores a reference to the player so I don’t need to keep two player variables

modern wind
#

u

sharp geyser
#

Guys, I am laying out my inventory system and I am running into a conundrum on design

#

My inventory is going to be weight based, more items = higher weight. Now I can handle this 2 ways when it comes to adding items to their inventory

  1. If they are at or going to be past the maxWeight when picking up an item, I refuse to give it
  2. I allow them to pick it up, and any weight past the maxWeight contributes to encumbrance
#

Which would you guys prefer as a game mechanic if you were to play a game with an inventory system

#

I am more leaning towards option 2 myself since that seems to be the most "smooth" approach

#

Also forces a player to start thinking more on balancing weight/encumbrance

dusk pebble
#

give the player the option to keep or drop an item from the inventory

queen needle
#

i like the pokemon go inventory(from my understanding), if i have 392/400 and pick up 10, it lets me pick up 10, but no more, but if it's like 50, that's too much and it won't let me pick it up, so it just has a small threshold of items to go above limit

sharp geyser
#

I mean I dont want to put a hard limit realistically

#

Because realism is sure you have a "max" weight you can carry, but if need be you can carry more

sharp geyser
#

If I was to put a hard limit on weight, i'd do it this way

#

Allow them to pick it up so long as it doesn't go too far over the maxWeight

queen needle
#

especially if it's weight it translates to real ;ife

#

you carry your max, but if need a lil over your max

sharp geyser
#

I need to be careful with weight distribution though

#

I need to make the weight system balanced

queen needle
#

okay statistics

sharp geyser
#

Like defining what an item weighs

sharp geyser
queen needle
#

true

sharp geyser
#

thats over my head

queen needle
#

what types of items will you have

sharp geyser
#

Weapons, Consumables (food, potions), Armor, Quest Items (which will be weightless), and maybe some other things

#

Misc ig is another category, such as books, trinkets, scrolls

queen needle
sharp geyser
#

Honestly I dont think it can be unbalanced unless I apply unrealisitc weight values

prime cliff
#

Look at other shooter games that do weight (fallout) and slot based inventory like how stuff takes up 2x2 or 1x2 grid

sharp geyser
#

So I just gotta be careful not to do that

#

Well its not a shooter game

#

but I get ya

sharp geyser
queen needle
#

like no way an apple is half of this weapon

sharp geyser
#

Yeah

#

I am thinking of making apples weight like .1 or .2

queen needle
#

is it on a scale from 0 to 1?

sharp geyser
#

Nah

#

0-Infinity /j

#

Imagine picking up a sword and it's weight is : Infinite

#

😭

queen needle
#
(Math.random() * (item_name.length + ((Math.random() * items.length) >> 0) >> 0)```
#

here you go gang

#

random weight

sharp geyser
queen needle
#

random weight based on length of items name and amount of items in inventory

sharp geyser
#

Wouldn't that cause problems

queen needle
#

oh 100%

wheat mesa
#

shifting right 0 bits twice?

sharp geyser
#

Apple 1 = 5
Apple 2 = 3

queen needle
#

floors

sharp geyser
#

😭

wheat mesa
#

Is that just a poor man’s floating point to integer conversion

queen needle
#

yes

wheat mesa
#

Ah

sharp geyser
#

WEll I am poor

wheat mesa
#

Java, my favorite

queen needle
#

~~()
Math.floor()
() >> 0

sharp geyser
#

Sword of God Aetheri weight = 0

#

😭

#

But nah

#

I will feed my item list into chatgpt and tell it to give me realisitc weight values

#

Im sure it can handle 300+ items

queen needle
#

it can

#

or just use ai ide

#

boom

sharp geyser
#

True

#

github copilot

queen needle
#

cursor

#

windsurf

sharp geyser
#

never heard of it

wheat mesa
#

One of the main AI IDEs

#

I hate all of them

sharp geyser
#

Lmao

wheat mesa
#

They all suck

#

The code quality is usually pretty terrible, even with the β€œgood” models

sharp geyser
#

For something like this it's perfect though

wheat mesa
#

Yeah since there’s no code involved πŸ˜‰

sharp geyser
#

I was tempted to try and vibe code this entire game

#

but I decided nah I actually want it to be good

#

While I may not be the best programmer I can definitely do better than shitgpt

wheat mesa
#

I think using AI for new concepts isn’t terrible as long as you’re learning as you go

#

Letting AI come up with solutions and not understanding them is bad. Allowing your own thoughts to guide the conversation to getting to the solution you want is the key

queen needle
# wheat mesa I hate all of them

I try every new one I see and never get a difference lol, they all just produce subpar code and only do what you want if you spend more time promoting than you would writing it

wheat mesa
#

The context window is far too small for LLMs to be genuinely good without hand holding. A good SWE can guide an AI into an elegant solution, but a good SWE can also write said solution themselves

queen needle
#

I agree, if you can prompt the AI to create good code, you yourself could write the good code

#

My least favorite thing is seeing people use it for translations though

sharp geyser
#

Right

#

So I am thinking since I have 3 points of inventory

#

Main, Belt and Wear

Main + Belt will affect picking up items, if your maxWeight is reached, you cannot pick up an item that's too heavy, likely have a grace threshold of 5-10lb

Wear's weight will affect movement

long marsh
long marsh
modern wind
#

alguien habla espaΓ±ol?

#

?

long marsh
# long marsh I would qualify myself as a "good SWE" for my company, and it's much faster prom...

My AI usage:

  1. I interpret the acceptance criteria
  2. I browse the code, gather context, understand execution entry and flow
  3. Using something like Claude Code, in plan mode, I give it the files it likely needs to work with, the entry points for it to understand, the acceptance criteria for the current change, and ensure that a CLAUDE.md has the repository structure, development requirements (integration tests, unit tests, minimum coverage, etc.) (me)
  4. Iterate on the plan, ask Claude if it has any suggestions or questions around the change / edge cases I haven't thought of, and get to a step-by-step where it finally seems correct. (me)
  5. Overlook each change Claude does and ensure that it's following convention (me)
    (optional 6. auto-accept once it hits a certain point)
#

☝️ And I'll do this process in parallel with up to 3 changes at once using git worktrees.

queen needle
#

sometimes i'll use 2 ai's, one to come up with a plan for execution, and then one to execute

long marsh
#

I would recommend it 100%

#

It's the only AI tool worth a damn imo

queen needle
#

uhh is that the terminal one?

long marsh
queen needle
#

i've not used it(the terminal scares me)

long marsh
queen needle
#

ooh

long marsh
#

Like I've mentioned in this chat, I specialize in generative AI applications for production workloads

queen needle
#

it's by Bytedance the same company that owns tiktok

sharp geyser
#
        updatePlayerData(this.owner.userId, (data) => ({
            ...data,
            inventory: {
                ...data.inventory,
                currentWeight: this.getWeight(),
                [this._containerName]: this.slots,
            },
        }));

This is valid right?

#

assuming this._containerName is a valid key in the inventory object

sharp geyser
#

Well hey it works

#

Now I just have to make sure that the reference to the profile is also updated

#

Cause right now doing this.inventory it gives stale data from before the item is given

#

I am thinking

#

I have a MarkDirty method that will notify when the data needs to be updated

lyric mountain
long marsh
#

For now, I've been using Zed as my primary editor

lyric mountain
#

I once asked it to help me find a way to detect intentional losses in my game, it worked pretty well but it consumed a third of the quota

sharp geyser
#

Lmao

sharp geyser
#

I hate bugs in code

lament rock
#

Sometimes, bugs become features

sharp geyser
#

and sometimes they make you wanna take a 12 gauge and do yk what

quartz kindle
lyric mountain
fiery crescent
sharp geyser
#

Nah I’m not a girl

long marsh
#

Haha you're right @light vine ☝️ ... thanks for the reference

long marsh
#

It would require me to rethink my current system to do something like that though, unfortunately. May be worth it long term though.

sharp geyser
#

If your current implementation limits expansion you already did something wrong

long marsh
#

This is the way my system currently works:

User types /blackjack <bet> ->
POST /discord/interactions endpoint ->
handler routes to the appropriate interaction handler (named intblackjack in this case) ->
interaction handler calls the cmdblackjack which handles business logic (checking balance, instantiating game state), returns the appropriate actions they can take (insurance, double, hit, stand, etc.) ->
interaction handler marshals the DTO to a JSON payload required by discord with the buttons / cards ->
complete

#

All this happens in under 3 seconds, so I don't need to call back into discord with an interaction update. I respond within the 3 second threshold.

#

This is using the HTTP interaction handler. No sharding. No websocket gateway. MINIMAL server overhead.

#

And will likely scale to hundreds of thousands of simultaneous players without problems. Which is crucial since I want to use this API to handle multiple "chatting" experiences. Twitch, Slack, etc.

sharp geyser
#

Right so what’s the issue then

long marsh
#

Since my architecture is stateless, I can't necessarily update the same message within the same execution context. If I want to send 3 separate updates to the same message, I would need to likely "queue" up something to update that message.

#

Keep in mind, I need to respond within 3 seconds.

#

What I'm trying to say is: no actual problem. Just won't work with the current way I'm doing it.

#

Will need to do:

User types /slots <bet> ->
POST /discord/interactions endpoint ->
handler routes to the appropriate interaction handler (named intslots in this case) ->
interaction handler calls the cmdslots which handles business logic (checking balance, instantiating game state), returns the resolved game state, "queue" up something to update the message with the rotating slots
interaction handler marshals the DTO to a JSON acknowledgement payload
complete

... (some time later) ...

the queue fires off -> goes and updates the message

#

And that entire "queue" process seems complex for something as simple as slots 🀣

#

Another option is to return a 201 acknowledgement, but continue the execution, therefor not need queuing πŸ€·β€β™€οΈ

#

Hmm... thinks for being my rubber duck! I realized I could simply just update the player's balance ahead of the emojis completing, but still render using a goroutine πŸ™‚ thanks @sharp geyser !

#

Something like this:

func handler(w http.ResponseWriter, r *http.Request) {
    // Send immediate response
    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]string{
        "status": "accepted",
        "message": "Processing in background",
    })
    
    // Start background processing
    go func() {
        // This runs after the response is sent
        time.Sleep(10 * time.Second)
        log.Println("Background task completed")
        // Process data, update database, send emails, etc.
    }()
}
sharp geyser
#

Yeah

#

So long as you respond ahead of time

#

Even using the api you can edit interactions within a certain time period as well

#

It may not be as clean as owo bot

#

but people have to understand you aren't using a gateway so you can't leverage most of what others do

long marsh
# sharp geyser Even using the api you can edit interactions within a certain time period as wel...

I actually think I can get it just right. I'll likely do something like this (rethinking through this again):

func handler(w http.ResponseWriter, r *http.Request) {
    // Parse request data first
    var data RequestData
    if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
        http.Error(w, "Invalid JSON", http.StatusBadRequest)
        return
    }
    
    // Start processing with the parsed data
    go func() {
        log.Println("this is where I can update the message here", data.ID)
    }()
    
    // Respond immediately that we've accepted it
    w.WriteHeader(http.StatusAccepted)
    json.NewEncoder(w).Encode(map[string]string{
        "status": "accepted", 
        "id": data.ID,
    })
}

This isn't catered towards discord, but you get the idea

#

The goroutine that's running in the background will update the message. The initial message will have rotating emojis.

#

Once again, @sharp geyser (sorry for that @ yet again haha), just wanted to thank you for showcasing owo's example. It spawned this idea haha

sharp geyser
#

I didn't show it

#

but no problem

long marsh
dusk pebble
#

ahhh

#

on github?

stark kestrel
#

by sharing the code here, yes

#

@solemn latch worth monitoring btw, iirc that message is that typical "try my game!!!" scam

real rose
#

do i need to download code from github D10giggle

stark kestrel
#

the profile also screams that

real rose
#

looks about right

#

i dont want to find out either kek

#

If its legit and they appeal then fair enough

#

(unlikely)

stark kestrel
#

would've loved to see the exe 😭

prime cliff
#

Yea something is off about that account because their Discord avatar dosen't match up with their connected youtube account avatar, the youtube one also has 3k subs with no content

long marsh
dusk pebble
long marsh
dusk pebble
long marsh
dusk pebble
#

no worries

long marsh
dusk pebble
#

ahhh nice

long marsh
#

Admittedly, I don't need a library wrapper for the HTTP interaction response model. It's as simple as wiring up an endpoint and having discord make POST requests to it.

dusk pebble
#

yeah

long marsh
#

If you're curious about the bot, it's simply used to gamble πŸ™‚

dusk pebble
dusk pebble
#

yeah, also adding a kind of lottery game where 3 numbers are drawn twice a day, if the member matches these numbers they get xtra coins

sharp geyser
#

@queen needle @radiant kraken after numerous bug hunts and squashing most if not all of them. The inventory system is existent and functional (somewhat)

#

No UI for it yet

#

but at the very least it's server api exists

sharp geyser
#

A game

prime cliff
fiery crescent
slow flax
prime cliff
clever tundra
#

Does anyone know a status / uptime site which I can actually customise to use the response data of my endpoint? Basically I have a fastapi thing with a /ping endpoint which I use ngrok to get a URL for, and then smth like betteruptime or the other main one to show the uptime, however I want to be able to use the data from my endpoint to show like bot uptime and latency and server counts etc on the page. Does anyone know of a free one that can do this? Bonus points if you can use custom domains on it.
If not then I guess I have to go through the pain of making my own thing from scratch again

prime cliff
#

That sounds like something very custom i've never heard of status services using metadata but that sounds like a neat idea

clever tundra
#

I tried better stack and uptimerobot but uptimerobot can't use custom domains without paying, and betterstack only lets you use custom .js if you pay. Only other option is make my own and host with vercel but don't really want to spend time doing that.

#

The hardest part about bot development is not being able to pay for stuff. Docs? Find an alternative. Uptime monitoring? Find an alternative.

prime cliff
#

For docs stuff i use gitbooks some stuff is paid but it gets the job done and you can use custom domain but you have to use a specific setting

digital swan
prime cliff
clever tundra
#

The only thing I dislike is how retype doesnt have the like 1 2 3 steps bit

clever tundra
stark kestrel
#

E.g. docusaurus is quite a good one

#

Just host it on github pages and it's more than enough

clever tundra
#

The only reason I went with what I did is because I started using gitbook, made quite a bit and then couldn't be asked to remake it on another site

stark kestrel
#

It's just markdown

prime cliff
dusk pebble
#

bot approved embed should have a link to the bot page..... just a suggestion

stark kestrel
dusk pebble
clever tundra
#

I also cant find that

prime cliff
#

Ah

#

So they fully went paid yea that sucks, i probably have legacy access

clever tundra
#

shame

#

ok

clever tundra
#

oh hold on no its a case of markdown files

digital swan
#

It’s easy peasy

#

It’ll be free to host too

clever tundra
#

so are my existing docs

#

i need to edit most if not all of the markdown in my current files to be able to work with starlight tho

lunar flicker
celest trail
#

my bot is online at this very moment, but when adding it to other servers, apparently it is not staying online for other discord users. how can I solve this?

neon leaf
#

@solemn latch

prime cliff