今日已更新 380 条资讯 | 累计 29142 条内容
关于我们

标签:#p

找到 12051 篇相关文章

开发者

Designing a Movement Transaction System for a Sokoban Game

Context My multiplayer game Lights Out is based on a 2D grid. Entities can only ever be in exactly one grid tile. This makes the rule evaluation really simple and understandable. However, it doesn't really feel nice to play (which you know if you've ever played any of the PuzzleScript games). At the same time, the more content is in the game, the more complex and arbitrary the game rules become. I therefore introduced the Movement Transaction System into the code base to deal with this. This includes two sides: - The gameplay code on server side deals with transactions. This bundles all movement code (including rule evaluation) into a single system. - The visualization & prediction code on client side deals with visual interpolation for moves (introducing some juice into the gameplay feel), based on the transactions managed by the server. The Transaction A single transaction includes the movement delta, a list of entities that it has affected and some flags. A transaction then undergoes several stages: - Queued : Gameplay code has requested an entity to move - Issued : The visual interpolation for the transaction has started in the client, but the entities have not been moved from a gameplay perspective - Committed : The entities have now been moved onto their new tiles, the visual interpolation is finishing - Aborted : The transaction couldn't be committed as it would've violated gameplay rules. Visual interpolation is reversed. The Visual Interpolation Whenever a transaction is issued on server-side, the server tells the clients to start a visual interpolation based on the transaction. This information includes the desired duration of the interpolation, as well as some flags (like whether to use acceleration or do a linear interpolation). The client then updates the visual interpolation every frame, until the transaction is either aborted or the target position has been reached. Simplifying Gameplay Code This new system has made the gameplay code much simpler. I c

2026-08-07 原文 →
AI 资讯

🧹 From Urban Gardens to Clean Streets: Building a Decentralized Robot Ecosystem with MyZubster and Monero"

What started as a vision for mapping urban gardens has evolved into something much bigger. Over the past weeks, we've built a complete decentralized ecosystem that connects IoT sensors, robots, and communities using Monero (XMR) and MYZ tokens. The Journey: From Gardens to Streets It all began with a simple idea: create a map for urban gardens. But we quickly realized that a map alone wasn't enough. We needed a full system that could: Monitor soil health in real-time Automate irrigation and analysis Enable private, decentralized payments Connect communities and institutions Here's what we built. 🗺️ The Urban Garden Map Using Leaflet.js and a REST API, we created an interactive map where anyone can register their urban garden. The map supports: Geolocation with /nearby endpoint Full CRUD operations for gardens Search by name and city Check it out: Live Demo 📡 Arduino Sensors for Smart Agriculture We integrated Arduino sensors to monitor soil conditions in real-time: pH (0-14 scale) EC (Electrical Conductivity) Temperature and Humidity The data flows through Node.js APIs and is stored in MongoDB, making it accessible for analysis and reporting. 🦾 The Robot Ecosystem We built a family of software robots that can receive payments automatically in MYZ and XMR: 1. AgricoloBot - The Garden Assistant Monitors soil health Generates automatic reports Provides recommendations for farmers 2. Robot Arm - The Physical Gardener 4 DOF (Degrees of Freedom) Controlled via WebSocket Can water, plant, analyze, and harvest 3. CleanStreetBot - Street Cleaning Robot Reports waste with geolocation Automates zone cleaning Generates reports for municipalities 4. RecicloBot, PuliziaBot, CompostBot - Recycling and Waste Management Monitor containers and optimize collection routes Track composting and organic waste management 💰 Decentralized Payments with Monero and MYZ All robots receive automatic payments through an escrow system: 85% → Robot owner 2% → MyZubster platform 8% → Bosco Community

2026-08-06 原文 →
AI 资讯

Migrating From S3 to Branch-Aware Storage

If your files already live in Amazon S3, the pitch for storage that branches with your database is appealing but the word "migration" makes it sound like a project. It mostly is not. Neon's object storage speaks the S3 API, so the code you already wrote, the AWS SDK calls and presigned URLs, keeps working. What changes is how you point the client and where the bucket comes from, and that is a small, mechanical diff. The actual data move is a copy loop you can run once. The one thing to do up front is confirm the object operations your app actually relies on: the demo here exercises PutObject , GetObject , listing, and presigned URLs, and I flag the S3 features you should check for yourself further down. This post is the practical version: what stays identical, the exact config that changes, a script to copy the objects across, and an honest list of the S3 features that do not have an equivalent so you know what to check before you commit. The repo with the working client is at the end. TL;DR Neon object storage is S3-compatible. Your @aws-sdk/client-s3 code for the common operations, PutObject , GetObject , getSignedUrl , listing, works unchanged (these are what the demo verifies). Confirm anything beyond that, like multipart for large objects, against the current preview. The diff is the client config: point endpoint at the Neon storage endpoint, pin region: 'us-east-2' , set forcePathStyle: true . The bucket is declared in neon.ts instead of created in the console, and credentials are injected per branch. Move the data with a list-and-copy loop between two S3 clients (source AWS, destination Neon). What does not carry over: S3 bucket policies, event notifications and Lambda triggers, storage classes and Glacier transitions, and cross-region replication. Object CRUD and presigning do. The payoff is everything else in this series: once the files are on Neon, they branch with your database. Prerequisites An existing S3 bucket and credentials that can read it A Neon p

