Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
github.com/thommil/tge
TGE aims to provide a light, portable and unopiniated runtime to integrate your favorite Go libraries (at least mines) to portable applications (dektop, web & mobile) and package them in a proper way (not a mere executable).
TGE is not and should not be another new game engine but instead a way to focus on business code and not low level pipes and hacks. The core is intended to be as light as possible and depends on plugins to enable cool features (OpenGL, AL, Vulkan, GUI...)
TGE runtime benefits from power ful channels paradigm of Go to propose rendering across 2 synchronized loops Ticker and Render:
See it in action in tge-examples and look below for more details.
An online demo (Work in Progress) is also available here : http://tge-demo.thommil.com
Core implements a minimal runtime for several platforms:
Plugins allow to create your game/application by choosing implementation for different parts (GUI, rendering, sound...). This way, you choose how to create your game/application. I'm trying to port as many features as I can in plugins, natively portable libraries are off course directly usable too (physics, AI...).
Plugin link | Details |
---|---|
tge-gesture | Gestures for touch screens with support for Android, IOS and mobile browsers. Implements longpress, swipe and pinch gestures. |
tge-gl | OpenGL/ES 3+ API based on go-gl work. Expose OpenGL to App in a portable way, il you want a low level access to the graphical context. Needed by most graphical libraries and plugins. |
tge-g3n | Based on the awesome G3N game engine written in Go. This great piece of software engineering is brought to Mobile and Web by TGE. |
tge-audio | Audio support based on Web Audio API. Brings full support for sound effects and spacialization with a comprehensive API ;) |
Based on what is done with tools like Vue.js, Node or Spring, TGE offers a command line tool tge-cli to ease creation and build of TGE applications.
To get the client, run:
go get github.com/thommil/tge-cli
The command line tool should be available in the $GOPATH/bin folder.
The create a new application workspace, run:
tge-cli init [package-name]
An application folder will be created with all needed resources to begin. See tge-cli and Go Doc for details and API.
Once the application folder is created, releases can be generated using:
tge-cli build -target [target] [package-path]
Target allows to build your application for Desktop, Mobile or Web backend. See tge-cli for full details on how to use it and customize each target.
App is the main entry point of a TGE application. The code below is generated by tge-cli when creating a new project:
package main
import (
"time"
// Runtime package
tge "github.com/thommil/tge"
//Available plugins - Just uncomment to enable
//gesture "github.com/thommil/tge-gesture"
//gl "github.com/thommil/tge-gl"
//g3n "github.com/thommil/tge-g3n"
)
// App instance context and definition
type App struct {
// Put global attributes of your application here
}
// OnCreate is called at App instanciation, the Runtime resources are not
// yet available. Settings and treatments not related to Runtime should be done here.
func (app *App) OnCreate(settings *tge.Settings) error {
// Settings is passed as a pointer can be modified to adapt App to your needs
// Ex :
// settings.Name = "My Awesome App++"
// settings.Fullscreen = true
// settings.EventMask = tge.AllEventsEnable
// ...
return nil
}
// OnStart is called when all Runtime resources are available but looping as not been
// started. Initializations should be done here (GL conf, physics engine ...).
func (app *App) OnStart(runtime tge.Runtime) error {
// Here is the place where your initialize everything, the runtime is UP but the loops
// are not started :
// - OpenGL
// - Physics
// - AI
// - Load previous Save
// - State Machine setup
// ...
return nil
}
// OnResume is called just after OnStart and also when the Runtime is awaken after a pause.
func (app *App) OnResume() {
// This method is called to notify that loops are started, don't place heavey treatments here
// Most of the time, this method is just used to hide/remove a pause screen
}
// OnRender is called each time the graphical context is redrawn. This method should only implements
// graphical calls and not logical ones. The syncChan is used to wait for Tick() loop draw commands
func (app *App) OnRender(elaspedTime time.Duration, syncChan <-chan interface{}) {
// Always listen at least for one object from syncChan to synchronize it with Tick(), in other case the Tick() loop
// will be blocked
<-syncChan
// This loop is dedicated to graphical/GPU treatments:
// - OpenGl Calls
// - Vulkan Calls (one day ;)
//
// Data becomes available from syncChan pipe and sent by the Tick loop, as mentioned below, it's possible to
// reused syncChan several times in a single Render/Tick call for progressive rendering.
//
// As syncChan is a generic interface channel, it's also possible to select treatment to apply:
// data := <-syncChan
// switch data.(type) {
// ...
// }
}
// OnTick handles logical operations like physics, AI or any background task not relatd to graphics.
// The syncChan is used to notify Render() loop with draw commands.
func (app *App) OnTick(elaspedTime time.Duration, syncChan chan<- interface{}) {
// This loop is dedicated to logical/CPU treatments:
// - physics
// - AI
// - State Machine
// - File access ...
//
// Each time Tick loop needs to send data to Render loop, use the syncChan.
//
// In can be done once per call or several times if you want a progressive rendering
//
// As data can be shared between Tick and Render loops, a good practice is too handle heavy treatments
// in Tick dedicated data, then copy data to Render dedicated data and send it through the syncChan.
//
// A good candidate for copy if the reflect.Copy() function:
// reflect.Copy(reflect.ValueOf(renderData), reflect.ValueOf(tickData))
//
// If your data is based on something else than slices but its size justifies low level memory copy, you can
// also put ticker data in single element slice and use reflect.Copy().
//
// Tick loop is running in a dedicated Go routine, it's also possible to start subroutines in this loop to
// benefit from availble cores and increase treatment speed using map/reduce oriented algorithms.
//
// Always send at least one object to syncChan to synchronize it with Render(), in other case the Tick() loop
// will be a simple infinite loop and your App will destroy your Desktop/Mobile/Browser
syncChan <- true
}
// OnPause is called when the Runtime lose focus (alt-tab, home button, tab change ...) This is a good entry point to
// set and display a pause screen
func (app *App) OnPause() {
// Most of the time, just set a flag indicating the paused state of your App
}
// OnStop is called when the Runtime is ending, context saving should be done here. On current Android version this
// handler is also called when the application is paused (and restart after).
func (app *App) OnStop() {
// This is where you backup everyting if needed (state machine, save ...) The runtime tries to call and execute
// this method before leaving to allow proper exit but nothing is guaranteed on some targets (WEB)
}
// OnDispose is called when all exit treatments are done for cleaning task (memory, tmp files ...)
func (app *App) OnDispose() {
// Optional but always good practice to clean up everything before leaving :)
}
// Main entry point, simply instanciates App and runs it through Runtime
func main() {
// The line below should be the only one, code here is not portable!
tge.Run(&App{})
}
To create new TGE plugins for sharing or to defines dedicated libraries across your applications, use the code below:
package myplugin
import (
// Always import TGE for initalization purpose
tge "github.com/thommil/tge"
)
// Plugin implementation, no need to expose
type plugin struct {
}
// Go init function, register your plugin on TGE runtime HERE
func init() {
tge.Register(plugin{})
}
// Init code of your plugin, called before runtime loops
func (p *plugin) Init(runtime tge.Runtime) error {
return nil
}
// GetName is used to identify the plugin in TGE registry
func (p *plugin) GetName() string {
return "myplugin"
}
// Dispose allows to clean up plugin resources
func (p *plugin) Dispose() {
}
It's possible to write code for a specific platform the same way TGE does.
For desktop, add the following Go build directives:
// +build darwin freebsd linux windows
// +build !android
// +build !ios
// +build !js
for mobile (targeting only android or ios is also possible):
// +build android ios
and for browser:
// +build js
At last, it's also possible to create a dedicated file for debugging purpose by adding:
// +build debug
The file will be used if the -dev flag is set in tge-cli command line for build.
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.