{"id":21156276,"url":"https://github.com/9551-dev/pixelbox_lite","last_synced_at":"2025-07-09T12:32:25.688Z","repository":{"id":247560876,"uuid":"822831238","full_name":"9551-Dev/pixelbox_lite","owner":"9551-Dev","description":"Very fast and modular teletext character renderer for Computercraft","archived":false,"fork":false,"pushed_at":"2024-08-20T19:05:51.000Z","size":3179,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-08-20T21:14:10.044Z","etag":null,"topics":["2d","cctweaked","characters","computercraft","lua","modular","pixelbox","renderer","teletext"],"latest_commit_sha":null,"homepage":"https://pixels.devvie.cc","language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/9551-Dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-01T23:22:55.000Z","updated_at":"2024-08-20T19:05:54.000Z","dependencies_parsed_at":"2024-07-09T11:45:33.851Z","dependency_job_id":"3ab863a1-ca5b-4adc-9133-632131ab8e47","html_url":"https://github.com/9551-Dev/pixelbox_lite","commit_stats":null,"previous_names":["9551-dev/pixelbox_lite"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/9551-Dev%2Fpixelbox_lite","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/9551-Dev%2Fpixelbox_lite/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/9551-Dev%2Fpixelbox_lite/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/9551-Dev%2Fpixelbox_lite/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/9551-Dev","download_url":"https://codeload.github.com/9551-Dev/pixelbox_lite/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225541711,"owners_count":17485778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["2d","cctweaked","characters","computercraft","lua","modular","pixelbox","renderer","teletext"],"created_at":"2024-11-20T11:41:22.210Z","updated_at":"2024-11-20T11:41:22.706Z","avatar_url":"https://github.com/9551-Dev.png","language":"Lua","readme":"\n# \u003cimg src=\"assets/logo.png\" alt=\"logo\" width=\"50\"/\u003e PIXELBOX LITE\n\n### About\n***Very fast*** ComputerCraft library used for rendering graphics with teletext characters (\\128-\\159)\n\n\u003cimg src=\"assets/charset.png\" alt=\"logo\" width=\"50%\"/\u003e\n\n### What is this and why do i need it?\nPixelbox *lite* is a \"minimal\" library for drawing 2D graphics (color buffers) to the terminal/windows\nin CC:T.\n\nIts main objective is to be\n- **very fast**\n- lightweight (minified fits into under 5kB)\n- easy to use/integrate\n- modular (provides a way to load modules, and for modules to be created)\n- flexible (in terms of what you can actually have it do)\n- display quality (there are some extra snippets for denoising)\n\nWith pixelbox lite you can technically get 6x more pixels out of your terminal, each character can now be a block of 3x2 pixels\n\nHere you can see the same terminal resolution (default computer: 51x19 chars) being filled with random colors, without and with pixelbox\n\n![](assets/random_base.png)\n![](assets/random_pixelbox.png)\n\n### Installation\nInstalling is a very simple as its just a singular file\n```\nwget https://raw.githubusercontent.com/9551-Dev/pixelbox_lite/master/pixelbox_lite.lua\n```\n\n## Modularity\nSome info about the modularity of pixelbox can be found [here](#modules)\n\nFor a list of modules and info about them you can check out https://github.com/9551-Dev/pixelbox_modules\n\n## Basic usage\nAs for the usage its pretty simple to get started\n- require the api\n- use the `new` function to make a `box` object for your desired terminal\n- write to its `canvas` property of the box, which is a 2D array (`canvas[y][x] = color`; `color = 2^n; 0\u003c=n\u003c=15`)\n- run the render method, and thats it.\n\nHeres an example of how that could look\n```lua\nlocal box = require(\"pixelbox_lite\").new(term.current())\n\n-- blue vertical line\nbox.canvas[5][5] = colors.blue\nbox.canvas[6][5] = colors.blue\nbox.canvas[7][5] = colors.blue\n\n-- disconnect on it\nbox.canvas[6][6] = colors.blue\n\n-- yellow vertical line\nbox.canvas[5][7] = colors.yellow\nbox.canvas[6][7] = colors.yellow\nbox.canvas[7][7] = colors.yellow\n\n-- display to terminal\nbox:render()\n```\nHeres what this produces\n\n![](assets/results/r1.png)\n\nInstead of defining stuff like hand like we did here, how about we use some for loops to make some interesting patterns\n```lua\nlocal box = require(\"pixelbox_lite\").new(term.current())\n\nlocal n,m,scale  = 0.9,7.8,30\nlocal full_color = 15/4\n\nfor i=0,15 do local c = i/15 term.setPaletteColor(2^i,c,c,c) end\n\nfor y=1,box.height do\n    for x=1,box.width do\n        box.canvas[y][x] = 2^math.floor(((\n            math.sin(n*math.pi*x/scale) *\n            math.sin(m*math.pi*y/scale) +\n            math.sin(m*math.pi*x/scale) *\n            math.sin(n*math.pi*y/scale)\n        )*full_color)%15)\n    end\nend\n\nbox:render()\n\nos.pullEvent(\"char\")\nfor i=0,15 do term.setPaletteColor(2^i,term.nativePaletteColor(2^i)) end\n```\nJust like this\n\n![](assets/results/chladni.png)\n\n## api functions\nHere i will show the functions which are actually under the pixelbox api, to access these you would actually have to make a separate variable for pixelbox like this\n```lua\nlocal pixelbox = require(\"pixelbox\")\nlocal box = pixelbox.new(term.current())\n...\n```\ninstead of the classic\n```lua\nlocal box = require(\"pixelbox\").new(term.current())\n```\n#### Values\n- pixelbox.initialized`[boolean]`: remains false until `pixelbox.new` is ran, used to tell pixelbox when to generate its lookup tables (so they arent generated multiple times)\n- pixelbox.license`[string]`: stores pixelbox'es MIT license\n- shared_data`[table]`: unused by default, designed to be used by plugins to communicate between each other.\n\n#### Methods\n- `pixelbox.new(window,[background],[modules])`: makes a new `box` object given a window/terminal object and an optional background color, if a color is not given the terminals current `backgroundColor` is used. Also allows for loading of pixelbox modules via third argument (array of modules, runs box:load_module internally pre-pixelbox init, pixelbox.initialized == false)\n- `pixelbox.make_canvas([source_table])`: makes a bare pixelbox canvas, this doesnt contain any values/information yet other than an OoB (Out of Bounds) metatable (this metatable is actually a type of pixelbox `canvas_scanline` which has the y_position set as `\"NONE\"`) for handling writes outside of the canvas. Can be populated via `pixelbox.setup_canvas()`. Argument allows you to use any existing table to make the \"bare\" canvas, it will just attach a metatable.\n- `pixelbox.make_canvas_scanline(y_position)`: Makes a canvas scanline \"object\", pretty much only meant to be used internally, these objects check all of their new data writes to make sure they didnt try to write onto a floating point location, if they do. Throws an error, giving the index as the x coordinate and a y_position value given at creation value as the y coordinate.\n- `pixelbox.setup_canvas(box,bare_canvas,color)`: makes a canvas fit to be used with a specific `box` object given a box, a bare canvas and a color to fill the background/empty data with\n- `pixelbox.restore(box,color,[keep_existing])`: either (depending on keep_existing, true doesnt make a completely freash canvas) gives a `box` object a completely new canvas given a color or completely rewrites existing one (used portion) with a given color\n- `pixelbox.module_error(module,error_message,[level],[error_supress])`: used internally and also meant to be accesed aby modules to throw their error, handles report messages, error level shifting, module dev contacts and some other stuff, error_supress makes function not do anything, primarily used just to make some internal pixelbox_lite.lua code neater\n\n## data\nHere i will tell ya a bunch of useful data you can get from the `box` object\n\n#### Values\n- box.canvas`[table[y][x]]`: 2D buffer of colors used to tell pixelbox what to draw\n- box.CANVAS`[table[y][x]]`: same as canvas. Exists for back compat reasons\n- box.term`[window]`: holds the terminal object the box is meant to be rendered to\n- box.term_width`[number]`: Width of the terminal being drawn to in characters\n- box.term_height`[number]`: Height of the terminal being drawn to in characters\n- box.width`[number]`: Width of the terminal being drawn to in \"pixels\" (term_width*2)\n- box.height`[number]`: Height of the terminal being drawn to in \"pixels\" (term_height*3)\n- box.background`[number]`: holds the default background color for when the screen is being cleared\n- box.modules`{[module.id]={MODULE_DATA},module_functions={ELEMENT_INDEX}}`: Holds almost all the data related to pixelboxes modularity, stores each module under its id, also holds a shared index (`module_functions`) of all elements directly added to `box` via modules through the api\n\n#### Methods\n- `box:render()`: has pixelbox process the color buffer (canvas) and write the result to its output window object (box.term)\n- `box:clear([color])`: fills the canvas with either a given color or the current `box.background` color if one is not provided or is invalid\n- `box:load_module([{MODULES/FLAGS}])` loads an array of modules and eats up flags (load settings), usable flags: `[supress,force]`, `supress` supresses any errors thrown by the sanity-checker within `box:load_module`, this might for example be a module id or a module field name conflict, `force` on the other hand doesnt just supress errors, it has it override all problematical issues, this disables the sanity checker but also has it do whatever it wants to do.\n\nSuggested usage:\n```lua\nbox:load_module{\n    require(\"pb_modules/module1\"),\n    require(\"pb_modules/module2\"),\n    require(\"pb_modules/module3\"),\n    -- ...\n\n    force   = false,\n    supress = false,\n}\n```\n- `box:set_pixel(x,y,color)`: function for setting colors in the canvas, i have no idea why you would use this. Essentially box.canvas[y][x] = color\n- `box:set_canvas(canvas)`: easily allows you to swap the boxes canvas given one.\n- `box:resize(w,h,color)`: recalculates width/height values and rewrites the canvas to a new given size, filling it with a given color or `box.background` if one is not given\n- ~~**`box:analyze_buffer()`**: reads all the data in the `canvas` which is meant to be used with the current setting, checks for canvas, scanline, pixel and color value validity, throws an error if something is invalid. **Returns true on all checks passed**~~ deprecated, moved into its own separate module [PB_MODULE:analyzer](https://github.com/9551-Dev/pixelbox_modules?tab=readme-ov-file#pixelbox-analyzer)\n\n## More complex usage\njust to show what you can do, i will take previous H example but setup the canvas completely by hand\n```lua\nlocal pixelbox = require(\"pixelbox_lite\")\nlocal box      = pixelbox.new(term.current())\n\nlocal bare_canvas   = pixelbox.make_canvas()\nlocal usable_canvas = pixelbox.setup_canvas(box,bare_canvas,colors.black)\n\n-- blue vertical line\nusable_canvas[5][5] = colors.blue\nusable_canvas[6][5] = colors.blue\nusable_canvas[7][5] = colors.blue\n\n-- disconnect on it\nusable_canvas[6][6] = colors.blue\n\n-- yellow vertical line\nusable_canvas[5][7] = colors.yellow\nusable_canvas[6][7] = colors.yellow\nusable_canvas[7][7] = colors.yellow\n\nbox:set_canvas(usable_canvas)\nbox:render()\n```\nYou could also just use an empty table instead of `pixelbox.make_canvas` but that wont have protection against writing outside of bounds. Thats why i rather recommend passing in a source_table to it\n\n---\n\n## Modules\nAn example use of the module api:\n\n`test.lua`\n```lua\nlocal pixelbox = require(\"pixelbox_lite\")\nlocal box      = pixelbox.new(term.current(),nil,{\n    require(\"test_module\"),\n    require(\"test_module_2\")\n})\n\nbox:load_module{\n    require(\"test_module\"),\n    require(\"test_module_2\"),\n    supress = true,\n}\n\nfor y=1,box.height do\n    for x=1,box.width do\n        box.canvas[y][x] = 2^math.random(0,15)\n    end\nend\n\nbox.bd.set_box(2,2,9,6,colors.red)\nbox.bd.set_dot(1,1,3,colors.blue)\n\nbox:render()\n\nterm.setTextColor(colors.pink)\nprint((\"Box drawer loadstate: %q\"):format(box.state.get_box_drawer_loadstate()))\n\nbox:throw()\n\nos.pullEvent(\"char\")\n```\n\n`test_module.lua`\n```lua\nreturn {init=function(box,module,api,share,api_init)\n    return {\n        throw=function()\n            api.module_error(module,\"Oopsie daisy \u003ew\u003c\",2)\n        end,\n        bd={\n            set_box=function(x,y,w,h,color)\n                for y_iter=y,y+h-1 do\n                    for x_iter=x,x+w-1 do\n                        box.canvas[y_iter][x_iter] = color\n                    end\n                end\n            end,\n            set_dot=function(x,y,diameter,color)\n                diameter = diameter - 0.5\n\n                local half_dia = diameter/2 - (diameter/2)%1\n                for y_iter=y-half_dia,diameter+y do\n                    for x_iter=x-half_dia,diameter+x do\n                        box.canvas[y_iter][x_iter] = color\n                    end\n                end\n            end,\n            field=\"teehe\"\n        }\n    },{\n        verified_load=function()\n            share[module.id] = {init_state=not api_init}\n        end\n    }\nend,id=\"9551:box_drawer\",name=\"box drawer\",author=\"9551\",contact=\"https://ligma-hotline.uwu\",report_msg=\"\\nMrow:3 -\u003e %s\"}\n```\n\n`test_module_2.lua`\n```lua\nreturn {init=function(box,module,api,share,api_init)\n    return {\n        state={get_box_drawer_loadstate=function()\n            return share[\"9551:box_drawer\"].init_state\n        end}\n    }\nend,id=\"9551:etc_plg\",name=\":3\",author=\"9551\",contact=\"https://ligma-hotline.gay\",report_msg=\"\\nMeow:3 -\u003e %s\"}\n```\n\n---\n## Some stuff made with Pixelbox\n![](assets/examples/isometrih.png)\n![](assets/examples/fractal3.png)\n![](assets/examples/fractal2.png)\n![](assets/examples/render.png)\n![](assets/examples/fractal1.png)\n![](assets/examples/img1.png)\n![](assets/examples/img2.png)\n![](assets/examples/img3.png)\n\n---\n### credit\n\n- [HaruCoded](https://github.com/Kariaro) for coming up with the algorithm used to minimize memory usage and speed of character lookups (Smart pep :3)\n\n---\n\n**Meow :3**\nhttps://devvie.cc","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F9551-dev%2Fpixelbox_lite","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F9551-dev%2Fpixelbox_lite","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F9551-dev%2Fpixelbox_lite/lists"}