2026-08-06 原文 →
AI 资讯

Apple increases trade-in offers and adds new Android devices

Apple bumped up its trade-in offers for iPhones, iPads, Macs, Apple Watches, and certain Android phones, with some devices now worth over $100 more, 9to5Mac reports. The Mac Studio's trade-in value increased the most, going up by $260. While some devices' offers are unchanged, most got an increase of around $5 to $20, with a […]

2026-08-06 原文 →
AI 资讯

Stop Standing Up an S3 Bucket Per Preview Environment

If your app stores files and you want real preview environments, you eventually hit the same wall: each preview needs its own storage, so you start provisioning a bucket per environment. That sounds cheap until you write it down. For every ephemeral environment you create a bucket, attach a policy, mint an IAM role or access keys, set CORS, add a lifecycle rule so it eventually cleans up, wire the credentials into the preview's config, and register a teardown step for when the PR closes. Then you find the orphaned buckets the teardown missed, months later, still billing. The reason this is painful is that the bucket is a separate resource from the database, so it needs its own lifecycle. Neon collapses that: the bucket is declared as part of the branch, so it is created and destroyed with the branch and needs no per-environment provisioning at all. This post compares the two approaches and shows the branch version working with no bucket-management code in sight. The repo is at the end. TL;DR Isolated storage per preview usually means provisioning a bucket per environment: policy, IAM, CORS, lifecycle, credential wiring, teardown. It is slow, it drifts, and it leaves orphaned buckets that keep costing money. On Neon the bucket is declared once in neon.ts . Creating a branch brings the bucket (with a copy-on-write copy of the files) and injects scoped credentials; deleting the branch removes it. There is no per-environment bucket to create, no IAM role to mint, and nothing to orphan. Copy-on-write means fifty preview buckets do not cost fifty times the storage, only what each one changes. Prerequisites A Neon project on the platform preview (object storage, us-east-2 ) The Neon CLI, and a CI system that opens/closes preview environments Familiarity with S3 buckets and IAM if you have done the manual version The per-environment bucket, written out Here is what "just give the preview its own bucket" actually expands to, per environment: Create a bucket with a unique nam

2026-08-06 原文 →
AI 资讯

Building a Reliable AI Image Pipeline: Tasks, Failures, and Credit Refunds

