npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@lugobots/lugo4node

v2.0.8

Published

Lugo4Node is a NodeJS implementation of a client player for [Lugo](https://lugobots.ai/) game.

Downloads

119

Readme

Lugo4Node - A Lugo Bots Client

Lugo4Node is a NodeJS implementation of a client player for Lugo game.

It is not a bot that plays the game, it is only the client to connect to the game server.

This package implements many methods that does not affect the player intelligence/behaviour/decisions. It is meant to reduce the developer concerns on communication, protocols, attributes, etc.

Using this client, you just need to implement the Artificial Intelligence of your player and some other few methods to support your strategy (see the example folder and The Dummies JS).

Table of Contents

Requirements

  • NPM >= 16

Installation

npm install @lugobots/lugo4node

Usage

There are three ways to use Lugo4Node client:

First option: Implementing a Bot class (simpler and recommended)

See example

Lugo4Node PlayAsBot implements a very basic logic to reduce the code boilerplate. This client will wrap most repetitive code that handles the raw data got by the bot and will identify the player state.

The Bot interface requires the methods to handle each player state based on the ball possession.

class Bot  {
    // OnDisputing is called when no one has the ball possession
    onDisputing(inspector: GameSnapshotInspector): Order[] | { orders: Order[], debug_message: string } | null {
      // the magic code comes here
      return ...
    }
    
    // OnDefending is called when an opponent player has the ball possession
    onDefending(inspector: GameSnapshotInspector): Order[] | { orders: Order[], debug_message: string } | null {
      // the magic code comes here
      return ...
    }
    
    // OnHolding is called when this bot has the ball possession
    onHolding(inspector: GameSnapshotInspector): Order[] | { orders: Order[], debug_message: string } | null {
      // the magic code comes here
      return ...
    }
    
    // OnSupporting is called when a teammate player has the ball possession
    onSupporting(inspector: GameSnapshotInspector): Order[] | { orders: Order[], debug_message: string } | null {
      // the magic code comes here
      return ...
    }
    
    // AsGoalkeeper is only called when this bot is the goalkeeper (number 1). This method is called on every turn,
    // and the player state is passed at the last parameter.
    asGoalkeeper(inspector: GameSnapshotInspector, state: PLAYER_STATE): Order[] | { orders: Order[], debug_message: string } | null {
      // the magic code comes here
      return ...
    }
}

Second option: Implementing the turn handler (a little more work)

As you noticed, the option 1 has some logic injected in it, so you may want to remove that layer of logic and implement yours.

The most raw way to communicate with the lugo is receiving the game raw snapshots. See example

In this case, you must use the client's play method. The play method will call your call back function for any message received from the game lugo.

It may require that you know a bit more about the game steps, but still not too much.

Third option: Using reinforcement learning :brain:

If you are a machine learning enthusiastic you may want to use the Lugo reinforcement learning environment.

Lugo bots is an asynchronous game, so you will need to use the Lugo4Node Gym library to create your model:

See example and documentation at RL lib readme file

Helpers

There are a many things that you will repeatedly need to do on your bot code, e.g. getting your bot position, creating a move/kick/catch order, finding your teammates positions, etc.

Lugo4Node brings some libraries to help you with that:

Snapshot inspector

Auto generated doc coming soon

The Snapshot inspector is quite useful. Firs to it helps you to extract data from the Game Snapshot each game turn.

const inspector = new GameSnapshotInspector(proto.lugo.Team.Side.HOME, 8, snapshot);

inspector.getSnapshot(): Lugo.GameSnapshot | null
inspector.getTurn(): number
inspector.getMe(): Lugo.Player
inspector.getBall(): Lugo.Ball | null
inspector.getPlayer(side: Lugo.Team.Side, number: number): Lugo.Player | null
inspector.getBallHolder(): Lugo.Player | null
inspector.isBallHolder(player: Lugo.Player): boolean
inspector.getTeam(side: Lugo.Team.Side): Lugo.Team | null
inspector.getMyTeam(): Lugo.Team | null
inspector.getOpponentTeam(): Lugo.Team | null
inspector.getMyTeamSide(): Lugo.Team.Side
inspector.getOpponentSide(): Lugo.Team.Side
inspector.getMyTeamPlayers(): Lugo.Player[] 
inspector.getOpponentPlayers(): Lugo.Player[]
inspector.getMyTeamGoalkeeper(): Lugo.Player | null
inspector.getOpponentGoalkeeper(): Lugo.Player | null

And also help us to create the Turn Orders Set based on the game state and our bot team side:

inspector.makeOrderMove(target: Lugo.Point, speed: number): Lugo.Order
inspector.makeOrderMoveMaxSpeed(target: Lugo.Point): Lugo.Order
inspector.makeOrderMoveFromPoint(origin: Lugo.Point, target: Lugo.Point, speed: number): Lugo.Order
inspector.makeOrderMoveFromVector(direction: Lugo.Vector, speed: number): Lugo.Order
inspector.makeOrderMoveByDirection(direction: DIRECTION, speed?: number): Lugo.Order
inspector.makeOrderMoveToStop(): Lugo.Order
inspector.makeOrderJump(target: Lugo.Point, speed: number): Lugo.Order
inspector.makeOrderKick(target: Lugo.Point, speed: number): Lugo.Order
inspector.makeOrderKickMaxSpeed(target: Lugo.Point): Lugo.Order
inspector.makeOrderCatch(): Lugo.Order

Mapper and Region classes

Naturally, the bots see the game field based on coordinates x and y, as in a cartesian plane.

However, that's not something that we want to be concerned about during the bot development.

The classes Mapper and Region work together to facilitate it for use.

The Mapper

Mapper slices the field in columns and rows, so your bot does not have to care about precise coordinates or the team side. The mapper will automatically translate the map position to the bot side.

And you may define how many columns/rows your field will be divided into.

const map = new Mapper(10, 10, teamSide)

// you may find a Map Region based in coordinates:
const region = map.getRegion(2, 3)

// and you may find a Map Region based in a map point
const region = map.getRegionFromPoint(inspector.getPlayer(proto.lugo.Team.Side.AWAY, 5))

// and you can also know the position of the goals
map.getAttackGoal(): Goal
map.getDefenseGoal(): Goal

The Region

The Region helps your bot to see the game map in quadrants, so it can move over the field without caring about coordinates or team side.

region.front()
region.back()
region.left()
region.right()