Most AI image generators look like a prompt box with a Generate button. That is also how my first version started. But once real users entered the workflow, the difficult problems appeared somewhere else: browser refreshes, external task IDs, reference images, partial failures, credit refunds, private assets, and public artwork moderation. While building Magggic , I learned that an AI image generator is less like a form submission and more like a small distributed job system. This article covers the decisions that made that workflow more reliable. The code samples below are intentionally simplified. The important part is the shape of the workflow, not a specific database or image provider. The prompt box is only the beginning A synchronous prototype is easy to imagine: const images = await provider . generate ( prompt ); return images ; That version works until the request takes a minute, the provider times out, one of four requested images fails, or the user refreshes the page. The production workflow I needed looked more like this: Prompt + references ↓ Create a local queued task ↓ Charge credits with an idempotency key ↓ Submit work to the image provider ↓ Persist every completed output immediately ↓ Finalize the task and refund failed outputs ↓ Keep the result private until the user publishes it The provider request is only one step. The local task is the source of truth for what the user sees. 1. Persist the task before calling the provider The first important decision was to create a generation record before making the external API request. A generation stores the information needed to reconstruct the job: type Generation = { id : string ; userId : string ; idempotencyKey : string ; prompt : string ; referenceImages : string []; model : string ; ratio : string ; resolution : string ; count : number ; cost : number ; status : " queued " | " generating " | " completed " | " failed " ; outputs : string []; providerRequestIds : string []; failureReason : string |

2026-08-06 原文 →
AI 资讯

Google's Custom Search image API dies in 2027. Two traps in replacing it.

Google's Custom Search JSON API is closed to new customers, and existing customers have until 2027-01-01 to move off it. That deadline takes searchType=image with it. I maintain cse-bridge , a small self-hosted service that speaks Google's customsearch/v1 wire format on top of your own SearXNG instance, so migrating is a base-URL change rather than a rewrite. Web search shipped first. This week I added image search — and it turned out to be much less mechanical than "map some more fields", because two of the assumptions that hold for web results are actively wrong for image results. Both are worth knowing whether or not you ever use my code. If you are writing anything that normalises image search results, you will hit them. Trap 1: link is not the page For a web result, Google's link is the URL of the page. Easy. For an image result, link is the image file itself , and the page it was found on lives in image.contextLink : { "link" : "https://facts.net/wp-content/uploads/2020/08/AdobeStock_209028852.jpeg" , "displayLink" : "facts.net" , "image" : { "contextLink" : "https://facts.net/nature/animals/red-panda-facts" , "thumbnailLink" : "https://ts1.mm.bing.net/th?id=OIP.I_aIcVvl98DbktQmP297ugHaE7&pid=15.1" , "width" : 4000 , "height" : 2666 } } SearXNG has it the other way round: the result's url is the page, and the image is in a separate img_src field ( documented here ). So the naive mapping — reuse the web mapper, add an image object — produces items whose link points at an HTML document. That fails silently , which is what makes it nasty. Your JSON still validates. Your item count is right. Every field is a well-formed URL. But every client that does <img src={item.link}> — which is the entire point of image search — renders nothing, and it looks like the images are broken rather than like your mapper is wrong. The fix is a rule, not a patch: if a result has no image URL, drop the whole result . Never fall back to the page URL to keep the count up. export functio

2026-08-06 原文 →
AI 资讯

I Did 52 WHOIS Lookups On Attackers — Here's What I Learned

security #api #webdev #discuss The chat went live at 2 PM. By 2:14 it was a war zone. I thought adding real-time chat to my dev blog would spark pair-programming threads. Instead, bots flooded it with phishing links and slurs. One bot even dropped an oddly specific threat about my home city. I flipped on request logging. In the next 24 hours it logged 52 distinct attacker hostnames. IP bans did nothing. They came back from new IPs, new ASNs, new registrars. IP bans felt like swatting flies. I wanted to know what these domains actually were. That's when I started bulk-WHOISing every domain they posted. What 52 hostile domains actually look like I wrote a small Python runner. Feed it a list of hostnames and it spits out JSON. The first version used public RDAP servers directly. Public RDAP servers were slow, rate-limited, and ccTLDs broke them. I wanted DNS, SSL, subdomains, email history, and takeover risk in the same response. I landed on the enrichment endpoint at RapidAPI and put the script on GitHub . import json , time , sys , os from urllib.parse import quote import requests RAPIDAPI_KEY = os . environ . get ( " RAPIDAPI_KEY " , "" ) BASE_URL = " https://domain-whois2.p.rapidapi.com/whois " HEADERS = { " X-RapidAPI-Key " : RAPIDAPI_KEY , " X-RapidAPI-Host " : " domain-whois2.p.rapidapi.com " } def lookup ( domain : str ): url = f " { BASE_URL } ?domain= { quote ( domain ) } " try : r = requests . get ( url , headers = HEADERS , timeout = 20 ) r . raise_for_status () return r . json () except requests . exceptions . Timeout : return { " domain " : domain , " error " : " timeout " } except requests . exceptions . HTTPError as e : return { " domain " : domain , " error " : f " http { e . response . status_code } " } except Exception as e : return { " domain " : domain , " error " : str ( e )} def batch ( domains , delay = 0.6 ): results = [] for d in domains : print ( f " [*] { d } " , file = sys . stderr ) results . append ( lookup ( d )) time . sleep ( delay ) r

2026-08-06 原文 →
AI 资讯

Presigned-URL Uploads From a Serverless Function

The naive way to accept file uploads is to POST them to your API, let the server read the bytes, and write them to object storage. It works until the files get large or the traffic gets real. Now every upload crosses your infrastructure twice, once from the client to your server and once from your server to storage, and your server holds the whole file in memory or on disk while it does. On a serverless function it is worse, because functions have request-size and duration limits that a big upload runs straight into. Presigned URLs are the standard fix, and they predate serverless by a decade. Your server does not move the bytes; it hands the client a short-lived, pre-authorized URL and the client uploads directly to object storage. The server only issues permission and records metadata. On a Neon Function this is the same AWS S3 SDK you already use, pointed at the branch's storage endpoint. This post builds it and tests the whole round trip. The repo is at the end. TL;DR Proxying uploads through a function sends the bytes across it, burning bandwidth and memory and hitting request-size limits. A presigned URL is a time-limited, pre-authorized link to one object key. The client PUTs the bytes straight to storage; the function never touches them. On Neon Functions you generate it with getSignedUrl from @aws-sdk/s3-request-presigner , the same code as any S3-compatible store. I tested the full flow: presign, the client PUT straight to storage returned 200 , a metadata record was saved, and downloading the object returned the exact bytes. One gotcha to pin: the injected AWS_REGION is the storage-cell host, not a region, so set region: 'us-east-2' on the client. Prerequisites A Neon project on the platform preview with a declared bucket (object storage, us-east-2 ) The AWS SDK: @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner Familiarity with S3-style object storage and HTTP PUT Why not just proxy the upload Sending the file through the function has three costs that

2026-08-06 原文 →